如何阻止GTest调用目标归档中的main函数?
解决CMake测试程序误调用主程序main函数的问题
你尝试用list(FILTER)过滤$<TARGET_OBJECTS:objlib>的方法行不通,因为$<TARGET_OBJECTS>是CMake的生成器表达式,在配置阶段还没被展开成实际的目标文件路径列表,list(FILTER)根本拿不到可处理的内容,所以正则表达式怎么改都没用。
下面是两种可行的解决思路:
方案一:拆分业务代码与主程序(推荐)
根源问题是你的objlib把main.cpp也包含进去了,正确的做法是把业务逻辑和主程序入口分开,这样测试时只链接业务代码即可。
修改src/CMakeLists.txt:
# 把业务代码(file1.cpp、file2.cpp)单独做成静态库 add_library(objlib STATIC file1.cpp file2.cpp ) # 主程序单独编译,链接业务库 add_executable(myapp main.cpp) target_link_libraries(myapp PRIVATE objlib)
然后修改tests/CMakeLists.txt,直接链接业务库和GTest的main:
add_executable(mytest mytests.cpp) # 链接业务库和GTest主程序 target_link_libraries(mytest PRIVATE objlib GTest::Main) # 引入src目录的头文件(如果测试代码需要调用src的函数) target_include_directories(mytest PRIVATE ${CMAKE_SOURCE_DIR}/src) add_test(NAME mytest COMMAND mytest)
方案二:临时生成不含main的对象库(兼容原有结构)
如果不想改动src的原有CMake结构,可以在测试目录里过滤掉main.cpp,重新生成一个不含主函数的临时对象库:
修改tests/CMakeLists.txt:
# 获取objlib的所有源文件列表 get_target_property(OBJLIB_SOURCES objlib SOURCES) # 过滤掉main.cpp list(FILTER OBJLIB_SOURCES EXCLUDE REGEX "main.cpp$") # 用过滤后的源文件创建临时对象库,继承原objlib的编译配置 add_library(objlib_no_main OBJECT ${OBJLIB_SOURCES}) target_compile_options(objlib_no_main PRIVATE $<TARGET_PROPERTY:objlib,COMPILE_OPTIONS>) target_include_directories(objlib_no_main PRIVATE $<TARGET_PROPERTY:objlib,INCLUDE_DIRECTORIES>) # 测试程序链接临时库和GTest主程序 add_executable(mytest mytests.cpp) target_link_libraries(mytest PRIVATE objlib_no_main GTest::Main) add_test(NAME mytest COMMAND mytest)
你原有测试CMake的错误点
顺便提一下你原来的tests/CMakeLists.txt里的几个问题:
target_link_directories是用来指定链接目录的,不是直接链接目标/库,应该用target_link_libraries- 最后一行多了个多余的
),属于语法错误 - 用
${CMAKE_BINARY_DIR}/src作为头文件目录不合理,应该用${CMAKE_SOURCE_DIR}/src(源码目录)
内容的提问来源于stack exchange,提问作者Ender
相关产品推荐
相关产品推荐

