在上一节的内容中(),我给了一个使用Cmake的实例,用到了一些简单的语法。

从这节开始系统的总结一下Cmake的使用。

CMakeLists.txt 的语法比较简单,由命令、注释和空格组成,其中:

1.命令不区分大小写。

2.符号 # 后面的内容被认为是注释。

3.命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔

在CmakeLists.txt写好以后,创建build文件夹保存编译的中间内容和生成的文件,使用cmake指令:

mkdir build 
cd build
cmake ..
make

在第一节中,一个libhello.cpp为了和主函数main.cpp建立联系,通过了两种方式:

1.直接在add_executable里面,把两个cpp文件都包含进去;

2.把libhello.cpp通过add_library打包成一个库hello_library,然后把hello_library通过target_link_libraries链接到可执行文件上。

但是,如果有很多个需要用到的lib.cpp呢?都这么重复太麻烦了,因此可以通过aux_source_directory 命令,该命令会查找指定目录下的所有源文件,然后将结果存进指定变量名。

aux_source_directory(<dir> <variable>)

那么之前的CmakeLists.txt就还可以这么写:

#声明Cmake的最低版本
cmake_minimum_required( VERSION 3.0)
 
#声明一个cmake工程
project( Hello )

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

#添加一个可执行程序
add_executable(Hello ${DIR_SRCS})

CMake 会将当前目录所有源文件的文件名赋值给变量 DIR_SRCS ,再指示变量 DIR_SRCS 中的源文件需要编译成一个名称为 Hello 的可执行文件。(不过如果通过这种方式,要确保只有一个main.cpp,不然cmake ..的时候不会出错,但是在make的时候就会出错。


多级目录与文件:

如果在main.cpp所在目录下再创建一个文件夹,把libhello.cpp和libhello.h放进去的话,那CMakeLists.txt该怎么写呢?

./hellofile
    |
    +--- main.cpp
    |
    +--- lib/
          |
          +--- libhello.cpp
          |
          +--- libhello.h

对于这种情况,应该先在lib文件夹内,先创建一个CMakeLists.txt:

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)
# 生成链接库
add_library (Hello_library ${DIR_LIB_SRCS})

这样以后,libhello.cpp文件就被打包成了一个库。这里用到的方法是把目录下的所有源文件都弄成一个变量,然后打包成库。注意语法是如果要指示某个变量里的源文件,就把它先用大括号括住,然后用美元符号$一下(类似于解引用)

对于main.cpp,它里面inlcude了"lib/libhello.h",但是h文件里只是声明,没有具体的函数定义,因此,像第一节所述,需要把打包成的库Hello_library给链接到可执行文件上。因此这里需要用到一个新的命令:add_subdirectory(),把子目录包括进来:

#声明Cmake的最低版本
cmake_minimum_required( VERSION 3.0)
 
#声明一个cmake工程
project( Hello )

# 添加 lib 子目录
add_subdirectory(lib)
# 指定生成目标 
add_executable(Hello main.cpp)
# 添加链接库
target_link_libraries(Hello Hello_library)