Cmake、GNU Make和手动编译的区别

43

我是编程新手,所以这更多是一个抽象问题而不是技术问题。我一直在使用集成开发环境(IDE)进行学习,但听说它们在创建可执行文件时往往过于简化编译、汇编和链接的过程。

我正在尝试下载和编译一个库(在这种情况下是librocket),而不依赖于IDE。我首先需要使用Cmake创建二进制文件。在配置和生成后,在输出目录中没有看到任何目标文件或.cpp文件。然后我必须使用GNU make命令才能在输出目录中创建目标文件和.cpp文件。

Cmake和GNU make从下载源代码到实际创建目标文件的步骤是什么?编译器和链接器的调用是在哪个阶段进行的?

我已成功编译了一个测试库,并使用g++编译了另一个链接到它上面的程序,但我有点迷失,因为我必须使用Cmake和GNU make而不是直接调用编译器。


1
你应该能够编写一个库并使用它来编写程序,而不需要使用make或Cmake。它们是非常高级的辅助工具。 - user755921
2个回答

48

Cmake是一个"项目生成器"。它实际上不会构建任何目标文件等;它所做的是为其他工具(如GNU make)生成控制文件,这些工具将构建目标文件等。

使用cmake而不是直接编写makefile的优点在于,使用相同的cmake输入文件,cmake可以为各种不同的构建控制工具生成项目文件:除了makefile之外,它还可以生成Xcode(Mac OS X)项目文件,Microsoft Visual Studio项目文件以及其他工具(如Ninja)的控制文件。如果您正在编写需要在许多不同平台上构建的软件,则使用cmake通常是一个不错的选择。

对于您的情况,具体操作如下:cmake仅生成一组makefiles。当您拥有一个干净的工作空间时,通常只需要执行此操作一次。然后,您运行make,该工具使用这些makefiles根据需要调用编译器,以便在各种文件更改时进行编译。makefiles 还具有重新运行 cmake 自身的规则,如果任何 cmake 输入文件发生更改。


3
最终,makefile 是否仍会执行像 g++ 这样带有一堆选项的编译器命令来生成目标文件,还是说它完全做了其他事情? - kristhedemented
5
是的,make确实会使用一系列选项调用g++编译器,但只有在Makefile中提供了使用g++的相关信息时,它才会这样做。你可以将make看作是一种脚本语言,用于自动构建具有许多(内部)依赖关系的程序,这些程序源自复杂的源代码树。 - Roberto
6
@kristhedemented 是的,make只是调用命令。它没有任何内置的编译功能。对于由cmake生成的makefile,如果想要查看make调用的命令,可以运行make VERBOSE=1 - MadScientist

16
在编译拥有大量文件的项目时,如果直接调用编译器可能会让你感到困惑。当然,你可以将相关命令放在脚本中并运行它,但是这种情况下,如果你添加/删除了一个文件,就需要更新脚本。此外,在这种情况下,如果你只想编译已更改的部分而不是每次做出小更改就重新编译所有内容,那么你希望只编译更改过的部分。如果你在假设脚本中添加了这个(和其他提高开发效率的)功能,那么你将要重新发明makemake旨在仅运行自上次调用make以来更改的代码部分的编译。它还允许您自动添加源文件等。
然而,如果你的代码需要与不同编译器、平台和链接到不同库等方案一起工作,那么对于make来说事情就有点复杂了。你仍然可以做到,但这需要很多工作。这就是cmake出现的原因。 cmake为你想要的系统构建makefile(或类似的构建系统,例如:Visual Studio)。cmake具有预先构建的不同编译器和系统的文件,将自动找到正确的编译器标志集并链接到正确的库等。

当然,如果您正在编写一个类似于“Hello World!”的程序,您既不需要make也不需要cmake。如果您不需要支持多个编译器/平台,则不需要cmake。但如果您正在开发某些庞大的库或应用程序,makecmake将帮助您更轻松地完成任务。


1
写得非常好。我一直在寻找这样的解释。 - Albert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接