包含混合 C 和 C++ 代码的 Makefile
Makefile with mixed c and C++ code
我试图在编译 .c 和 .cpp 文件时做一些非常简单的事情,以便在 Ubuntu 上创建应用程序。我创建了一个 Makefile,但它失败并出现以下错误。
~/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如下
#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
#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
#include "class_a.h"
A::A()
{
a = 0;
}
int
A::addToA(int c)
{
a += c;
return a;
}
生成文件
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++ 名称重整,这样 linker 才能正常工作。
即C函数int add(int, int)
实际上在目标文件中生成了一个名为add
的符号。但是 C++ 函数 int add(int, int)
将生成一个名为 _Z3addii
的符号。而那些不会 link.
解决方案:混合语言函数,在用C++编译时应该声明extern "C"
。不幸的是,extern "C"
声明在 C 中不存在,仅在 C++ 中存在。
所以标准成语是:
test1.h
#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
函数,并且所有代码将一起 link。
我试图在编译 .c 和 .cpp 文件时做一些非常简单的事情,以便在 Ubuntu 上创建应用程序。我创建了一个 Makefile,但它失败并出现以下错误。
~/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如下
#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
#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
#include "class_a.h"
A::A()
{
a = 0;
}
int
A::addToA(int c)
{
a += c;
return a;
}
生成文件
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++ 名称重整,这样 linker 才能正常工作。
即C函数int add(int, int)
实际上在目标文件中生成了一个名为add
的符号。但是 C++ 函数 int add(int, int)
将生成一个名为 _Z3addii
的符号。而那些不会 link.
解决方案:混合语言函数,在用C++编译时应该声明extern "C"
。不幸的是,extern "C"
声明在 C 中不存在,仅在 C++ 中存在。
所以标准成语是:
test1.h
#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
函数,并且所有代码将一起 link。