使用CMake进行项目构建

发表于: 2018年04月30 20:45

CMake使用-基础语法

根据维基百科上的介绍,CMake是一款跨平台的自动化构建系统。我们可以编写与编译平台无关的配置文件(CMakeLists.txt), 然后再生成对应编译平台的编译配置(例如Linux下的Makefile)然后再执行对应的编译指令。

CMake是为了解决跨平台编译而创造出来的,CMake的功能更加的强大,语法却比较简单,即使没有跨平台的编译需求,也可以用使用CMake来进行项目的构建配置。

CMake语法构成

  1. 当用CMake进行项目构建的时候, CMake会去寻找名为 CMakeLists.txt 的规则文件。
  2. 一个CMakeLists.txt 文件一般由多个命令(也可以是0个命令)。
  3. CMake文件中可以使用注释,一般用 # 作为行注释符
  4. CMake中也可以使用变量,变量只有string类型,但是这些变量可以通过一些command转换成其他的类型

CMake使用之-单文件编译

首先我们编写一个简单的 hello word的程序,源码省略。 再编写一个CMake的规则,保存在当前目录下的CMakelist中,其内容如下:

cmake_minimum_required(VERSION 3.5)
add_executable(hello hello.cpp)

我们执行在当前目录下执行 cmake . CMake此时会在检查包括系统版本, 编译器和ABI的版本信息,如果没有其他错误,就会在当前目录下生成Makefile, 执行Make就可以编译并生成目标文件 hello

上面的CMakeList的一行代码是什么含义呢?

add_executable 在CMake的官方文档中叫做Command(指令), 一般我喜欢理解成函数。它的第一个参数 表示要生成的可执行目标文件的名称, 后面紧跟的是源文件的名称。 两个参数之间用空格分隔。

如果有多个源文件,我们可以简单的加上其他的文件名. 例如

add_executable(hello hello.cpp hello2.cpp hello3.cpp)

target_link_libraries 但是这种方法在文件少,项目小的情况下,还能支持的了,但是一旦项目较大,文件变更频繁的情况下,这种方法将不再适用。

CMake使用之-添加多个源文件

CMake中有一个file的命令,我们可以通过这个命令来遍历目录下的所有指定格式的文件。这里CMakeList的内容如下

cmake_minimum_required(VERSION 3.5)

# 遍历当前目录下的所有后缀是cpp的文件
file(GLOB CURR_SRC *.cpp)

add_executable(hello ${CURR_SRC})

file指令的第一个参数,有多个选项,这里的GLOB表示生成一个文件列表,并将这些文件名保存到CURR_SRC这个变量中。 如果需要递归访问子目录,第一个参数则要换成 GLOB_RECURSE。 使用上面的CMakeList,就不用一个一个手动的加源文件了。file指令功能参数多且复杂,CMake中有更简单的 aux_source_directory 。 用 aux_source_directory 编写的规则如下:

cmake_minimum_required(VERSION 3.5)

# 遍历当前目录下的所有源文件名并保存到 CURR_SRC变量中
aux_source_directory(. CURR_SRC)

add_executable(hello ${CURR_SRC})

引入头文件

include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])

这个命令作用是把指定的目录添加到头文件搜索路径中,这些路径默认是被添加到原变量后面,可以使用BEFORE选项让路径填加在原路径之前。当使用相对路径时,默认是相对当前路径。

添加库的搜索路径

link_directories(directory1 directory2 ...)

需要注意的是,link_directories需要在目标创建之前调用,才会生效。 官方文档有明确的说明 link_directories

指定要链接的库

target_link_libraries(<target> [item1 [item2 [...]]]
                  [[debug|optimized|general] <item>] ...)

通过这个命令告诉编译器要链接到哪些共享库, 其中target可以是最终的二进制文件,也可以是我们自己要生成的共享库。item1, item2 可以是静态库也可以是动态库。

例如:
target_link_libraries(main hello)

同时还有一个相似的命令 link_libraries 将动态库添加到所有的target上。官方的文档上推荐优先使用 target_link_libraries

使用CMake编译动态链接库与静态链接库

在上文中我们使用 add_executable来指定生成可执行文件。有时候我们需要编译生成动态链接库或者生成静态的链接库。

# 指定生成静态库, 
add_library(archive STATIC a.cpp b.cpp)

# 指定生成动态库
add_library(archive SHARED a.cpp b.cpp)
© 2018 - fluyy - 粤ICP备17114935号