如何在20分钟内学会CMake


如果您曾经工作或编写过 C 或 C++ 项目,那么您可能听说过称为 CMake 的构建系统。对于刚接触 C 或 C++ 的程序员来说,单独的构建系统使用单独的语言的概念可能看起来很奇怪。但是,如何正确编译、构建和打包项目的知识对于 C++ 程序员来说绝对是必不可少的知识。在本指南中,将解释 CMake 作为构建系统所扮演的角色,并讨论 CMake 最重要的方面和功能。您将在 20 分钟内学习如何使用 CMake 构建库和可执行文件。

一、什么是CMake ?

百度百科

CMake官网

二、为什么要使用CMake ?

与许多其他编程语言不同,c++编译器没有一个集中分布的、单一的。c++语言是按照ISO标准规范建模的,像Microsoft或Clang这样的编译器供应商随后实现了ISO标准规范。每一个编译器都有不同的设置和选项,并且运行在不同的操作系统上。大多数c++程序都是为了跨平台和在任何现代编译器上运行而编写的,用定制的构建脚本来实现这一点是很困难的。这需要每个编译器和操作系统的详细知识,以及大量的知识。

CMake从一个用CMake语言编写的抽象脚本生成c++项目的构建系统。CMake提供了一个接口来指定构建选项和过程,而不涉及编译器或操作系统的特定细节。请注意,它只涵盖了用于构建项目的跨平台功能,您仍然需要负责在不同平台上运行的实际源代码。

三、项目结构和CMakeLists.txt文件

有多种方式来布局一个c++项目。有些项目将头文件和源文件分开,有一个include目录和一个src目录,而有些项目将头文件和源文件放在同一个目录中。为此目的,我们将使用头文件目录和源文件目录的组合,因此项目结构稍微简单一些。

在每个项目的开始必须是一个CMakeLists.txt文件。这是CMake识别为构建脚本文件的文件名。一个项目可以有多个CMakeLists.txt,但每个目录中只能有一个。对于项目顶层目录中的文件,必须在文件的顶部显示以下内容:

cmake_minimum_required(VERSION 3.6) 
project(foo)

这两行代码表示了构建项目所需的cmake的最小版本,以及项目的名称。在这种情况下,最小版本并不重要,只要它至少是3.0。让我们再看看下面的示例项目布局:

- CMakeLists.txt
- some.h
- some.cpp
- main.cpp

这里有一个CMake文件CMakeLists.txt,一个头文件some.h和一个源文件some.cpp。还有另一个源文件main.cpp。在大多数c++项目中,有一个包含项目代码的库供其他项目和程序使用,还有一个可执行文件,允许项目中的一些代码作为CLI程序运行。对于本例,some.cpp将表示核心库代码,而main.cpp将表示同样构建的可执行文件。

四、构建库

为了让CMake构建库,组成库的源文件需要在cmakelist .txt文件中指定。为此,我们必须构造一个文件列表并调用add_library函数。

在CMake中,重要的是要理解变量和数据类型的工作方式可能与其他任何语言都不同。CMake中的所有变量都是字符串。CMake中的列表是包含分隔符的字符串; 。 使用set()unset()函数创建和销毁变量。下面是一个创建列表并打印它的示例。

set(some_var "a" "b" "c")
message("${some_var}")

这将打印:

a;b;c

上面是CMake的另一个重要特性,变量访问。通过set()函数创建变量后,它的值只能通过语法${var}访问。这是因为在CMake中,所有内容都是字符串。即使没有带引号的值也是字符串。语句message(hello)hello视为一个5个字符的字符串。

现在,为了构建库,我们必须将以下内容添加到构建文件CMakeLists.txt中:

set(FOO_SOURCES some.cpp)
add_library(foos STATIC "${FOO_SOURCES}")

在对add_library()的调用中,通过${}语法访问源变量。然而,我们也传递另一个参数SHARED。这告诉CMake我们是想要静态库还是共享库。

五、添加可执行

现在我们已经向构建文件添加了一个库,我们可以扩展该文件以包含构建可执行文件并将库链接到该可执行文件的说明。让我们创建一个简单的c++文件main.cpp,它调用库中的一个函数:

#include "some.h"
int main(int argc, char const* argv[]) {
    someFunc(); //定义在some.cpp
    return 0;
}

然后,我们可以在构建文件中添加以下内容:

add_executable(foot main.cpp)
target_link_libraries(foot foos)

add_executable函数的工作原理与add_library非常相似,它接受一个name变量和一个表示源文件的列表。在这种情况下,因为我们知道我们的可执行文件只有一个额外的源文件,所以我们不需要一个单独的变量来将源文件表示为一个列表,我们可以直接传递它。target_link_libraries函数的第一个参数是一个目标,然后是必须是库的其他目标的列表,就像第一个参数一样。

在CMake中,“目标(target)”是一个由CMake生成的生成系统构建的对象。在本例中,库和可执行文件都是构建目标。在更复杂的项目中,定制目标有时用于表示所构建项目所需的文件的创建。但是现在,让我们只关注基本的构建目标。

六、综合在一起

现在已经讨论了编写CMakeLists.txt文件的过程,我们可以开始运行CMake,然后使用CMake生成的构建系统来编译我们的代码。如果你的系统上还没有安装CMake,通常你可以通过运行brew install CMake来安装它。否则,请尝试***此链接***。

CMake通常在一个空目录中运行,该目录引用CMakeLists.txt根文件所在的路径。例如,如果当前在项目的目录中,通常会使用以下命令:

mkdir build
cd build
cmake ..

这将运行CMake,并让它在当前目录中生成构建文件。它将打印出大量与它检测到并用于生成这些文件的编译器相关的信息。

接下来,您将实际运行CMake生成的文件并编译项目。如果您使用的是MacOS系统或Linux系统,您将运行make。如果你是在windows系统上,你通常会运行 msbuild ALL_BUILD.vcxproj。这将导致编译器运行并尝试编译您的代码。

注意:如果你的代码有语法错误或写得不正确,这可能会失败。CMake不检测或检查语言语法,它只关心构建过程*。


就这样! 希望到现在为止,您对 CMake 感到很自在,可以编写自己的构建文件,并使用它在 C++ 中创建简单的项目。 总的来说,CMake 是一个庞大的框架,包含许多专门的组件,可以帮助构建几乎所有 C++ 项目。 随着您的进步和对它的熟悉,您可能需要更高级和复杂的 CMake,例如拥有多个子目录,或添加 3rd 方库作为项目的依赖项。

如有侵权,请联系删除。

CMake 是一个跨平台的构建工具,用于生成与编译器无关的构建脚本。学会编写 CMakeLists.txt 文件是使用 CMake 的关键。 以下是一些帮助你快速学习 CMakeLists 的步骤: 1. 了解基本语法:CMakeLists 文件使用 CMake 语言编写,它有自己的语法规则。你可以通过阅读 CMake 官方文档或教程来了解基本的语法。 2. 创建项目目录结构:通常,一个 CMake 项目包含一个主目录和多个子目录。主目录包含顶级的 CMakeLists 文件,而子目录包含其他源代码文件、库和可执行文件。 3. 编写顶级 CMakeLists 文件:在主目录中创建一个名为 CMakeLists.txt 的文件。在该文件中,你需要指定项目的名称、最低 CMake 版本要求以及其他全局设置。 4. 添加子目录:如果你的项目有多个子目录,可以使用 `add_subdirectory()` 命令将它们添加到顶级 CMakeLists 文件中。这样可以使得每个子目录都有自己的 CMakeLists 文件来管理子目录的构建规则。 5. 设置编译选项:使用 `add_compile_options()` 命令来设置编译选项,例如编译器标志、预处理器定义等。 6. 添加源代码文件和库:使用 `add_executable()` 命令来添加可执行文件,使用 `add_library()` 命令来添加库。你需要指定源代码文件的路径和名称。 7. 链接库和可执行文件:使用 `target_link_libraries()` 命令将库链接到可执行文件中,以便在构建过程中解析依赖关系。 8. 其他设置和操作:根据你的项目需求,可能需要进行其他设置和操作,如设置包含路径、链接其他第三方库等。 以上是一个简单的步骤概述,帮助你快速入门 CMakeLists 的编写。当然,CMake 还有更多高级功能和选项,你可以根据具体需求学习和使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值