我在C / C ++上编码并使用(GNU)Makefile来编译代码。我可以用CMake做同样的事情并获得MakeFile。但是,使用Makefile和CMake编译代码有什么区别?
答案 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
执行两步构建:它在ninja
或make
或许多其他生成器中生成低级构建脚本,然后运行它。通常堆积在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也算在内),而且它们都很恐怖。
说实话,这是CMake
和make
的共同点-它们的语言非常恐怖:
开始。
但是在CMake
中,您编写的代码行要少得多。