2017-09-04 77 views
-1

我有一个包含多个源文件的项目,并且我正在使用GoogleTest库为其中一些源文件创建单元测试。这些测试都是单独的.cpp文件,每个文件都包含要测试的相应源文件的标题。CMake - 仅在需要时将库链接到可执行文件

我想为每个单元测试创​​建一个单独的可执行文件。为此,我有一个循环,为test_sources列表中的每个成员创建可执行文件,并根据test_names列表对其进行命名。

问题是,我的几个单元测试需要另一个第三方库。该库在${${PROJECT_NAME}_EXTERNAL_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() 
+0

@Frank它相对于'StringExTest'所需的'错误日志状态' – Blue7

+0

'',但是你写'StringExTest是不需要POCO库的测试之一'相对于'$ {PROJECT_BINARY_DIR}/$ {EXTERNAL_NAME} 。那么是哪一个呢? – VTT

+0

@VTT错误日志认为它需要POCO库,因为它正在链接到可执行文件。但是,StringExTest绝对不需要POCO。 – Blue7

回答

2

将完整路径传递到target_link_libraries()。通过使用get_filename_component()ABSOLUTE arg,您可以制作绝对路径${PROJECT_NAME}_EXTERNAL_LIBRARIES

+0

谢谢你的回答。您能否扩展如何将相对路径与绝对路径相结合?我在这里创建了一个新问题:https://stackoverflow.com/questions/46041606/cmake-make-a-list-of-paths-absolute – Blue7

+0

这很好用,谢谢! – Blue7

+0

对不起,我说得太快了!如果我删除了构建文件夹并尝试从头开始重新构建,则会得到与原始问题相同的错误。现在它也绝对将绝对路径传递给目标链接库。 – Blue7

相关问题