CMake常见指令 ============== 常见指令语法 ------------- - project指令语法 :: project(projectname [CXX] [C] [Java]) ##可以使用这个指令定义工程名称,并可指定工程支持的语言,支持的语言是可以忽略的,默认情况下支持所有语言。这个指令隐式的定义了两个cmake变量 ##_BINARY_DIR以及_SOURCE_DIR #建议直接使用PROJECT_BINARY_DIR以及PROJECT_SOURCE_DIR,这样修改工程名称后也不会影响这两个变量 - set指令语法 :: set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]]) #set指令用来显式的定义变量 - message指令语法 :: message([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...) #这个命令用于向终端输出用户定义的信息,包含了三种类型:SEND_ERROR(产生错误,生成过程被跳过)、STATUS(输出前缀为-的信息)、FATAL_ERROR(立即终止所有cmake过程) - add_library: 该指令的主要作用就是将指定的源文件生成链接文件,然后添加到工程中去 :: add_library( [STATIC | SHARED | MODULE | OBJECT] [EXCLUDE_FROM_ALL] source1 [source2 ...]) .. note:: name:表示库文件的名字,该库文件会根据命令中列出的源文件来创建 STATIC|SHARED|MODULE|OBJECT: 分别对应静态库,动态库,MODULE(一种不会被链接到其他目标中的插件,但可能会运行时加载), OBJECT(可以将源代码编译为对象文件) - option: 为用户提供一个可选项,如果没有指定,将使用OFF作为初始值 :: option( "help string" [initial value]) #: 选项名 #"help string" 提示用户的信息 #[initial value]: 变量初始值ON or OFF 例: option(WITH_BLUEFS "libbluefs library" OFF) 构建过程中,会提示libbluefs library文字,等待用户输入(ON or OFF),输入的值保存在WITH_BLUEFS变量里 - execute_process: 执行进程.该命令可以执行一个或多个命令作为当前命令的子命令,将输出结果保存在cmake变量或文件中,所有的进程使用单个的标准错误输出管道 :: execute_process(COMMAND [args1 ...] COMMAND [args2...] [...] [WORKING_DIRECTORY ] [TIMEOUT ] [RESULT_VARIABLE ] [OUTPUT_VARIABLE ] [ERROR_VARIABLE ] [INPUT_FILE ] [OUTPUT_FILE ] [ERROR_FILE ] [OUTPUT_QUIET] [ERROR_QUIET] [OUTPUT_STRIP_TRAILING_WHITESPACE] [ERROR_STRIP_TRAILING_WHITESPACE] .. note:: 如果指定了WORKING_DIRECTORY,则指定的目录将作为子进程当前的工作目录 如果指定了TIMEOUT,则如果在指定时间内子进程未完成,将会被中断 RESULT_VARIABLE保存最后命令执行的结果 OUTPUT_VARIABLE,ERROR_VARIABLE保存标准输出和标准错误输出的内容 OUTPUT_QUIET,ERROR_QUIER忽略标准输出和错误输出 例 :: excute_process( COMMAND ${PYTHON_EXECUTABLE} "-c" "print('hello, world!')" RESULT_VARIABLE _status OUTPUT_VARIABLE _hello_world ERROR_QUIET ) - target_sources:往source文件中追加源文件 :: add_executable(test_app "") target_sources(test_app PRIVATE subsource.cpp PUBLIC subsource.h) .. note:: 源文件一般指定为PRIVATE,因为源文件只是在构建时使用,而头文件指定为PUBLIC,是因为构建和编译时都会使用 - add_custom_command: 为生成的构建系统添加一条自定义的构建规则 有两种使用方法: 方法一: 增加一个自定义命令用来产生一个输出 :: add_custom_command(OUTPUT output1 [output2...] #输出,可以输出到一个变量中 COMMAND command1 [ARGS] [args1...] #自定义的命令 COMMAND command2 [ARGS] [args2...] [MAIN_DEPENDENCY depend] [DEPENDS[depends...]] #列出该命令的依赖项 [IMPLICIT_DEPENDS depend1 ...] [WORKING_DIRECTORY dir] #指定在哪个目录下执行该命令 [COMMENT comment] [VERBATIM] [APPEND]) #COMMENT提示信息会在构建时打印出来, #VERBATIM告诉Cmake为指定的生成器和平台生成正确的命令,来确保是与平台无关的 方法二: :: add_custom_command(TARGET target PRE_BUILD | PRE_LINK | POST_BUILD COMMAND command1 [args1...] COMMAND command2 [args2...] [WORKING_DIRECTORY dir] [COMMENT comment] [VERBATIM]) - function & macro :: function( [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) endfunction() macro( [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) endmacro() .. note:: 相同点: function和macro都没有返回值 不同点:function和macro的变量作用域不同,如果宏内修改变量值宏外相同名称的变量值也会更改,function内则不会,如果想达到同样的效果则需要使用关键字PARENT_SCOPE - check_cxx_compiler_flag: 判断C++编译器是否支持某flag,flag可以是-g,-std=c++11等 :: check_cxx_compiler_flag( ) 例 check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11) unset(COMPILER_SUPPORTS_CXX11 CACHE) if(COMPILER_SUPPORTS_CXX11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") else() message(STATUS "the compiler has no C++11 support") endif() check_c_compiler_flag使用方法类似 - configure_file: 拷贝input文件到output,并更改其中的内容 :: configure_file( [COPYONLY] [ESCAPE_QUOTES] [@ONLY] [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF]]) - set_target_properties: 为目标文件设置属性,语法如下 :: set_target_properties(target1 target2 ... PROPERTIES prop1 value1 prop2 value2...) - include_directories: 添加头文件目录,相当于把路径添加到环境变量中 - link_directories: 添加库文件目录,相当于把需要链接的库文件目录添加到LD_LIBRARY_PATH中 - find_library: 查找库所在的目录 - list: 列表操作,有以下方法 :: #返回list的长度 list(LENGTH ) #返回list中index的element到value中 list(GET [ ...] ) #添加新的element到list中 list(APPEND [ ...]) #返回list中element的index,没有找到返回-1 list(FIND ) #将新element插入到list中的index位置 list(INSERT [ ...]) #从list中删除某个element list(REMOVE_ITEM [ ...]) #从list中删除指定index的element list(REMOVE_AT [ ...]) #从list中删除重复的element list(REMOVE_DUPLICATES ) #将list的内容反转 list(REVERSE ) #将list按字母顺序排序 list(SORT ) - file: 文件操作命令 :: #Reading file(READ [...]) file(STRINGS [...]) file( ) file(TIMESTAMP [...]) file(GET_RUNTIME_DEPENDENCIES [...]) #Writing file({WRITE | APPEND} ...) file({TOUCH | TOUCH_NOCREATE} [ ...]) file(GENERATE OUTPUT [...]) #Filesystem file({GLOG | GLOB_RECURSE} [...] [...]) file(RENAME ) file({REMOVE | REMOVE_RECURSE} [ ...]) file(MAKE_DIRECTORY [...]) file({COPY | INSTALL} ... DESTINATION [...]) file(SIZE ) file(READ_SYMLINK ) file(CREATE_LINK [...]) #Path Conversion file(RELATIVE_PATH ) file({TO_CMAKE_PATH | TO_NATIVE_PATH} ) #Transfer file(DOWNLOAD [...]) file(UPLOAD [...]) #Locking file(LOCK [...]) - string :: #search and replace string(FIND [...]) string(REPLACE ...) #Regular Expressions string(REGEX MATCH ...) string(REGEX MATCHALL ...) string(REGEX REPLACE ...) #Manipulation string(APPEND [...]) string(PREPEND [...]) string(CONCAT [...]) string(JOIN [...]) - fin_package: 寻找外部项目,并加载设置 :: find_package( [version] [EXACT] [QUIET] [MODULE] [REQUIRED] [[COMPONENTS] [components...]] [OPTIONAL_COMPONENTS components...] [NO_POLICY_SCOPE]) - cmake_parse_arguments: CMake参数解析命令,可以用于解析函数或宏的参数列表 :: cmake_parse_arguments( ...) cmake_parse_arguments(PARSE_ARGV ) .. note:: options:可选值,此处包含可选项的变量的名称,对应的值为TRUE或FALSE one_value_keywords:单值关键词列表 multi_value_keywords:多值关键词列表 args:参数,一般传入${ARGN}即可 prefix:前缀,解析出的参数都会按照prefix_参数名的形式形成新的变量 :: function(my_install) set(options OPTIONAL FAST) set(oneValueArgs DESTINATION RENAME) set(multiValueArgs TARGETS CONFIGURATIONS) cmake_parse_arguments(my_install "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) endfunction() 函数调用 my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) #可选值OPTIONAL和FAST,函数调用时传入了OPTIONAL #单值关键词列表包含DESTINATION和RENAME,函数调用时传入DESTINATION,参数名为bin #多值关键词列表包含TARGETS和CONFIGURATIONS