Cmake Practice
文章目录
cmake基本语法规则
- 变量使用 ${} 方式获取,但是在IF控制语句中是直接使用变量名
- 指令(参数1 参数2) 参数使用括弧括起,参数之间使用空格或者分号分开
- 指令不区分大小写,参数和变量是区分大小写的(推荐你全部使用大写命令)
- 清理工程,运行:make clean
- cmake不支持“make distclean”(原本用于清理构建过程中产生的中间文件的)
- cmake推荐进行外部构建,外部编译过程如下
- 首先在工程目录中建立build目录
- 进入build目录,运行cmake … (… 代表父目录)
- 运行make构建工程
CMakeLists.txt剖析
ADD_SUBDIRECTORY
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置,EXCLUDE_FROM_ALL参数的含义是将这个目录从编译过程中排除。比如,工程的example,可能需要工程构建完成后,再进入example目录单独进行构建(也可通过定义依赖来解决此类问题)
SET EXECUTABLE_OUTPUT_PATH/LIBRARY_OUTPUT_PATH
#PROJECT_BINARY_DIR编译发生的当前目录
#ROJECT_SOURCE_DIR:内部编译,工程代码所在目录;外部编译,外部编译所在目录
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
通过这两个指令可以指定最终的目标二进制的位置(如果需要改变目标存放路径,就在哪里定义上述定义)
INSTALL
INSTALL指令用于定义安装规则,安装的内容可以包括目标二进制、动态库、静态库以及
文件、目录、脚本等
#参数中的TARGETS后面跟的就是我们通过ADD_EXECUTABLE或者ADD_LIBRARY定义的目标文件,可能是可执行二进制、动态库、静态库
#目标类型也就相对应的有三种,ARCHIVE特指静态库,LIBRARY特指动态库,RUNTIME特指可执行目标二进制
INSTALL(TARGETS targets...
[[ARCHIVE|LIBRARY|RUNTIME]
[DESTINATION <dir>]
[PERMISSIONS permissions...]
[CONFIGURATIONS
[Debug|Release|...]]
[COMPONENT <component>]
[OPTIONAL]
] [...])
DESTINATION定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候CMAKE_INSTALL_PREFIX其实就无效了。如果你希望使用CMAKE_INSTALL_PREFIX来定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是${CMAKE_INSTALL_PREFIX}/<DESTINATION定义的路径>
#举个栗子
#可执行二进制myrun安装到${CMAKE_INSTALL_PREFIX}/bin目录
#动态库libmylib安装到${CMAKE_INSTALL_PREFIX}/lib目录
#静态库libmystaticlib安装到${CMAKE_INSTALL_PREFIX}/libstatic目录
INSTALL(TARGETS myrun mylib mystaticlib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION libstatic
)
特别注意的是你不需要关心TARGETS具体生成的路径,只需要写上TARGETS名称就可以了
普通文件的安装
#可用于安装一般文件,并可以指定访问权限,文件名是此指令所在路径下的相对路径(默认权限644)
INSTALL(FILES files... DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL])
#非目标文件的可执行程序安装(比如脚本之类)(默认权限755)
INSTALL(PROGRAMS files... DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL])
#目录的安装
INSTALL(DIRECTORY dirs... DESTINATION <dir>
[FILE_PERMISSIONS permissions...]
[DIRECTORY_PERMISSIONS permissions...]
[USE_SOURCE_PERMISSIONS]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[[PATTERN <pattern> | REGEX <regex>]
[EXCLUDE] [PERMISSIONS permissions...]] [...])
DIRECTORY后面连接的是所在Source目录的相对路径,但注意abc和abc/有很大区别:如果目录名不以/结尾,那么这个目录将被安装为目标路径下的abc,如果目录名以/结尾,代表将这个目录中的内容安装到目标路径,但不包括这个目录本身
PATTERN用于使用正则表达式进行过滤,PERMISSIONS用于指定PATTERN过滤后的文件权限
#将工程安装到/tmp/t2目录
#如果不定义DCMAKE_INSTALL_PREFIX,将安装到默认的/usr/local
cmake -DCMAKE_INSTALL_PREFIX=/tmp/t2/usr ..
ADD_LIBRARY
#SHARED 动态库 STATIC 静态库
ADD_LIBRARY(libname [SHARED|STATIC|MODULE]
[EXCLUDE_FROM_ALL]
source1 source2 ... sourceN)
#例子:ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
#如果需要同时编译静态库和动态库,则libname不能重名
SET_TARGET_PROPERTIES
#需要重名的解决办法
#这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和API版本
SET_TARGET_PROPERTIES(target1 target2 ...
PROPERTIES prop1 value1
prop2 value2 ...)