使用Makefile和CMake编译代码之间的区别

时间:2014-09-11 14:07:47

标签: c++ c makefile cmake

我在C / C ++上编码并使用(GNU)Makefile来编译代码。我可以用CMake做同样的事情并获得MakeFile。但是,使用Makefile和CMake编译代码有什么区别?

2 个答案:

答案 0 :(得分:305)

Make(或者更确切地说是Makefile)是一个构建系统 - 它驱动编译器和其他构建工具来构建代码。

CMake是构建系统的生成器。它可以生成Makefile,它可以生成Ninja构建文件,它可以生成KDEvelop或XCode项目,它可以生成Visual Studio解决方案。从同一个起点开始,使用相同的CMakeLists.txt文件。因此,如果您有一个独立于平台的项目,那么CMake也是一种使其与构建系统无关的方法。

如果您的Windows开发人员习惯于使用GNU Make发誓的Visual Studio和Unix开发人员,那么CMake就是其中一种方式。

如果您打算将项目设置为多平台或广泛可用,我总是建议使用CMake(或其他构建系统生成器,但CMake是我个人的偏好)。 CMake本身也提供了一些很好的功能,如依赖检测,库接口管理或与CTest,CDash和CPack的集成。

使用构建系统生成器可以使您的项目更加面向未来。即使您现在只使用GNU-Make-only,如果您以后决定扩展到其他平台(无论是Windows还是嵌入式设备),或者只是想使用IDE,该怎么办?

答案 1 :(得分:7)

关于CMake是“生成器”的说法是一个普遍的误解。

从技术上讲这不是错;它只是描述了它如何工作,而不是它做什么。

在问题的上下文中,它们做同样的事情:获取一堆C / C ++文件并将其转换为二进制文件。

那么,真正的区别是什么?

  • CMake更高级。它专为编译C ++而设计,您可以为其编写更少的构建代码,但也可以用于通用构建。 make也具有一些内置的C / C ++规则,但它们几乎没有用。

  • CMake执行两步构建:它在ninjamake或许多其他生成器中生成低级构建脚本,然后运行它。通常堆积在Makefile中的所有shell脚本片段仅在生成阶段执行。因此,CMake的构建速度可以提高几个数量级。

  • CMake的语法更容易支持外部工具than make's

  • make一旦构建了工件,就会忘记其构建方式。它是由什么来源构建的,哪些编译器标志? CMake对其进行跟踪,make由您自己决定。如果自Makefile的先前版本以来删除了一个库资源,则make将不会重建它。

  • 现代CMake(从版本3.something开始)适用于“目标”之间的依赖项。目标仍然是单个otput文件(很遗憾),但是可以具有传递性(CMake术语为“ public” /“ interface”)依赖性。 这些可传递依赖项可以从依赖包中公开或隐藏。 CMake也将为您管理目录。使用make,您将陷入逐个文件和手动管理目录的状态。

您可以使用标志文件在make中编写代码,以弥补最后两个空白,但您自己一个人。 make确实包含一个Turing complete language(偶数两个,有时三个Guile也算在内),而且它们都很恐怖。

说实话,这是CMakemake的共同点-它们的语言非常恐怖:

  • 它们没有类型;
  • 没有数组,只有空格分隔的字符串,从而避免了地狱;
  • 通常通过设置全局变量将参数传递给函数; (这在现代CMake中正在解决-变量现在可以具有名称空间;目标是其属性的名称空间)
  • 默认情况下,忽略未定义变量的引用;

开始。

但是在CMake中,您编写的代码行要少得多。