209

我不只是为了我自己。CMakeLists.txt我希望这个问题能成为许多喜欢我的新手的参考,因为对于这么小的文件 ,幕后究竟发生了什么感到非常困惑

cmake_minimum_required (VERSION 2.6)
project(Tutorial)
add_executable(Tutorial tutorial.cpp)

还有这么小的tutorial.cpp

int main() { return 0; } 

生成了很多文件

CMakeCache.txt  cmake_install.cmake  Makefile
CMakeLists.txt  tutorial.cpp

和一个CMakeFiles包含这么多文件和文件夹的文件夹

CMakeCCompiler.cmake               CMakeOutput.log    Makefile.cmake
cmake.check_cache                  CMakeSystem.cmake  progress.marks
CMakeCXXCompiler.cmake             CMakeTmp           TargetDirectories.txt
CMakeDetermineCompilerABI_C.bin    CompilerIdC        Tutorial.dir
CMakeDetermineCompilerABI_CXX.bin  CompilerIdCXX
CMakeDirectoryInformation.cmake    Makefile2

不了解幕后发生的事情(即:为什么必须生成文件以及它们的目的是什么)是学习 CMake 的最大障碍。

如果有人知道,请您为后代解释一下吗?这些文件的用途是什么,当我键入时cmake .,cmake 在构建项目之前究竟是在配置和生成什么?

4

3 回答 3

117

秘诀是您不必了解生成的文件的作用。

CMake 在构建系统中引入了很多复杂性,其中大部分只有在您使用它来构建复杂的软件项目时才会得到回报。

好消息是,CMake 很好地避免了这些混乱:使用源外构建,您甚至不必查看生成的文件。如果你到目前为止还没有这样做(我猜是这样,因为你写了cmake .),请在继续之前检查它们。使用 CMake 混合构建目录和源目录真的很痛苦,而且不是系统应该使用的方式。

简而言之:而不是

cd <source_dir>
cmake .

总是使用

cd <build_dir_different_from_source_dir>
cmake <source_dir>

我通常在我的源目录中使用一个空的子文件夹build作为构建目录。

为了减轻您的痛苦,让我快速概述一下 CMake 生成的相关文件:

  • 项目文件/Makefiles - 你真正感兴趣的:在选定的生成器下构建项目所需的文件。这可以是从 Unix Makefile 到 Visual Studio 解决方案的任何内容。
  • CMakeCache.txt - 这是一个持久的键/值字符串存储,用于在运行之间缓存值。存储在此处的值可以是库依赖项的路径,也可以是是否要构建可选组件。ccmake变量列表与您在运行或时看到的大部分相同cmake-gui。不时查看这可能很有用,但我建议尽可能使用上述工具更改任何值。
  • 生成的文件- 这可以是从自动生成的源文件到导出宏的任何内容,可帮助您将构建的项目与其他 CMake 项目重新集成。其中大部分仅按需生成,不会出现在简单项目中,例如您问题中的项目。
  • 其他任何事情都是让构建系统满意的噪音。特别是,我从来不需要关心CMakeFiles子目录中发生的任何事情。

一般来说,您不应该弄乱 CMake 为您生成的任何文件。所有问题都可以通过CMakeLists.txt一种或另一种方式从内部解决。只要结果按预期构建您的项目,您可能就可以了。不要太担心血淋淋的细节——因为这是 CMake 一开始就试图让你摆脱的。

于 2013-07-08T13:58:36.957 回答
19

如其网站所述:

Cmake 是跨平台的开源构建系统,用于使用独立于编译器的方法管理软件的构建过程

在大多数情况下,它用于生成项目/制作文件 - 在您的示例中,它已生成Makefile用于构建您的软件(主要在 Linux/Unix 平台上)。

Cmake 允许提供跨平台构建文件,这些构建文件将为特定的编译/平台生成平台特定的项目/make 文件。

例如,您可以尝试在 Windows 上使用 Visual Studio 编译您的软件,然后在您的CMakeLists.txt文件中使用正确的语法,您可以启动

cmake .

在 Windows 平台上的项目目录中,Cmake 将生成所有必要的项目/解决方案文件(.sln等)。

如果您想在 Linux/Unix 平台上构建您的软件,您只需转到您拥有CMakeLists.txt文件的源目录并触发cmake .它,它将生成您通过简单 makemake all.

在这里你有一些关于关键 Cmake 功能的很好的介绍http://www.elpauer.org/stuff/learning_cmake.pdf

编辑

如果您想让平台相关库包含/变量定义等,您可以在CMakeLists.txt文件中使用此语法

IF(WIN32)
   ...do something...
 ELSE(WIN32)
   ...do something else...
 ENDIF(WIN32)

还有很多命令可以用来防止构建失败,并且 Cmake 会通知你,例如你没有 boost 库filesystemregex安装在你的系统上。为此,您可以使用以下语法:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

检查它是否会为适当的系统/IDE/编译器生成生成文件。

于 2013-07-08T11:23:37.750 回答
7

CMake 究竟如何工作是开发人员的问题,所以这个问题在这里无法回答。

但是,我们可以提供一些有用的指导,说明何时应该使用 CMake,以及何时需要担心它是如何工作的。我也不喜欢“哦,它只是工作”的答案——因为,特别是在软件中,没有什么是“正常工作”的,你总是必须在某些时候进入细节。

CMake 是一种工业级工具。它自动化了几个非常复杂的过程,并考虑了您可能不知道的许多变量,特别是作为一个相当新的开发人员,可能对 CMake 可以处理的所有操作系统和构建工具的了解有限。生成这么多文件以及事情看起来如此复杂的原因是因为所有其他系统都很复杂,必须加以考虑和自动化。此外,还有“缓存”问题和该工具的其他节省时间的功能要了解 CMake 中的所有内容,就意味着了解这些构建工具和操作系统中的所有内容以及这些变量的所有可能组合,您可以想象这是不可能的。

需要注意的是,如果你不负责管理大型跨平台构建系统,而且你的代码库是几个 KLOC,可能高达 100KLOG,使用 CMake 似乎有点像使用 100,000 美元的林业树木移除机器从 2 英尺乘 2 英尺的花园中清除杂草。(顺便说一句,如果你从未见过这样的机器,你应该在 youtube 上找一个,它们很棒)

如果您的构建系统又小又简单,最好只手动编写自己的 makefile 或自己编写脚本。当您的 makefile 变得笨拙或您需要在另一个平台上构建系统版本时,您可以切换到 CMake。到那时,您将有很多问题需要解决,您可以提出更集中的问题。同时,查看一些关于 CMake 的好书,或者更好的是,自己写一本!8)

于 2019-11-07T19:29:12.030 回答