CMake最佳实践语法笔记

552 阅读2分钟

常见语法指令记录

PROJECT 指令的语法是:

PROJECT(projectname [CXX] [C] [Java]) 你可以用这个指令定义工程名称,并可指定工程支持的语言,支持的语言列表是可以忽略的, 默认情况表示支持所有语言。这个指令隐式的定义了两个 cmake 变量: _BINARY_DIR 以及_SOURCE_DIR,这里就是 HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR(所以 CMakeLists.txt 中两个 MESSAGE 指令可以直接使用了这两个变量),因为采用的是内部编译,两个变量目前指的都是工程所 在路径/backup/cmake/t1,后面我们会讲到外部编译,两者所指代的内容会有所不同。 同时 cmake 系统也帮助我们预定义了 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR 变量,他们的值分别跟 HELLO_BINARY_DIR 与 HELLO_SOURCE_DIR 一致。 为了统一起见,建议以后直接使用 PROJECT_BINARY_DIR,PROJECT_SOURCE_DIR,即 使修改了工程名称,也不会影响这两个变量。如果使用了 _SOURCE_DIR,修改工程名称后,需要同时修改这些变量。

SET 指令的语法是:

SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]]) 现阶段,你只需要了解 SET 指令可以用来显式的定义变量即可。 比如我们用到的是 SET(SRC_LIST main.c),如果有多个源文件,也可以定义成: SET(SRC_LIST main.c t1.c t2.c)。 MESSAGE 指令的语法是: MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...) 这个指令用于向终端输出用户定义的信息,包含了三种类型: SEND_ERROR,产生错误,生成过程被跳过。 SATUS,输出前缀为—的信息。FATAL_ERROR,立即终止所有 cmake 过程.

ADD_EXECUTABLE(hello ${SRC_LIST})

定义了这个工程会生成一个文件名为 hello 的可执行文件,相关的源文件是 SRC_LIST 中 定义的源文件列表

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存 放的位置。EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除,比如,工程 的 example,可能就需要工程构建完成后,再进入 example 目录单独进行构建(当然,你 也可以通过定义依赖来解决此类问题)。

INSTALL 指令:

目标文件的安装: INSTALL(TARGETS targets... [[ARCHIVE|LIBRARY|RUNTIME] [DESTINATION ] [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT ] [OPTIONAL] ] [...]) 参数中的 TARGETS 后面跟的就是我们通过 ADD_EXECUTABLE 或者 ADD_LIBRARY 定义的 目标文件,可能是可执行二进制、动态库、静态库。 目标类型也就相对应的有三种,ARCHIVE 特指静态库,LIBRARY 特指动态库,RUNTIME 特指可执行目标二进制。 DESTINATION 定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候 CMAKE_INSTALL_PREFIX 其实就无效了。如果你希望使用 CMAKE_INSTALL_PREFIX 来 定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是 ${CMAKE_INSTALL_PREFIX}/

ADD_LIBRARY ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)

你不需要写全 libhello.so,只需要填写 hello 即可,cmake 系统会自动为你生成 libhello.X 类型有三种: SHARED,动态库 STATIC,静态库 MODULE,在使用 dyld 的系统有效,如果不支持 dyld,则被当作 SHARED 对待。 EXCLUDE_FROM_ALL 参数的意思是这个库不会被默认构建,除非有其他的组件依赖或者手工构建。

SET_TARGET_PROPERTIES:

其基本语法是: SET_TARGET_PROPERTIES(target1 target2 ... PROPERTIES prop1 value1 prop2 value2 ...) 这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和 API 版本。

INCLUDE_DIRECTORIES:

INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...) 这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,如果路径 中包含了空格,可以使用双引号将它括起来,默认的行为是追加到当前的头文件搜索路径的 后面,你可以通过两种方式来进行控制搜索路径添加的方式: 1,CMAKE_INCLUDE_DIRECTORIES_BEFORE,通过 SET 这个 cmake 变量为 on,可以 将添加的头文件搜索路径放在已有路径的前面。 2,通过 AFTER 或者 BEFORE 参数,也可以控制是追加还是置前。

TARGET_LINK_LIBRARIES:

TARGET_LINK_LIBRARIES(target library1 library2 ...) 这个指令可以用来为 target 添加需要链接的共享库。