gpt4 book ai didi

c++ - 在子目录中调用 target_link_libraries 的替代方法

转载 作者:行者123 更新时间:2023-11-30 03:30:41 25 4
gpt4 key购买 nike

案例:

我已经声明了一个函数 setup_target_for_coverage在单独的 .cmake 脚本中,添加到 CMAKE_MODULE_PATH , 它为代码覆盖率分析准备了一个目标 ( mylib )。 setup_target_for_coverage从子目录调用到 mylib (mylib_tests)。

要求是所有与测试和代码覆盖有关的事情,仅针对此目标,发生在 mylib/tests 中和 setup_target_for_coverage ,并来自 mylib/CMakeLists.txt我们只添加了测试子目录,仅此而已。最后,mylib 都不知道测试细节或代码覆盖率的存在。 ,它只是“盲目地”调用add_subdirectory( tests ) .

示例:

看起来像这样:

我的库:

# ./mylib/CMakeLists.txt:

project( mylib )
add_library( mylib main.cpp )
# This is all mylib should be aware of, everything else is hidden
add_subdirectory( tests )

mylib_tests:

# ./mylib/tests/CMakeLists.txt:

project( mylib_tests )

# ...

include(code-coverage)
setup_target_for_coverage(
TARGET mylib
TEST_RUNNER mylib_tests
)

代码覆盖率:

# ./cmake/code-coverage.txt:

function(setup_target_for_coverage)
# Parse arguments...

# Setting compile flags: Works as expected
target_compile_options( ${args_TARGET}
PRIVATE
-g -O0 --coverage
)

# Setting linker flags: THIS FAILS <---------------
target_link_libraries( ${args_TARGET}
PRIVATE
--coverage
)

add_custom_target( ${args_TARGET}_coverage}
# Setup lcov, run "TEST_RUNNER", generate html...
COMMAND ...
)

endfunction()

简而言之,它设置了编译器和链接器标志 ( --coverage ) 并添加了一个运行 gcov/lcov 和 genhtml 的自定义目标。

问题:

问题在于 target_link_libraries ,(如文档所述)需要在创建目标的同一“目录”中发生:

The named <target> must have been created in the current directory by a command such as add_executable() or add_library() [...]

因此我得到以下错误:

Attempt to add link library "--coverage" to target "mylib" which is not built in this directory.

我试图通过使用 set_property 来解决这个问题直接

set_property(
TARGET ${TARGET}
APPEND_STRING PROPERTY LINK_FLAGS "--coverage"
)

没有用。它失败并出现以下错误,即使在同一个 CMakeLists.txt 中也是如此:

"undefined reference to `__gcov_merge_add'"

如果 target_link_libraries 有效移至./mylib/CMakeLists.txt ,但这如上所述不满足我的要求。

有什么想法吗?

最佳答案

将评论变成答案。正如您所强调的,您只能在同一目录范围内定义的目标上调用 target_link_libraries()(编辑:此限制自 CMake 3.13 起不再存在)。当您调用 add_subdirectory() 时,您进入了一个新的目录范围,因此遇到了您询问的问题。

另一方面,include() 命令不会创建新的目录作用域。这有两个直接相关的效果:

  • included 目录的文件中,您仍然可以为 including 目录范围内的目标调用 target_link_libraries()
  • CMAKE_CURRENT_SOURCE_DIR 的值不会改变,因此您可能希望在包含的文件中使用 CMAKE_CURRENT_LIST_DIR。请注意,CMAKE_CURRENT_BINARY_DIR 没有等效项,它也不会改变。

一个典型的模式可能是这样的:

mylib/CMakeLists.txt:

add_library( mylib main.cpp )
include( tests/CMakeLists.txt )

mylib/tests/CMakeLists.txt:

add_executable( someTest "${CMAKE_CURRENT_LIST_DIR}/someTest.cpp" )
# ...

也许至少是切线相关的,您也可以在 this article 中找到这些想法引起兴趣。它展示了如何跨目录管理源和目标,一路上涉及 add_subdirectory()include() 的讨论。

关于c++ - 在子目录中调用 target_link_libraries 的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44811329/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com