CMake-仅在需要时将库链接到可执行文件 [英] CMake - Only link a library to an executable if it is needed

查看:257
本文介绍了CMake-仅在需要时将库链接到可执行文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多个源文件的项目,并且我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆