You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 17:35:03