C++ CMake-仅在需要时将库链接到可执行文件
我有一个包含几个源文件的项目,我正在使用GoogleTest库为其中一些源文件创建单元测试。这些测试都是独立的C++ CMake-仅在需要时将库链接到可执行文件,c++,qt,cmake,linker,shared-libraries,C++,Qt,Cmake,Linker,Shared Libraries,我有一个包含几个源文件的项目,我正在使用GoogleTest库为其中一些源文件创建单元测试。这些测试都是独立的.cpp文件,每个文件都包含要测试的各个源文件的头 我想为每个单元测试创建一个单独的可执行文件。为此,我有一个循环,为test\u sources列表中的每个成员创建一个可执行文件,并根据test\u names列表对其命名 问题是我的几个单元测试需要另一个第三方库。此库在${${PROJECT\u NAME}{u EXTERNAL\u LIBRARIES}列表中定义。我已尝试将此链接到
.cpp
文件,每个文件都包含要测试的各个源文件的头
我想为每个单元测试创建一个单独的可执行文件。为此,我有一个循环,为test\u sources
列表中的每个成员创建一个可执行文件,并根据test\u names
列表对其命名
问题是我的几个单元测试需要另一个第三方库。此库在${${PROJECT\u NAME}{u EXTERNAL\u LIBRARIES}
列表中定义。我已尝试将此链接到我的文本可执行文件,但出现错误:
Error: No rule to make target 'PocoNetExternal/Foundation/libPocoFoundationd.so', needed by 'StringExTest'. Stop.
这是因为StringExTest是不需要POCO库的测试之一。如果我删除指向POCO的链接,我会得到一个不需要POCO的可执行文件的undefined reference
错误。有趣的是,如果我把链接放回并重新构建,所有的编译和运行都很好,没有错误。不幸的是,这还不够好,因为我需要它第一次工作,所以它可以在我们的持续集成服务器上工作
下面是将Gtest和Poco链接到可执行文件的代码。我如何更改它,使其仅在需要时链接POCO?如果添加或删除了其他测试,则此代码也需要可重用,无需修改
##########################################################################
##### Loop over all the .cpp files and create separate executables
list(LENGTH test_sources len1) #len1 is length of test_sources list
math(EXPR len2 "${len1} - 1") #len2 is len1 - 1
foreach(val RANGE ${len2}) #for val = 0 to len2
list(GET test_names ${val} name) #name will change on every loop
list(GET test_sources ${val} src) #list(GET <list> <element index> <output variable>)
add_executable("${name}" "${src}" "${test_files}") #add_executable(<name> source1 [source2 ...])
endforeach()
##########################################################################
###### Link the libraries
makeLibPathsAbsolute()
foreach(val RANGE ${len2}) #for val = 0 to len2
list(GET test_names ${val} name) #name will change on every loop
target_link_libraries(${name} gtest_main) #link gtest libraries
message(STATUS "LINKING: ${external_libraries_abs} to ${name}\n")
target_link_libraries(${name} ${external_libraries_abs}) #link all other libraies (give the absolute path path)
endforeach()
##########################################################################
#####循环所有.cpp文件并创建单独的可执行文件
列表(长度测试源len1)#len1是测试源列表的长度
数学(EXPR len2“${len1}-1”)#len2是len1-1
foreach(val范围${len2})#对于val=0到len2
列表(获取测试名称${val}name)#名称将在每个循环中更改
列表(获取测试源${val}src)#列表(获取)
添加可执行文件(“${name}”“${src}”“${test_files}”)#添加可执行文件(source1[source2…)
endforeach()
##########################################################################
######链接图书馆
makeLibPathsAbsolute()
foreach(val范围${len2})#对于val=0到len2
列表(获取测试名称${val}name)#名称将在每个循环中更改
目标链接库(${name}gtest_main)#链接gtest库
消息(状态“链接:${external\u libraries\u abs}到${name}\n”)
目标链接库(${name}${external\u libraries\u abs})#链接所有其他库(给出绝对路径)
endforeach()
将完整路径传递到目标链接库()。您可以使用withabsolute
arg使${PROJECT\u NAME}{EXTERNAL\u库中的路径成为绝对路径。@Frank这是相对于${PROJECT\u BINARY\u DIR}/${EXTERNAL\u NAME}
错误日志状态“StringExTest”所需的,但随后编写“StringExTest是不需要POCO库的测试之一”。那么是哪一个呢?@VTT错误日志认为它需要POCO库,因为它正在链接到可执行文件。然而,StringExTest肯定不需要POCO。也许我遗漏了一些东西,但是当没有任何东西从它导入时,链接一些额外的库并不会造成任何伤害,也不会产生任何链接错误。并且错误发布的错误消息与链接完全无关。实际上,cmake似乎出于某种原因试图构建poco。“所需者”是一个生成文件,而不是链接器。您有一个不存在的文件作为StringExTest的依赖项。您需要修复makefile或生成它的方式。谢谢您的回答。您能详细介绍一下如何将路径列表从相对变为绝对吗?我在这里提出了一个新问题:对不起,我说得太快了!如果我删除build文件夹并尝试从头开始重新构建,我会得到与原始问题相同的错误。它现在也在向目标链接库传递绝对路径,这很奇怪。尝试运行make VERBOSE=1
,也许这会提供线索。排序。这是因为我没有使用add_dependencies()
。在开始构建单元测试可执行文件之前,主项目(其中包含我正在测试的函数以及poco库)还没有完成构建。我很快会把这个作为答案发布。