【问题标题】:How exactly does CMake work?CMake 究竟是如何工作的?
【发布时间】:2013-07-05 16:44:48
【问题描述】:

我并不是只为自己提出这个要求。我希望这个问题能成为许多喜欢我的新手的参考,因为对于这么小的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在构建项目之前究竟是在配置和生成什么?

【问题讨论】:

  • 我知道源代码外的构建。如果有人没有进行源代码构建并且仍在寻找清理生成文件的方法,则此技术效果很好:stackoverflow.com/a/12055610/453673
  • aosabook.org/en/cmake.html 上有精彩的描述,并且可能对问题进行了深入的回答(此处无法简单概括)。
  • @SebTu 链接断开。 cmake.html 页面不存在。
  • @Nav Yap,搞砸了标记语法,抱歉。因此,这里是更正的版本:对于刚接触 cmake 的人,我真的建议阅读 architecture of cmake。它提供了足够的信息来感受 cmake 的工作原理,而不会失去细节。

标签: cmake


【解决方案1】:

如其网站所述:

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/编译器生成makefile。

【讨论】:

  • 谢谢帕特里克。有用的答案,但您链接到的 pdf 主要解释了学习 CMake 的第二阶段,这基本上是 CMake 的实现。我问的是第一阶段的解释,一个人必须了解 CMake 到底发生了什么!
  • @Nav 我已经扩展了我的答案。您仍然可以在网上搜索更多信息。
  • 这与回答的问题相去甚远。
【解决方案2】:

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

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

好消息是,CMake 可以很好地让您远离这些混乱:使用out-of-source builds,您甚至不必查看生成的文件。如果你到目前为止还没有这样做(我猜是这样,因为你写了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 - 这是一个持久的键/值字符串存储,用于在运行之间缓存值。存储在此处的值可以是库依赖项的路径,也可以是是否要构建可选组件。变量列表与您在运行ccmakecmake-gui 时看到的大部分相同。不时查看这可能很有用,但我建议尽可能使用上述工具更改任何值。
  • 生成的文件 - 这可以是任何东西,从自动生成的源文件到可帮助您将构建的项目与其他 CMake 项目重新集成的导出宏。其中大部分是按需生成的,不会出现在一个简单的项目中,例如您问题中的项目。
  • 其他任何事情都是让构建系统满意的噪音。特别是,我从来不需要关心 CMakeFiles 子目录中发生的任何事情。

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

【讨论】:

  • 谢谢。知道源代码之外的构建,但正如您所见,提出这个问题的目的是为了了解更多。您答案的 CMakeCache.txt 部分确实有帮助。我正在寻找的正是这种解释。另外,我的问题的最后一句话:“cmake在构建项目之前究竟是什么配置和生成
  • CMakeFiles 目录包含 CMakeError.logCMakeOutput.log 对于 CMake 构建故障排除很重要。
  • 有时您需要在CMakeFiles/target_name.dir 目录中检查的两件事是flags.makelink.txt 文件。我不得不在复杂的项目中检查这些,它从上游项目继承了标志/链接的东西。例如:我有一些错误,因为 TPL A 依赖于 TPL B。我的项目也依赖于 B,我在本地安装了它;但是 A 使用了我系统中的 B 版本(而不是我的本地安装),它具有不同的启用选项,并且它首先出现,导致我的项目出现错误。仅查看 link.txt 我才发现正在发生这种情况。
【解决方案3】:

CMake 的具体工作原理是开发人员的问题,所以这里无法回答这个问题。

但是,我们可以提供一些有用的指导,说明您应该何时使用 CMake,以及何时需要担心它是如何工作的。我也不喜欢“哦,它可以正常工作”的答案——因为,尤其是在软件中,没有任何东西可以“正常工作”,而且你总是必须在某些时候深入了解细节。

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

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

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

【讨论】:

    猜你喜欢
    • 2011-06-26
    • 2021-08-15
    • 2012-06-08
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 2011-06-01
    • 1970-01-01
    相关资源
    最近更新 更多