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 菜鸟升级指南的主要内容,如果未能解决你的问题,请参考以下文章

[原创] Cmake实战指南

CentOS7 升级 cmake

CMake版本升级

转载:Ubuntu14.04下升级cmake工具

jetson nano 升级cmake

CMake通过工具链升级进行增量编译