返回介绍

1.1 将单个源文件编译为可执行文件

发布于 2025-05-06 21:45:53 字数 6530 浏览 0 评论 0 收藏

NOTE : 此示例代码可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-01/recipe-01 中找到,包含 C++、C 和 Fortran 示例。该示例在 CMake 3.5 版(或更高版本) 中是有效的,并且已经在 GNU/Linux、macOS 和 Windows 上进行过测试。

本节示例中,我们将演示如何运行 CMake 配置和构建一个简单的项目。该项目由单个源文件组成,用于生成可执行文件。我们将用 C++讨论这个项目,您在 GitHub 示例库中可以找到 C 和 Fortran 的例子。

准备工作

我们希望将以下源代码编译为单个可执行文件:

#include <cstdlib>
#include <iostream>
#include <string>
​
std::string say_hello() { return std::string("Hello, CMake world!"); }
​
int main() {
  std::cout << say_hello() << std::endl;
  return EXIT_SUCCESS;
}

具体实施

除了源文件之外,我们还需要向 CMake 提供项目配置描述。该描述使用 CMake 完成,完整的文档可以在 https://cmake.org/cmake/help/latest/ 找到。我们把 CMake 指令放入一个名为 CMakeLists.txt 的文件中。

NOTE : 文件的名称区分大小写,必须命名为 CMakeLists.txt ,CMake 才能够解析。

具体步骤如下:

  1. 用编辑器打开一个文本文件,将这个文件命名为 CMakeLists.txt
  2. 第一行,设置 CMake 所需的最低版本。如果使用的 CMake 版本低于该版本,则会发出致命错误:
    cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
  3. 第二行,声明了项目的名称( recipe-01 ) 和支持的编程语言(CXX 代表 C++):
    project(recipe-01 LANGUAGES CXX)
  4. 指示 CMake 创建一个新目标:可执行文件 hello-world 。这个可执行文件是通过编译和链接源文件 hello-world.cpp 生成的。CMake 将为编译器使用默认设置,并自动选择生成工具:
    add_executable(hello-world hello-world.cpp)
  5. 将该文件与源文件 hello-world.cpp 放在相同的目录中。记住,它只能被命名为 CMakeLists.txt
  6. 现在,可以通过创建 build 目录,在 build 目录下来配置项目:
    $ mkdir -p build
    $ cd build
    $ cmake ..
    ​
    -- The CXX compiler identification is GNU 8.1.0
    -- Check for working CXX compiler: /usr/bin/c++
    -- Check for working CXX compiler: /usr/bin/c++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/user/cmake-cookbook/chapter-01/recipe-01/cxx-example/build
  7. 如果一切顺利,项目的配置已经在 build 目录中生成。我们现在可以编译可执行文件:
    $ cmake --build .
    ​
    Scanning dependencies of target hello-world
    [ 50%] Building CXX object CMakeFiles/hello-world.dir/hello-world.cpp.o
    [100%] Linking CXX executable hello-world
    [100%] Built target hello-world

工作原理

示例中,我们使用了一个简单的 CMakeLists.txt 来构建“Hello world”可执行文件:

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(recipe-01 LANGUAGES CXX)
add_executable(hello-world hello-world.cpp)

NOTE : CMake 语言不区分大小写,但是参数区分大小写。

TIPS : CMake 中,C++是默认的编程语言。不过,我们还是建议使用 LANGUAGES 选项在 project 命令中显式地声明项目的语言。

要配置项目并生成构建器,我们必须通过命令行界面(CLI) 运行 CMake。CMake CLI 提供了许多选项, cmake -help 将输出以显示列出所有可用选项的完整帮助信息,我们将在书中对这些选项进行更多地了解。正如您将从 cmake -help 的输出中显示的内容,它们中的大多数选项会让你您访问 CMake 手册,查看详细信息。通过下列命令生成构建器:

$ mkdir -p build
$ cd build
$ cmake ..

这里,我们创建了一个目录 build (生成构建器的位置),进入 build 目录,并通过指定 CMakeLists.txt 的位置(本例中位于父目录中) 来调用 CMake。可以使用以下命令行来实现相同的效果:

$ cmake -H. -Bbuild

该命令是跨平台的,使用了 -H-B 为 CLI 选项。 -H 表示当前目录中搜索根 CMakeLists.txt 文件。 -Bbuild 告诉 CMake 在一个名为 build 的目录中生成所有的文件。

NOTE : cmake -H. -Bbuild 也属于 CMake 标准使用方式: https://cmake.org/pipermail/cmake-developers/2018-January/030520.html 。不过,我们将在本书中使用传统方法(创建一个构建目录,进入其中,并通过将 CMake 指向 CMakeLists.txt 的位置来配置项目)。

运行 cmake 命令会输出一系列状态消息,显示配置信息:

$ cmake ..
​
-- The CXX compiler identification is GNU 8.1.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/cmake-cookbook/chapter-01/recipe-01/cxx-example/build

NOTE : 在与 CMakeLists.txt 相同的目录中执行 cmake . ,原则上足以配置一个项目。然而,CMake 会将所有生成的文件写到项目的根目录中。这将是一个源代码内构建,通常是不推荐的,因为这会混合源代码和项目的目录树。我们首选的是源外构建。

CMake 是一个构建系统生成器。将描述构建系统(如:Unix Makefile、Ninja、Visual Studio 等) 应当如何操作才能编译代码。然后,CMake 为所选的构建系统生成相应的指令。默认情况下,在 GNU/Linux 和 macOS 系统上,CMake 使用 Unix Makefile 生成器。Windows 上,Visual Studio 是默认的生成器。在下一个示例中,我们将进一步研究生成器,并在第 13 章中重新讨论生成器。

GNU/Linux 上,CMake 默认生成 Unix Makefile 来构建项目:

  • Makefile : make 将运行指令来构建项目。
  • CMakefile :包含临时文件的目录,CMake 用于检测操作系统、编译器等。此外,根据所选的生成器,它还包含特定的文件。
  • cmake_install.cmake :处理安装规则的 CMake 脚本,在项目安装时使用。
  • CMakeCache.txt :如文件名所示,CMake 缓存。CMake 在重新运行配置时使用这个文件。

要构建示例项目,我们运行以下命令:

$ cmake --build .

最后,CMake 不强制指定构建目录执行名称或位置,我们完全可以把它放在项目路径之外。这样做同样有效:

$ mkdir -p /tmp/someplace
$ cd /tmp/someplace
$ cmake /path/to/source
$ cmake --build .

更多信息

官方文档 https://cmake.org/runningcmake/ 给出了运行 CMake 的简要概述。由 CMake 生成的构建系统,即上面给出的示例中的 Makefile,将包含为给定项目构建目标文件、可执行文件和库的目标及规则。 hello-world 可执行文件是在当前示例中的唯一目标,运行以下命令:

$ cmake --build . --target help
​
The following are some of the valid targets for this Makefile:
... all (the default if no target is provided)
... clean
... depend
... rebuild_cache
... hello-world
... edit_cache
... hello-world.o
... hello-world.i
... hello-world.s

CMake 生成的目标比构建可执行文件的目标要多。可以使用 cmake --build . --target <target-name> 语法,实现如下功能:

  • all (或 Visual Studio generator 中的 ALL_BUILD) 是默认目标,将在项目中构建所有目标。
  • clean ,删除所有生成的文件。
  • rebuild_cache ,将调用 CMake 为源文件生成依赖(如果有的话)。
  • edit_cache ,这个目标允许直接编辑缓存。

对于更复杂的项目,通过测试阶段和安装规则,CMake 将生成额外的目标:

  • test (或 Visual Studio generator 中的 RUN_TESTS ) 将在 CTest 的帮助下运行测试套件。我们将在第 4 章中详细讨论测试和 CTest。
  • install ,将执行项目安装规则。我们将在第 10 章中讨论安装规则。
  • package ,此目标将调用 CPack 为项目生成可分发的包。打包和 CPack 将在第 11 章中讨论。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。