CMake中使用get_target_property判断Target是否存在
2014-08-07 16:35
1681 查看
使用Cmake的add_custom_target建立自定义的Target后,必须将这个Target加入all依赖,否则生成的Makefile不会执行这个Target的内容。这样会有个问题,如果需要编译如下目录:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/03/808e01039d8cf7571471be654a7751ca)
目录下有N个目录,这些目录下或是目录,或是文件,那么递归下去,就会有若干CMakeLists.txt,也就是说,会有若干个add_custom_target(all ...)的存在。进入单独目录编译或许不要紧,但是如果我们在顶层或者中间层执行cmake生成Makefile,就会报重复Target的错误,这个重复的Target就是多次添加的all。错误如下:
只能在叶子编译而不能在中上层编译,这样显然不行。一个可行的解决方案是,在向all中添加Target前,先判断Target‘是否存在,如果不存在,则使用add_custom_target添加依赖(add_custom_target的问题在于,它本身不判断Target是否存在,每次都是新建);如果存在,则使用add_dependencies添加依赖(add_dependencies只是添加依赖,而不会新建Target)。在这里,使用get_target_property判断Target存在与否,原型如下:
有get必有set,向一个Target添加键值的方法是set_property,原型如下:
使用append_dependencies向all添加依赖,这样就能有效解决在中上层目录中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冲突的现象。
相关文章推荐
- 使用WinAPI函数FindFirstFile或GetFileAttributes判断文件是否存在
- hashmap判断是否存在key时,使用get(key)==null判断还是containsKey?
- 2014-03-31工作日志:判断文件是否存在可以使用GetFileAttributes 方法。
- PHP使用get_headers函数判断远程文件是否存在的方法
- PHP使用get_headers函数判断远程文件是否存在的方法
- C#判断文件是否存在和文件夹是否存在(Windows Mobile上可以使用)
- 使用API判断网络是否连通(InternetGetConnectedState / IsNetworkAlive)
- JQuery Ajax在.net里面的使用(判断用户名是否存在)
- SQl Server 动态SQL给变量赋值 和OBJECTPROPERTY函数使用及判断表 存储过程 视图等是否存在
- sql server中列中字符换使用分割字符后,判断是否存在指定的项
- 使用位图法判断整形数组是否存在重复
- 使用API判断网络是否连通(InternetGetConnectedState / IsNetworkAlive)
- 使用API判断网络是否连通(InternetGetConnectedState / IsNetworkAlive)
- 使用File类判断文件是否存在以及创建,拷贝和移动文件
- C# 判断 检测 access 建库 建表 文件是否存在等 数据操作 使用 ADOX
- 在Google App Engine中使用hash和marshal持久化模块,快速判断数据库条目是否已经存在
- document.getElementById("radFs")对象为空,js判断对象是否存在?
- jQuery -- 如何使用jQuery判断某个元素是否存在
- 使用jquery实现判断用户名是否存在的实例
- 如何使用jQuery判断一个元素是否存在