CMake Usage
在我的 C++ 项目中,我更倾向于使用 CMake 而非 Make。这主要是因为 CMake 在整合第三方库时表现出了更高的便捷性,同时在项目维护方面也更为出色。下面简要介绍一下 CMake 的一些常用方法和特点:
- 跨平台构建系统:CMake 支持多平台,无论是 Windows、Linux 还是 MacOS,都可以使用相同的 CMake 文件来构建项目。
- 更易于管理依赖关系:当涉及到第三方库时,CMake 使得管理和链接这些库变得更加简单。通过简单的指令,可以轻松地将外部库集成到项目中。
- 易于维护和扩展:CMake 的脚本语言清晰明了,使得项目的维护和扩展变得更加容易。即便项目规模扩大,使用 CMake 也可以保持构建配置的清晰和简洁。
- 生成原生构建环境:CMake 能够为不同的编译器生成原生的构建文件。例如,它可以为 Visual Studio 生成解决方案文件,为 Make 生成 Makefile,这让开发者可以使用自己熟悉的工具进行构建。
- 灵活性和可配置性:CMake 允许用户编写复杂的构建脚本,这些脚本可以根据不同的平台和条件进行适当的调整和配置。
总结一下,CMake 由于其跨平台性、易于管理依赖关系、良好的可维护性和灵活性,成为了构建 C++ 项目的优选工具。对于希望简化构建过程并增强项目可维护性的开发者来说,学习并使用 CMake 是非常值得的。
CMake Third Part Library
C++ 生态中有许多功能强大的第三方库,比如 Abseil 和 argparse。然而,对于初学者来说,学习如何在 CMake 项目中正确调用这些库可能会有些挑战。以下是一个简单的指南,帮助您开始使用这些库:
Load Library
使用abseil当作例子来详细的解释一下,首先我们的CMakeLists.txt初始化如下:
1 | cmake_minimum_required(VERSION 3.22) |
当我们想添加abseil
可以进行一下操作:
1 | cmake_minimum_required(VERSION 3.22) |
FetchContent
是 CMake 3.11 及更高版本中引入的一个模块,旨在简化从外部源获取代码的过程。这个模块允许您在构建时下载或更新外部依赖项,而不需要预先下载这些依赖项或将它们包含在您的项目源代码中。这种方法对于管理外部库非常有用,特别是当这些库频繁更新或者有多个项目共享时。
声明外部内容:使用
FetchContent_Declare
函数,您可以指定要获取的外部内容。您需要提供一些细节,比如项目名称、源代码的位置(例如 Git 仓库)等。例如:1
2
3
4FetchContent_Declare(
abseil
GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git
)获取内容:
FetchContent_MakeAvailable
或FetchContent_GetProperties
和FetchContent_Populate
函数用于下载和更新声明的内容。当这些命令执行时,CMake 会检查是否已经下载了内容,如果没有,则会从指定的源获取它。1
FetchContent_MakeAvailable(abseil)
集成到项目中:一旦内容被获取,它就可以被集成到您的项目中。通常,这意味着添加对应的子目录或链接库到您的项目中。
1
target_link_libraries(test absl::flat_hash_map)
添加完abseil
的库之后我们就可以在项目中调用该库,比如:
1 |
|
在上面的例子中我们调用了absl::flat_hash_map
和absl::flat_hash_set
编译顺利通过,说明成功调用了该库。
CMake Subdirectory
在处理大型 C++ 项目时,有效地组织代码和文件夹结构是至关重要的。这不仅有助于保持项目的整洁,还能简化构建和维护过程。在这里,我们将讨论如何在 CMake 中添加子文件夹,并将必要的库链接到这些子文件夹中,以实现更好的项目结构和模块化。
按照上面的例子,我们把absl::flat_hash_map
添加到一个单独的文件夹中,我们首先创建一个文件夹src
在src
文件夹下创建hash.cpp
,hash.h
和CMakeLists.txt
三个文件,内容分别如下:
hash.h
1 |
|
hash.cpp
1 |
|
CMakeLists.txt
1 | add_library(src |
这种在根目录下的CMakeLists.txt
也需要简单修改如下:
1 | cmake_minimum_required(VERSION 3.22) |
add_subdirectory(src)
: 这行命令告诉 CMake 在当前项目中添加一个子目录,这里是名为src
的目录。CMake 会查找src
目录下的CMakeLists.txt
文件,并执行其中的命令。这种做法通常用于项目结构中的源代码组织,将不同的代码部分放在不同的目录中,有助于保持项目的整洁和模块化。add_executable(test main.cpp)
: 这个命令创建了一个名为test
的可执行文件。main.cpp
是这个可执行文件的源文件。这行命令告诉 CMake 编译main.cpp
并将生成的可执行文件命名为test
。通常,main.cpp
包含程序的入口点,即main
函数。target_link_libraries(test absl::flat_hash_map src)
: 这行命令用于将库链接到您的目标可执行文件(这里是test
)上。这意味着它指定了构建test
时需要使用的库。absl::flat_hash_map
:来自于 Abseil 库的组件,这里作为一个链接目标。它表明您的程序使用了 Abseil 中的flat_hash_map
容器。src
:这是指在之前通过add_subdirectory(src)
添加的子目录。假设src
目录下的CMakeLists.txt
中定义了一个库(例如静态库或共享库),则src
代表该库。这样,test
可执行文件会链接该目录下定义的目标。