替代在子目录中调用target_link_libraries

时间:2017-06-28 19:46:21

标签: c++ cmake code-coverage gcov lcov

案例:

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

要求是所有与测试和代码覆盖有关的内容,<仅针对此目标的 ,都发生在mylib_testsmylib/tests ,从setup_target_for_coverage我们只添加了test-subdirectory和以外的其他。最后,mylib/CMakeLists.txt不知道测试细节或代码覆盖的存在,它只是盲目地&#34;致电mylib

实施例

看起来像这样:

MYLIB:

add_subdirectory( tests )

mylib_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/CMakeLists.txt:

project( mylib_tests )

# ...

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

简而言之,它设置了编译器和放大器。 linker-flags(# ./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() )并添加一个运行gcov / lcov和genhtml的自定义目标。

问题:

问题在于--coverage,其中(如文件所述)需要在同一目录中发生#34}。目标的创建地点:

  

必须在当前目录中创建已命名的target_link_libraries   <target>add_executable() [...]

等命令

因此我收到以下错误:

add_library()

我试图直接使用Attempt to add link library "--coverage" to target "mylib" which is not built in this directory. 来解决这个问题

set_property

无济于事。它失败并出现以下错误,即使在相同的CMakeLists.txt中也是如此:

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

如果将"undefined reference to `__gcov_merge_add'" 移至target_link_libraries,则可以正常运行,但如上所述,这不符合我的要求。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

将评论转化为答案。正如您所强调的那样,您只能在同一目录范围中定义的目标上调用8 specs, 5 failures Finished in 105.229 seconds 。当您致电target_link_libraries()时,您会输入新的目录范围,从而解决您所询问的问题。

另一方面,add_subdirectory()命令不会创建新的目录范围。这有两个直接相关的影响:

  • 包含目录的文件中,您仍然可以在包含目录的范围内为目标调用include()。< / LI>
  • target_link_libraries()的值不会发生变化,因此您可能希望在所包含的文件中使用CMAKE_CURRENT_SOURCE_DIR。请注意,CMAKE_CURRENT_LIST_DIR没有相应的内容也不会发生变化。

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

MYLIB /的CMakeLists.txt

CMAKE_CURRENT_BINARY_DIR

MYLIB /测试/的CMakeLists.txt

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

或许至少与切向相关,您也可能会发现this article中的想法很有意义。它显示了如何跨目录管理源和目标,并在此过程中触及add_executable( someTest "${CMAKE_CURRENT_LIST_DIR}/someTest.cpp" ) # ... add_subdirectory()讨论。

答案 1 :(得分:0)

function替换为macro

macro(setup_target_for_coverage)
  [...]
endmacro()

CMake宏类似于C宏:您可以将其视为文本替换,因此它的行为就像代码位于原始文件中一样。