参考资料
- cmake文档:https://mubu.com/doc/t1VDCEn4O0
command
set
cmake_parse_arguments
cmake_parse_arguments 为解析函数(function)或 宏(macros) 参数的命令;
cmake_parse_arguments(<prefix> <options> <one_value_keywords>
<multi_value_keywords> <args>...)
cmake_parse_arguments(PARSE_ARGV <N> <prefix> <options>
<one_value_keywords> <multi_value_keywords>)
参数解析
< options >: 可选值
此处包含可选项的变量名称, 对应的值为 TRUE 或 FALSE;
如果传递进来的参数包含此变量,则为 TRUE 反之为 FALSE
< one_value_keywords >: 单值关键词列表
每个关键词仅仅对应一个值
< multi_value_keywords >: 多值关键词列表
每个关键词可对应多个值
< args >… 参数, 一般传入 ${ARGN} 即可
****前缀, 解析出的参数都会按照 prefix_参数名 的形式形成新的变量;
示例:
cmake_minimum_required(VERSION 3.5)
project(PARSE)
function(MY_PARSE)
set(options ADULT)
set(oneValueArgs NAME AGE)
set(multiValueArgs SCORE)
cmake_parse_arguments(STUDENT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
# 通过 prefix_参数名: 例如 STUDENT_ADULT
message("isadult = ${STUDENT_ADULT}")
message("name = ${STUDENT_NAME}")
message("age = ${STUDENT_AGE}")
message("score = ${STUDENT_SCORE}")
endfunction()
MY_PARSE(ADULT NAME zhangsan AGE 20 SCORE 100 200 300 400 500)
add_executable(DEMO main.cpp)
运行结果:
rs:cmake-parse-arguments$ cmake ./
isadult = TRUE
name = zhangsan
age = 20
score = 100;200;300;400;500
_UNPARSED_ARGUMENTS: 表示未被使用的参数变量( $里面)
_KEYWORDS_MISSING_VALUES:定义了关键词,但是没有对应的值
使用技巧
CMake在不同目录间传值
一般用[set]命令定义的变量能从父目录传递到子目录,而不能传递到父目录。这里不讨论从父目录到子目录传值的情况,因为一般的方法都可以。下面主要介绍在子目录传值到父目录以及在子目录间传值的情况
方法一:
要用set(variable value CACHE INTERNAL docstring )这种方式定义的变量会把变量加入到CMakeCache.txt然后各级目录共享会访问到这个变量
比如:
在目录1的CMakeLists.txt中定义一个变量
set(Var1 "firest" CACHE INTERNAL "description words" )
//"description words"这个字符串相当于对变量的描述说明,不能省略,但可以自己随便定义
在目录2下的CMakeLists.txt中读取这个一个变量
M
ESSAGE(STATUS "Var1 : ${Var1}")
每次运行cmake都会更新这个变量,你会在CMakeCache.txt中找到这个变量
这种方法可以在不同目录之间传值,适应性较强,因为是通过读写缓存文件(CMakeCache.txt)来实现的
方法二
使用 PARENT_SCOPE 关键字
用 PARENT_SCOPE 声明的变量的生命空间在父目录,而不在当前目录,例如
set(SourceDir ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
如果想在当前目录和父目录都可以访问,则可以
set (LIB_VER 6)
set (LIB_VER ${LIB_VER} PARENT_SCOPE)
cmake:在各级子项目(目录)之间共享变量
项目目录结构如下图,facedetect和facefeature都要用到opencl中的include文件,1.2,2.0,2.1是不同的opencl版本的头文件,希望在cmake创建Makefile时,opencl文件夹下的CMakeLists.txt能定义类似INCLUDE_OPENCL_1_2,INCLUDE_OPENCL_2_0,INCLUDE_OPENCL_2_1,这样的变量,以保存不同版本的opencl 头文件位置,最后关键是能让项目中其他子目录的CMakeList.txt能使用这些变量。
├─facedetect
├─facefeature
└─opencl
└─include
├─1.2
│ └─CL
├─2.0
│ └─CL
└─2.1
└─CL
方法一 set:
一般用set命令定义的变量能从父目录传递到子目录,但opencl与facedetect和facefeature在同级目录,所以用set定义的变量无法共享,要用set(variable value CACHE INTERNAL docstring )这种方式定义的变量会把变量加入到CMakeCache.txt然后各级目录共享会访问到这个变量
比如:
在opencl下的CMakeLists.txt中定义一个变量
set(ICD_LIBRARY "${PROJECT_BINARY_DIR}/lib" CACHE INTERNAL "ICD Library location" )
//"ICD Library location"这个字符串相当于对变量的描述说明,不能省略,但可以自己随便定义