Makefile 编译 c 和 cpp 文件

Posted

技术标签:

【中文标题】Makefile 编译 c 和 cpp 文件【英文标题】:Makefile to compile both c and cpp files 【发布时间】:2016-02-03 14:03:07 【问题描述】:

我想编译我的程序,但这样做有一些问题。我的程序由一个用 C 编写的 main 函数组成。其他文件是我没有编写的 .h 或 .cpp 文件。我有一个 make 文件,但不幸的是我无法编译我的程序。这是文件的“架构”:

a.h 只包含常量的定义。

b.h 和 b.cpp。 b.cpp 包括 a.h

c.h 和 d.cpp。 c.h 包含 d.cpp 方法的签名。 d.cpp 包括 a.h、b.h 和 c.h。

最后一个文件是 main.c,其中包含 c.h。

我使用的makefile如下:

CXX      = g++
CXXFLAGS = -Wall -ansi -g
CC       = gcc
CCFLAGS  = -g
OBJS     = main.o a.o b.o c.o

exec : $(OBJS)
    $(CXX) -o $@ $(OBJS)

c.o: d.cpp b.h a.h  
    $(CXX) -c $(CXXFLAGS) $<

a.o: a.h
    $(CXX) -c $(CXXFLAGS) $<

b.o: b.cpp a.h
    $(CXX) -c $(CXXFLAGS) $<

%.o : %.cpp
    $(CXX) -c $(CXXFLAGS) $<

%.o : %.c
    $(CC) -c $(CCFLAGS) $<

谁能告诉我我错了?此外,如何修改makefile,以便我可以将a、b、c 和d 文件放在子文件夹中而不会造成任何问题?

谢谢!

编辑: 这是我得到的错误:

g++ -o tester main.o a.o b.o c.o
Undefined symbols for architecture x86_64:
    "_crypto_aead_encrypt", referenced from:
         _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [tester] Error 1

函数在c.h中声明,在d.cpp中定义

【问题讨论】:

你能说你有什么错误吗? 你确定你编译失败,而不是链接? 是的,错误发生在链接期间。我已经添加了错误。 你正确使用extern "C"了吗? how to write makefile mixing C and C++的可能重复 【参考方案1】:

最可能的原因是 main 包含的 c.h 中的定义在编译 main.c 时被编译为 extern "C",而在编译成 d.cpp 时却被编译为 C++ extern (name mangling)。

(如果 c.h 是 crypto_aead_encrypt 函数来自的位置)

简单的解决方案是将所有内容编译为 C++(或者将 main 重命名为 .cpp,或者使用 $CXX 编译 main.c 并将“-x c++”添加到 CXXFLAGS)。

不那么简单的解决方案需要在编译 d.cpp 时将 c.h 方法编译为 extern "C" - 这需要更改 c.h 和/或 d.cpp。或者为 c.h 中包含的 C++ 方法提供一个 C 包装器。

【讨论】:

谢谢,我会试试你的解决方案! :)

以上是关于Makefile 编译 c 和 cpp 文件的主要内容,如果未能解决你的问题,请参考以下文章

使用makefile动态编译c++代码

Makefile入门

在 makefile 中使用 ifeq 编译 C 或 CPP 文件

使用makefile编译多个文件(.c , .cpp , .h等)

用于在头文件更改时构建简单 c 项目重新编译的示例 makefile

什么时候应该在 Makefile 中使用 -c 或 -o GCC 选项?