CMake编译含多main文件项目报错:如何生成指定可执行文件?
解决CMake编译时main重定义的问题
问题根源很明确:你的foo.c和executable.c里都定义了main函数,直接编译会导致符号重定义冲突;而你之前尝试的库方法没成功,是因为foo.c里的main也被编译进了库,链接时依然和executable.c的main冲突。
下面是不用拆分function()的解决方案:
步骤1:修改foo.c,用条件编译隔离main函数
给foo.c里的main加条件编译,让它只在单独编译foo.c为可执行文件时生效,作为库编译时自动忽略:
#include "foo.h" // function()的实现 void function() { // 你的功能代码 } // 仅当定义COMPILE_FOO_AS_EXECUTABLE宏时,才编译这个main函数 #ifdef COMPILE_FOO_AS_EXECUTABLE int main() { // foo原有的main逻辑 } #endif
步骤2:编写正确的CMakeLists.txt
把foo.c编译成静态库(此时不会包含main定义),再让executable链接这个库:
# 将foo.c编译为静态库,默认不定义COMPILE_FOO_AS_EXECUTABLE,因此库中仅包含function() add_library(foo STATIC foo.c) # 编译目标可执行文件 add_executable(EXECUTABLE executable.c) # 让EXECUTABLE链接foo库,从而可以调用function() target_link_libraries(EXECUTABLE PRIVATE foo)
可选:保留foo自身的可执行文件
如果还需要单独编译foo.c成可执行文件,在CMakeLists.txt中添加以下内容:
# 编译foo自己的可执行文件,定义宏启用main函数 add_executable(foo_self foo.c) target_compile_definitions(foo_self PRIVATE COMPILE_FOO_AS_EXECUTABLE)
避坑说明
- 不要直接把
foo.c加入EXECUTABLE的源文件列表:两个main必然冲突。 - 不要在头文件中包含
.c文件:这会导致每个引用头文件的源文件都重复编译.c中的代码,引发函数多次定义错误。 - 之前用
add_library失败的核心原因:没处理foo.c里的main,库中依然包含main符号,链接时和executable的main冲突。
内容的提问来源于stack exchange,提问作者Jake
相关产品推荐
相关产品推荐

