cmake不允许您使用add_custom_target()在构建树中的不同位置创建具有相同名称的多个目标。 但是,它确实为该属性提供了特殊目标:
在子树中运行时,每个都将仅适用于该子树。 有没有办法达到用户目标的目的?
这是一个简化的例子:
toplevel CMakeLists.txt :
cmake_minimum_required(VERSION 2.8)
add_custom_target(thing)
add_subdirectory(sub1)
add_subdirectory(sub2)
SUB1 /的CMakeLists.txt :
add_executable(foo foo.cpp)
add_custom_target(thing.sub1 DEPENDS foo)
add_dependencies(thing thing.sub1)
SUB2 /的CMakeLists.txt :
add_executable(bar bar.cpp)
add_custom_target(thing.sub2 DEPENDS bar)
add_dependencies(thing thing.sub2)
我几乎可以得到我想要的行为:
我想要的是能够只运行 make thing 并将其应用于 当前的子目录,如 all 目标。
这可能吗? 如果不是它是一个缺失的功能,或者它是一个错误的,如果是这样的原因?
解决方案(差不多)
@ zuafi的方向让我找到了解决方案。
目前可以但仅使用政策CMP0002中的弃用行为。 实际上有一个缺少的功能,用于添加this open ticket所涵盖的本地目标。
我的解决方法是为自己实现 add_local_target()如下:
# determine whether local targets should be legal
if("${CMAKE_GENERATOR}" MATCHES "Make")
cmake_policy(SET CMP0002 OLD)
# property seems to be deprecated
set_property(GLOBAL PROPERTY ALLOW_DUPLICATE_CUSTOM_TARGETS 1)
set(ALLOW_LOCAL_TARGETS 1)
message("using Makefile generator")
else()
cmake_policy(SET CMP0002 NEW)
message("Generator=${CMAKE_GENERATOR}")
endif()
# add a custom target with the same name as another (posssibly global) target iff permitted
# see http://stackoverflow.com/questions/35489093/cmake-special-targets-like-all-and-test-having-the-same-name-in-multiple-pl
function(add_local_target target)
if(ALLOW_LOCAL_TARGETS)
set(dependencies "${ARGN}")
foreach(dependency IN LISTS dependencies)
if(TARGET ${dependency})
list(APPEND targets ${dependency})
else()
message("${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt: warning: dependency ${dependency} for add_local_target(${target}) is NOT a target")
endif()
endforeach()
add_custom_target(${target} DEPENDS ${targets})
endif()
endfunction()
这与 target.subdir 等目标路径很好地结合使用,如果使用非Makefile生成器,它可以用作后备路径。 我只是用:
add_local_target(thing DEPENDS thing.sub1)
更新
我认为这个解决方案可能会被巧妙地打破。如果您尝试构建“本地”目标,可以构建其他“本地”目标。但是,它将至少构建它应该构建的内容。它还将构建一个不同于全局项目范围的目标,并且将建立相同的名称。我还没有设法跟踪它,因为cmake生成的makefile有些粗糙。
答案 0 :(得分:1)
是的,它可能......但不是所有发电机都可以。特别是Ok w / UNIX Makefiles (参见CMP0002描述)。至于我,我想让我的项目树中的所有单元测试具有相同的名称(我有一个bash完成该名称:),所以我使用以下宏帮助我声明可执行文件:
macro(set_unit_test_target_name OUTPUT_VARIABLE DEFAULT_VALUE)
cmake_policy(GET CMP0002 _may_use_same_name)
if(_may_use_same_name STREQUAL "OLD")
set(${OUTPUT_VARIABLE} "unit_tests")
else()
set(${OUTPUT_VARIABLE} ${DEFAULT_VALUE})
endif()
endmacro()
# usage example
set_unit_test_target_name(UNIT_TESTS someTestExecutable)
add_executable(${UNIT_TESTS} ... )
因此对于* NIX构建,所有可执行文件都将命名为unit_tests
,并且具有其他生成器的唯一名称...