带有C和C ++混合代码的Makefile [英] Makefile with mixed c and C++ code

查看:107
本文介绍了带有C和C ++混合代码的Makefile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在编译.c和.cpp文件以在Ubuntu上创建应用程序方面做一些非常简单的事情.我创建了一个Makefile,但是它失败,并出现以下错误.

I'm trying to do something pretty simple in compiling .c and .cpp files to create an application on Ubuntu. I created a Makefile but it fails with the following error.

~/code/test$ make
gcc -Wall -c test1.c -o test1.o
g++ -c -Wall -D__STDC_LIMIT_MACROS main.cpp -o main.o
g++ -c -Wall -D__STDC_LIMIT_MACROS class_a.cpp -o class_a.o
echo g++ test1.o                               main.o class_a.o  -o myapp
g++ test1.o main.o class_a.o -o myapp
g++ test1.o                               main.o class_a.o -o myapp
main.o: In function `main':
main.cpp:(.text+0x21): undefined reference to `add(int, int)'
collect2: error: ld returned 1 exit status
make: *** [myapp] Error 1

main.cpp如下

main.cpp is as follows

#include "stdio.h"
#include "test1.h"
#include "class_a.h"

int main(int argc , char **argv)
{
   int c = 0; 
   c  = add(10, 15);
   A a;
   a.addToA(c);
   printf("result = %d\n",c); 
}

test1.h

#ifndef _FILE_H
#define _FILE_H

int add(int a, int b);
#endif 

test1.c

#include "test1.h"


int add(int a, int b)
{
    return a + b;
}

class_a.h

class_a.h

#ifndef _class_A_H
#define _class_A_H
class A 
{
public:
    A();

    int addToA(int c);

private:
    int a;

}; 

#endif // _class_A_H

class_a.cpp

class_a.cpp

#include "class_a.h"

A::A()
{
    a = 0;
}


int 
A::addToA(int c)
{
    a += c;
    return a;
}

Makefile

CXX = g++
CC = gcc
CFLAGS = -Wall -c
CXXFLAGS = -c -Wall -D__STDC_LIMIT_MACROS


CSOURCES=test1.c   

CPPSOURCES= main.cpp \
            class_a.cpp 


COBJECTS=$(CSOURCES:.c=.o)                              
CPPOBJECTS = $(CPPSOURCES:.cpp=.o) 
EXECUTABLE=myapp



all: $(EXECUTABLE)

$(EXECUTABLE): $(COBJECTS) $(CPPOBJECTS)
    echo $(CXX) $(COBJECTS) $(CPPOBJECTS) -o $@
    $(CXX) $(COBJECTS) $(CPPOBJECTS)-o $@


.c.o:
    $(CC) $(CFLAGS) $< -o $@

.cpp.o:
    $(CXX) $(CXXFLAGS) $< -o $@

clean:
        rm -rf $(COBJECTS)
        rm -rf $(CPPOBJECTS)
        rm -rf $(EXECUTABLE)

推荐答案

要能够从C ++调用C函数(或从C调用C ++函数),必须防止C ++名称混乱,以便链接程序正常工作.

To be able to call C functions from C++ (or C++ functions from C) you have to prevent the C++ name mangling, so that the linker will work properly.

也就是说,C函数int add(int, int)实际上在目标文件add中生成一个符号.但是C ++函数int add(int, int)将生成一个名为_Z3addii的符号.那些将不会链接.

That is, C function int add(int, int) actually generates a symbol in the object file called add. But a C++ function int add(int, int) will generate a symbol named _Z3addii. And those will not link.

解决方案:使用C ++编译时,混合语言函数应声明为extern "C".不幸的是,extern "C"声明在C中不存在,仅在C ++中存在.

Solution: the mixed language functions, when compiled in with C++ should be declared extern "C". Unfortunately the extern "C" declaration does not exist in C, only in C++.

所以标准成语是:

#ifndef _FILE_H
#define _FILE_H

#ifdef __cplusplus
extern "C" {
#endif

int add(int a, int b);

#ifdef __cplusplus
}  //extern "C"
#endif

#endif

那样,C代码与以前一样,但是C ++代码将使用未修饰的名称查找add函数,并且所有这些都将链接在一起.

That way, the C code is just as before, but the C++ code will look for the add function using the undecoraded name, and all will link together.

这篇关于带有C和C ++混合代码的Makefile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆