CMake-仅在需要时将库链接到可执行文件 [英] CMake - Only link a library to an executable if it is needed
问题描述
我有一个包含多个源文件的项目,并且我正在使用GoogleTest库为其中一些源文件创建单元测试.这些测试都是单独的.cpp
文件,每个文件都包含要测试的相应源文件的标题.
I have a project that includes several source files, and I am using the GoogleTest library to create unit tests for some of these source files. The tests are all separate .cpp
files and each includes the header of the respective source file to be tested.
我想为每个单元测试创建一个单独的可执行文件.为此,我有一个循环,为test_sources
列表中的每个成员创建一个可执行文件,并根据test_names
列表命名它.
I want to create a separate executable for each unit test. To do this I have a loop that creates an executable for each member in a test_sources
list, and names it according to a test_names
list.
问题是我的几个单元测试需要另一个第三方库.该库在${${PROJECT_NAME}_EXTERNAL_LIBRARIES})
列表中定义.我试图将其链接到我的文本可执行文件,但出现错误:
The problem is that a couple of my unit tests require another 3rd party library. This library is defined inside the ${${PROJECT_NAME}_EXTERNAL_LIBRARIES})
list. I have tried to link this to my text executables, but I get the error:
Error: No rule to make target 'PocoNetExternal/Foundation/libPocoFoundationd.so', needed by 'StringExTest'. Stop.
这是因为StringExTest是不需要POCO库的测试之一.如果删除指向POCO的链接,对于确实需要POCO的可执行文件,我会收到undefined reference
错误.有趣的是,如果我放回链接并重新构建,一切都会编译并运行良好且没有错误.不幸的是,这还不够好,因为我需要它第一次运行,因此它可以在我们的持续集成服务器上工作.
This is because StringExTest is one of the tests that does not need the POCO library. If I remove the link to POCO, I get an undefined reference
error for the executable that does need POCO. Interestingly if I put the link back in and build again everything compiles and runs fine and without error. Unfortunately, this is not good enough as I need it to work the first time so it works on our continuous integration server.
这是将Gtest和Poco链接到可执行文件的代码.如何更改此设置,使其仅在需要时链接POCO?如果添加或删除了其他测试,则此代码还需要无需修改即可重用.
Here is the code that links Gtest and Poco to the executables. How can I change this so it only links POCO if it is needed? This code also needs to be reusable without modification if other tests are added or removed.
##########################################################################
##### 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()
推荐答案
将完整路径传递给target_link_libraries()
.您可以使用 get_filename_component()将路径设置为绝对路径.与ABSOLUTE
arg.
Pass full path to target_link_libraries()
. You can make paths in ${PROJECT_NAME}_EXTERNAL_LIBRARIES
absolute by using get_filename_component() with ABSOLUTE
arg.
这篇关于CMake-仅在需要时将库链接到可执行文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!