Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ CMake-仅在需要时将库链接到可执行文件_C++_Qt_Cmake_Linker_Shared Libraries - Fatal编程技术网

C++ CMake-仅在需要时将库链接到可执行文件

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}列表中定义。我已尝试将此链接到

我有一个包含几个源文件的项目,我正在使用GoogleTest库为其中一些源文件创建单元测试。这些测试都是独立的
.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()

将完整路径传递到
目标链接库()。您可以使用with
absolute
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库)还没有完成构建。我很快会把这个作为答案发布。