#1 楼
Make(或Makefile)是一个构建系统-它驱动编译器和其他构建工具来构建您的代码。CMake是构建系统的生成器。它可以产生Makefile,可以产生Ninja构建文件,可以产生KDEvelop或Xcode项目,可以产生Visual Studio解决方案。从相同的起点,相同的CMakeLists.txt文件。因此,如果您有一个与平台无关的项目,那么CMake也是使其与系统无关的一种方法。
如果您有习惯于Visual Studio的Windows开发人员和Unix开发人员,他们对GNU Make,CMake都非常满意。是一种方法。
如果您打算使项目成为多平台项目,我总是建议使用CMake(或其他构建系统生成器,但CMake是我个人的喜好)。或广泛使用。 CMake本身还提供了一些不错的功能,例如依赖关系检测,库接口管理或与CTest,CDash和CPack的集成。
使用buildsystem生成器可使您的项目更具前瞻性。即使您现在仅使用GNU-Make,如果以后决定扩展到其他平台(Windows或嵌入式产品),或者只是想使用IDE怎么办?
#2 楼
关于CMake是“构建生成器”的说法是一个普遍的误解。从技术上讲这不是错误的;它只是描述了它是如何工作的,而不是它是做什么的。
在问题的上下文中,它们做同样的事情:获取一堆C / C ++文件并将其转换为二进制文件。
所以,真正的区别是什么?
CMake更高级。它专为编译C ++而设计,您可以为其编写更少的构建代码,但也可以用于通用构建。
make
也具有一些内置的C / C ++规则,但充其量是没有用的。CMake
执行两步构建:它在ninja
中生成低级构建脚本或make
或许多其他生成器,然后运行它。通常堆放在Makefile
中的所有shell脚本片段仅在生成阶段执行。因此,CMake
的构建可以快几个数量级。CMake
的语法比make的语法更容易支持外部工具。一旦
make
构建了工件,它就会忘记它是如何构建的。它是由什么来源构建的,哪些编译器标志? CMake
跟踪它,make
留给您。如果自先前版本的Makefile
以来删除了一个库资源,则make
不会重建它。现代
CMake
(从版本3开始)在以下方面的依赖关系方面起作用:目标”。目标仍然是单个输出文件,但它可以具有可传递(在CMake术语中为“ public” /“ interface”)依赖项。这些可传递依赖项可以向依赖包公开或隐藏。
CMake
将为您管理目录。使用make
,您将只能停留在逐个文件和逐个管理目录的级别。您可以使用中间文件在
make
中编写一些代码,以弥补最后两个空白,但您自己一个人。 make
确实包含图灵完整的语言(偶数为两个,有时三个为数)。前两个太可怕了,实际上几乎没有使用过Guile。老实说,这就是
CMake
和make
的共同点-它们的语言非常恐怖。想到的是它们:它们没有用户定义的类型;
CMake
具有三种数据类型:字符串,列表和具有属性的目标。 make
具有一个:字符串; 您通常通过设置全局变量将参数传递给函数。
这在现代CMake中得到了部分解决-您可以设置目标的属性:
set_property(TARGET helloworld APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}")
; 默认情况下会默认忽略对未定义变量的引用;
评论
这里有一些很好的信息,但有句话是完全错误的:cmake具有LIST类型,因为具有适当的LIST函数,这对于许多构建系统任务至关重要,这有点不同:cmake.org/cmake/help/git-master/command /list.html
–解决J
20-2-18在4:01
我不会称其为“完全”错误,但是感谢您的纠正。
– Victor Sergienko
20-2-27在22:56
@VictorSergienko,在OP的问题中没有被问到,但是我正在等待紧急情况……您使用哪种感觉比哪个更好?
–罗伯特·拉格(Robert Lugg)
20 Dec 23 '21:42
我出于历史原因使用make,但我讨厌它。 CMake也不是没有问题(尝试与其交叉编译),但是对于我自己的项目,CMake会成功,因为您编写的代码更少,并且受工具支持。
– Victor Sergienko
20 Dec 24'1:57
评论
谢谢!只是确认一下,如果我只在Linux环境下编程,而不仅仅是makefile就足够了,但是如果我希望Linux上的程序在Mac上比cmake运行,那是更好的选择,因为据我所知,我们不需要在该文件上创建新的makefile Mac,而是运行cmake。这就是重点吗?
–rish
2014年9月12日上午10:17
@rish是的,这就是要点。但是请注意,在Linux上进行编程的方法比Makefiles还要多-参见例如QtCreator,KDEvelop,Ninja。对于其中每一个,它要么是“创建一个项目并使它与Makefile保持同步”,要么是“重新运行CMake”。而且,正如答案所提到的那样,CMake还具有其他功能,例如依赖关系发现(例如find_package())或测试/打包支持。
–Angew不再以SO为荣
2014年9月12日上午10:22
我读到CMake无法创建非递归的makefile。还是这样吗?
– Maxim Egorushkin
2014年9月12日15:17
@Angew非递归是使用完整的项目依赖关系树一次调用make时。与顶级生成文件以特定顺序调用子项目生成文件时的递归相反。
– Maxim Egorushkin
2014-09-12 15:24
这是CMake的一个重要弱点-GNU make会产生皱纹,但是如果您花时间学习它,它将非常强大且用途广泛,并且可以在大量平台上运行。没有完整的依赖树来分析是一个主要缺陷,只是谷歌将其称为“递归使有害”。
– ErikAlapää
15/12/23在7:39