本文为我读《CMakeCookBook》时的笔记。
将单个源文件编译成可执行文件
cmake_minimum_required(VERSION 3.10 FATAL_ERROR) # 声明版本
project(p1 LANGUAGES CXX) #声明项目名称和支持的编程语言,CXX代表C++
add_executable(hello hello-world.cpp) # 生成可执行文件hello,这个可执行文件是通过链接源文件生成的
CMake
中,C++
是默认的编程语言。不过,还是建议使用LANGUAGES
选项在project
命令中显式地声明项目的语言。
然后可以通过创建build
目录,在build
目录下来配置项目
mkdir -p build
cd build
cmake ..
上述操作还可以使用cmake -H. -Bbuild
来实现。-H.
表示当前目录中搜索根CMakeLists.txt
文件。-Bbuild
告诉CMake在一个名为build
的目录中生成所有的文件。
GNU/Linux上,CMake默认生成Unix Makefile来构建项目:
- Makefile: make将运行指令来构建项目。
- CMakefile:包含临时文件的目录,CMake用于检测操作系统、编译器等。此外,根据所选的生成器,它还包含特定的文件。
- cmake_install.cmake:处理安装规则的CMake脚本,在项目安装时使用。
- CMakeCache.txt:如文件名所示,CMake缓存。CMake在重新运行配置时使用这个文件。
如果一切顺利,项目的配置已经在build
目录中生成。我们现在可以编译可执行文件:
cmake --build .
可以使用cmake --build . --target <target-name>
语法,实现如下功能:
- all是默认目标,将在项目中构建所有目标。
- clean,删除所有生成的文件。
- rebuild_cache,将调用CMake为源文件生成依赖(如果有的话)。
- edit_cache,这个目标允许直接编辑缓存。
构建和链接静态库和动态库
add_library(message
STATIC
Message.hpp
Message.cpp
)
target_link_libraries(hello message)
add_library(message STATIC Message.hpp Message.cpp)
:生成必要的构建指令,将指定的源码编译到库中。add_library的第一个参数是目标名。整个CMakeLists.txt中,可使用相同的名称来引用库。生成的库的实际名称将由CMake通过在前面添加前缀lib和适当的扩展名作为后缀来形成。生成库是根据第二个参数(STATIC或SHARED)和操作系统确定的。
target_link_libraries(hello-world message)
: 将库链接到可执行文件。此命令还确保hello可执行文件可以正确地依赖于消息库。因此,在消息库链接到hello可执行文件之前,需要完成消息库的构建。
编译成功后,构建目录包含libmessage.a
一个静态库(在GNU/Linux上)和hello
可执行文件。
add_library()
第二个参数的有效值:
STATIC
:用于创建静态库,即编译文件的打包存档,以便在链接其他目标时使用,例如:可执行文件。SHARED
:用于创建动态库,即可以动态链接,并在运行时加载的库。可以在 CMakeLists.txt 中使用 add_library(message SHARED Message.hpp Message.cpp) 从静态库切换到动态共享对象(DSO)。OBJECT
:可将给定add_library的列表中的源码编译到目标文件,不将它们归档到静态库中,也不能将它们链接到共享对象中。如果需要一次性创建静态库和动态库,那么使用对象库尤其有用。