使用Makefile和CMake编译代码有什么区别?

19 浏览
0 Comments

使用Makefile和CMake编译代码有什么区别?

我使用C/C++编码并使用(GNU) Makefile编译代码。我也可以使用CMake做同样的事情并获得Makefile。不过,使用Makefile和CMake编译代码有什么区别呢?

admin 更改状态以发布 2023年5月20日
0
0 Comments

关于CMake是“构建生成器”的说法是一个常见的误解。

它在技术上并没有错,只是描述了它的工作方式,而未描述它实际上是做什么。

在这个问题的上下文中,它们做的事情是一样的:将一堆C / C ++文件转换成二进制文件。

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

  • CMake更高级。它专门编译C ++,你编写的构建代码更少,但也可以用于通用构建。 make 也有一些内置的C / C ++规则,但它们最多是无用的。

  • CMake 进行了两步构建:它生成了一个低级构建脚本,使用 ninja make 或许多其他生成器,然后您运行它。通常堆积在 Makefile 中的所有shell脚本块仅在生成阶段执行。因此,CMake 构建速度可以快几个数量级。

  • CMake 的语法易于支持外部工具,比 make 更容易

  • 一旦 make 构建了一个工件,它就会忘记它是如何构建的。它是从什么源构建的,使用了什么编译器标志?CMake 追踪它,而 make 则留给你自己决定。如果一个库源自上一个 Makefile 版本以来被移除, make 不会重新构建它。

  • 现代的CMake (从版本3开始)以“目标”之间的依赖关系为基础。目标仍然是单个输出文件,但它可以具有传递性(CMake术语中的“公共”/“接口”)依赖项。这些传递性依赖项可以向依赖包公开或隐藏。CMake 将为您管理目录。使用 make ,您只能在逐个文件和手动管理目录的基础上工作。

你可以使用中间文件在make中编写一些东西来处理最后两个空隙,但是你得自己完成。 make包含了一个图灵完备的语言(有时候甚至包含两个或三个语言,如Guile),但前两个语言都很糟糕,而Guile几乎从未使用。

老实说,这就是CMakemake所共有的 —— 它们的语言都相当糟糕。我能想到的有:

  • 它们没有用户定义的类型;
  • CMake有三种数据类型:字符串、列表和带属性的目标。而make只有一个:字符串;
  • 你通常通过设置全局变量将参数传递给函数。
    • 现代的CMake部分地解决了这个问题 - 你可以设置一个目标的属性:set_property(TARGET helloworld APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}");
  • 默认情况下,引用未定义的变量会被静默忽略;
0
0 Comments

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

CMake是一个构建系统生成器。它可以生成Makefile,也可以生成Ninja构建文件,可以生成KDevelop或Xcode项目,还可以生成Visual Studio方案。从相同的起点,相同的CMakeLists.txt文件出发。因此,如果您有一个跨平台项目,则CMake是使其构建系统无关的一种方法。

如果您有习惯于Visual Studio的Windows开发人员和发誓要使用GNU Make的Unix开发人员,则可以使用CMake。

我始终建议如果您的项目要多平台或者广泛使用,则使用CMake(或其他构建系统生成器,但CMake是我的个人首选)。CMake本身还提供了一些不错的功能,如依赖检测、库接口管理或与CTest、CDash和CPack的集成。

使用构建系统生成器可以使您的项目更具未来性。即使您现在只使用GNU-Make,如果您以后决定扩展到其他平台(无论是Windows还是嵌入式系统),或者只想使用IDE,也没有问题。

0