CMake中使用get_target_property判断Target是否存在

              使用Cmake的add_custom_target建立自定义的Target后,必须将这个Target加入all依赖,否则生成的Makefile不会执行这个Target的内容。这样会有个问题,如果需要编译如下目录:

目录下有N个目录,这些目录下或是目录,或是文件,那么递归下去,就会有若干CMakeLists.txt,也就是说,会有若干个add_custom_target(all ...)的存在。进入单独目录编译或许不要紧,但是如果我们在顶层或者中间层执行cmake生成Makefile,就会报重复Target的错误,这个重复的Target就是多次添加的all。错误如下:

add_custom_target cannot create target "all" because
  another target with the same name already exists.  The existing target is a
  custom target created in source directory
See documentation
  for policy CMP0002 for more details.

只能在叶子编译而不能在中上层编译,这样显然不行。一个可行的解决方案是,在向all中添加Target前,先判断Target‘是否存在,如果不存在,则使用add_custom_target添加依赖(add_custom_target的问题在于,它本身不判断Target是否存在,每次都是新建);如果存在,则使用add_dependencies添加依赖(add_dependencies只是添加依赖,而不会新建Target)。在这里,使用get_target_property判断Target存在与否,原型如下:

get_target_property(VAR target property)
这里的property和VAR相当于一个map键值对,property是键,VAR是值,这个键值对从属于target,如果这个target没有这个键,那么VAR将返回OUTPUT_VALUE-NOTFOUND。

有get必有set,向一个Target添加键值的方法是set_property,原型如下:

set_property(<GLOBAL                            |
              DIRECTORY [dir]                   |
              TARGET    [target1 [target2 ...]] |
              SOURCE    [src1 [src2 ...]]       |
              TEST      [test1 [test2 ...]]     |
              CACHE     [entry1 [entry2 ...]]>
             [APPEND] [APPEND_STRING]
             PROPERTY <name> [value1 [value2 ...]])
这里功能较多,我们只需要设置TARGET为指定的target名,PROPERTY设置为需要的键值对即可。如此,判断一个Target是否存在就可以这么写:

get_target_property(OUTPUT_VALUE all STATUS)
if(${OUTPUT_VALUE} STREQUAL OUTPUT_VALUE-NOTFOUND)
	#Target all 不存在
else()
	#Target all 存在
endif()
在此基础上,包装一个自定义的函数append_dependencies,它向all中添加依赖,在all不存在的情况下,使用add_custom_target新建Target all并且增加依赖,对Target增加键值对讯息,如果all存在,则使用add_dependencies添加依赖,代码如下:

function(append_dependencies)
    set(multiValueArgs DEPENDENCIES)
    cmake_parse_arguments(APPEND_DEPENDENCIES "" "" "${multiValueArgs}" ${ARGN})
    
    get_target_property(OUTPUT_VALUE all STATUS)
    if(${OUTPUT_VALUE} STREQUAL OUTPUT_VALUE-NOTFOUND)
        add_custom_target(all DEPENDS ${APPEND_DEPENDENCIES_DEPENDENCIES})
        set_property(TARGET all PROPERTY STATUS AVAILABLE)
    else()
        add_dependencies(all DEPENDS ${APPEND_DEPENDENCIES_DEPENDENCIES})
    endif()
    
endfunction()<pre name="code" class="plain">

 使用append_dependencies向all添加依赖,这样就能有效解决在中上层目录中Target冲突的现象。 


  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值