CMake 菜鸟升级指南
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CMake 菜鸟升级指南相关的知识,希望对你有一定的参考价值。
注!看参考资料一边学习一边整理的,只整理了自己能理解的部分,更详细的内容大家去挖官方的文档哈!
应知应会
- 每一个要管理的目录都要包含一个CMakeLists.txt。(这个文件名不能有任何改动)
- CMake获取变量值的语法是 $变量名。
- CMake的指令可以大写、小写或大小混写,但是一般约定俗称都用大写。
- CMake指令的参数用括号括起来,参数之间用空格隔开,参数是大小写相关的,不要乱写。
- CMake参数也可以用分号“;”隔开,但不是约定俗成的用法,不建议使用。
CMake预定义变量
# 当前文件路径
$CMAKE_CURRENT_SOURCE_DIR
# 安装路径
$CMAKE_INSTALL_PREFIX # 默认值为 /usr/local
# 项目编译路径
$PROJECT_BINARY_DIR
# 项目名
$PROJECT_NAME
# 项目路径,值参照下面PROJECT指令说明
$PROJECT_SOURCE_DIR
常用指令说明
ADD_EXECUTABLE
ADD_EXECUTABLE(name sourceFile)
用sourceFile源文件生成一个名为name的可执行文件。sourceFile可以是单个文件,也可以是定义的文件列表变量。见下面的例子:
# 单个文件
ADD_EXECUTABLE($PROJECT_NAME main.cpp)
# 多个文件
ADD_EXECUTABLE($PROJECT_NAME main.cpp pow.cpp)
# 源文件变量
ADD_EXECUTABLE($PROJECT_NAME $SRC_FILE $LIB_FILE)
ADD_LIBRARY
ADD_LIBRARY(<name> [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 [source2...])
- [EXCLUDE_FROM_ALL] 这个库不会被默认构建,除非有其他的组件依赖或者手工构建。
- 生成最终共享库的文件名为,libname.so。会自动在库名前加lib。
补充点有关静态库和动态库的背景知识:
- 静态库的扩展名一般为".a"或".lib";动态库的扩展名一般为".so"或".dll";
- 静态库在编译时会直接整合到目标程序中,编译成功的可执行文件即使没有静态库也可以独立运行。
- 动态库在编译时不会放到链接的目标程序中,编译成功的可执行文件没有动态库无法独立运行。
- (接上条,有时候玩游戏会出现缺少xxx.dll的提示,就是缺少动态库)
ADD_SUBDIRECTORY
ADD_SUBDIRECTORY(directory [BINARY_DIR] [EXCLUDE_FROM_ALL])
向当前项目添加存放源文件的子目录。
- [BINARY_DIR] 指定生成的二进制文件的存放位置。
- [EXCLUDE_FROM_ALL] 将这个目录从编译中排除。
AUX_SOURCE_DIRECTORY
扫描指定文件夹下的所有源文件,并将源文件以列表的形式存放在变量中。
# 扫描当前文件夹下的所有原文将并将其存放在变量SRC_FILES中。
AUX_SOURCE_DIRECTORY($CMAKE_CURRENT_SOURCE_DIR SRC_FILES)
INSTALL
INSTALL(FILES|PROGRAM|DIRECTORY|TARGETS xxx DESTINATION xxx)
可以指定是安装文件、非目标文件的可执行程序、目录、可执行文件。
DESTINATION后可以写绝对路径,也可以写相对路径。相对路径是$CMAKE_INSTALL_PREFIX/<相对路径>。
安装目录时,指定路径为directoryName是安装该文件夹到目标目录,指定路径为directoryName/是安装该文件夹中的所有文件到目标目录中。
MESSAGE
MESSAGE([SEND_ERROR|STATUS|FATAL_ERROR] "Content")
相当于编程中的打印指令(python的print、C++的std::cout)。
- SEND_ERROR 报错误信息,不终止CMake构建过程。
- STATUS 普通输出信息。
- FATAL_ERROR 报错误信息,终止CMake构建过程。
PROJECT
PROJECT(projectname [CXX] [C] [JAVA])
[CXX] [C] [JAVA] 表示项目支持的语言,一般忽略这部分,默认情况下支持所有语言。
这个指令隐式地定义了两个CMake变量:
- <projectname>_BINARY_DIR
- <projectname>_SOURCE_DIR。
其中,SOURCE_DIR就是该指令所在CMakeLists.txt的文件夹路径。同时CMAKE也隐式地定义了另外两个变量:
- PROJECT_BINARY_DIR
- PROJECT_SOURCE_DIR
这两个变量的值和前面两个的值一样,区别在于上面两个变量在更改<projectname>后,所有使用了这两个变量的CMakeLists.txt脚本的相应位置都需要更改,而下面两个变量的更改是自动完成的。所以一般情况下使用下面两个可以降低后期调整的工作量。
SET
SET(VAR [VALUE])
SET 指令用来定义变量的值,相当于编程语言中的赋值操作(VAR=VALUE)。
# 定义SRC_LIST变量为三个cpp文件的列表。
SET(SRC_LIST main.cpp sqrt.cpp pow.cpp)
大型项目配置
指定二进制文件保存路径
指定最终二进制文件(可执行文件及库文件,不包含中间文件)的位置。
SET(EXECUTABLE_OUTPUT_PATH $PROJECT_BINARY_DIR/bin)
SET(LIBRARY_OUTPUT_PATH $PROJECT_BINARY_DIR/lib)
复制文件
将SOURCE目录文件or文件夹复制到BINARY目录。我自己理解的应用场景就是有一些资源文件需要拷贝什么的。
file(COPY $PROJECT_SOURCE_DIR/resource DESTINATION $PROJECT_BINARY_DIR)
特殊情况处理
文件名带空格
因为CMake的参数是用空格隔开的,那文件名里面带空格怎么办?
处理办法是给文件名加引号。在CMake中写文件名带引号或不带引号都可以,但文件名包含空格的时候就必须加上引号。
# 例:将hello world.cpp文件赋值给HELLO_SRC_FILE变量
# 错误!!!
SET(HELLO_SRC_FILE hello world.cpp)
# 正确
SET(HELLO_SRC_FILE "hello world.cpp")
以上是关于CMake 菜鸟升级指南的主要内容,如果未能解决你的问题,请参考以下文章