直接使用Make做过时了吗?[关闭]


31

因此,我遇到了很多有关直接创建makefile的评论/帖子/等等,以及在2015年如何做是一件愚蠢的事情。我知道诸如CMake之类的工具,实际上我经常使用CMake。事实是,CMake只是为您创建Makefile,并帮助消除了您自己做的乏味。当然,它还添加了许多其他强大的功能……但是最后它仍然是一个Makefile。

所以我的问题是,关于make的“过时”讨论是指整个Make实用程序,还是仅仅是手动编写自己的Makefile的想法?我根本不使用IDE进行C / C ++开发(只是emacs),所以我总是写Makefile。

如果Make被认为已经过时,那么C / C ++开发人员应该使用什么来构建小型个人项目?


8
对于小型个人项目,make没有Makefile就足够了。有什么麻烦?
ott

8
FreeBSD系统上的每个可用软件(包括台式机和服务器)都具有一个由“ make”启动的Makefile。不会。“ make”不是过时的。
罗布

3
人们可以自由使用IDE,但是如果他们的IDE在make首次编写后将近40年不能支持使用Makefile的项目,那么他们就不应指望人们能够解决此问题。
Miles Rout 2015年

1
“过时的关于谈话使”只是一种症状或一个痛点,而不是贬低的宣言。尤其是当尚无更好的替代方法,而所有减轻疼痛的方法仍以某种方式使用时,对于最容易产生疼痛的用户来说,这些方法是不可见的。尽管给出了很多很好的答案,但问题本身是基于边界观点的。
rwong 2015年

1
CMake是一层抽象。需要这种抽象驯服不符合开放源代码的各种消费者IDE产品Makefile。同样,它不仅是抽象,而且还允许配置(如autoconf)功能。像其他抽象一样,它允许替代方案。但这为CMake用户容易使用的Makefile替代方案的实验性新思路铺平了道路。
舒瓦

Answers:


30

最大的不同是CMake是跨平台的元构建系统。单个CMake项目可以生成常规的Unix / Linux makefile,用于Windows的Visual Studio项目,用于Mac的XCode项目,以及几乎所有您想使用或支持的非元构建系统。

我不会说直接使用make甚至手动编辑makefile是“过时的”,但是除非您正在处理不需要移植到Windows的Unix / Linux东西,否则您可能不应该这样做,就像您的方式一样。如果您想将文件移植到非Windows平台,则不应直接编辑Visual Studio项目文件。如果您对可移植性感兴趣,那么值得学习像Scons或CMake这样的元构建系统。


9
POSIX make也是跨平台的。
Blrfl 2015年

6
@Blrfl这可能是正确的,但是即使您要定位的所有平台都符合POSIX标准,即使您使用“使用所有相同的编译器重新(也仍然会是麻烦的问题的位置包含文件,你是否需要-lm-lnsl等等或这些设施是否包括在C库等)。
2015年

5
@Jules有更多(或更少)功能CMake,它基本上是为使用ELF加载程序的系统创建标准的模块化应用程序而量身定制的,并且为该特定工具链所需的所有工具提供了抽象。如果您脱离了该工具链(例如,裸机的自定义链接描述文件),却CMake突然根本不提供任何支持或可移植性,那么您最终会像以前用来破解完全自定义的构建脚本一样,对其进行破解。
Ext3h 2015年

这同样适用于Q化妆(尽管不是严重的不一致纪录了行为** AP CMake的是),BTW;)
mlvljr

11

难道make真的过时了吗?

我不这么认为。最后,make仍然足够强大,可以提供所需的所有功能,例如更改后的源代码的条件编译等。说的make已经过时,就像说编写自定义链接描述文件已经过时一样。

但是raw make没有提供的是扩展的功能和舒适的库存库,例如参数头生成,集成测试框架,甚至一般只是条件库。

另一方面,CMake直接针对生成通用ELF库和可执行文件进行了调整。每当您离开它们预定义的过程时,就必须CMake像以前破解自己的Makefile一样开始黑客入侵。

考虑到您可以使用C ++创建的内容远远超过了解ELF加载程序的系统的普通应用程序,因此CMake肯定并不适合所有情况。但是,如果您在这样的标准化环境中工作,CMake或者任何其他这些现代脚本生成器框架肯定是您最好的朋友。

它始终取决于您的应用程序的专业程度,以及CMake框架的结构适合您的工作流程的程度。


尽管有用,make却是一个可怕的系统,具有死胡思,奥术语法和大量不必要的限制,这些都会造成很多麻烦。
antred

7

从前,高级语言只是一个想法。人们试图实现编译器。当时存在严重的硬件限制-没有图形工具,因此“纯文本”最终被用作输入文件格式;计算机通常只有极少量的RAM,因此必须将源代码分解成多个部分,并将编译器拆分为单独的实用程序(预处理器,编译器,汇编器,链接器);CPU速度慢且昂贵,因此您无法进行昂贵的优化等。

当然,由于使用了许多源文件和许多实用程序来创建许多目标文件,因此手动构建任何东西都是一团糟。为了解决工具中的设计缺陷(由严重受限的硬件引起),人们自然会开始编写脚本来消除一些麻烦。

可悲的是,脚本笨拙而混乱。为了解决脚本问题(这是由有限的硬件导致的工具设计缺陷的解决方法),人们最终发明了实用程序来简化操作,例如make

然而; makefile笨拙且混乱。为了解决makefile的问题(这是针对由于硬件有限而导致的工具设计缺陷的解决方案),人们开始尝试自动生成的makefile。首先是让编译器生成依赖项;并推出了诸如auto-conf和cmake之类的工具。

这就是我们现在所处的位置:变通办法变通办法变通办法有限硬件导致的工具设计缺陷。

我期望到本世纪末,在现有的基础之上还会有更多的“变通方法”层。具有讽刺意味的是,导致所有这些的严格的硬件限制在几十年前就消失了,而现在我们仍在使用这种古旧混乱的唯一原因是“ 这是一成不变的方式 ”。


1
那么还有什么选择呢?替代方案是否完全改变了我们所知道的构建概念?
JParrilla 2015年

1
@Darkslash:一旦开始考虑(假设的)替代方案,就好比打开闸门-您最终会质疑一切(并最终产生诸如语义和语法分离的想法,并重新设计IDE和工具以及将其作为一组而不是单个组件进行交付)更大的难题)。更实际的是意识到诸如工具之类的工具cmake只能治疗症状而不能治愈根本原因。这使您更容易接受一个事实,即除了使用可能永远不会接近“理想”的工具外,别无选择。
布伦丹2015年

5
Makefile绝不“笨拙且混乱”。它们非常出色:make其核心是遍历非循环依赖图的引擎。关于“脚本”或命令行的所有内容都不是“古老的”。
Miles Rout 2015年

1
@MilesRout:笨拙而混乱的部分是图形构造。遍历足够优雅。但是,仅以一个最常见的凌乱部分为例:C头文件。每个#include都是边缘,但是make不能解析C文件。仍然不是问题,因为make可以将这些边与下一个节点(* .o文件)一起存储,但是它也不这样做。
MSalters 2015年

3
我不同意更好的设计是可能的。make不只是为了编译C!您需要一个接受.c.h归档并给出Makefiles的程序。但这不是make,那也不make应该做。同样,make这还不完全与C有关,内置于C的特定解决方案make不是一个好主意(偶然会违反UNIX哲学)。
Miles Rout 2015年

5

make (该工具或通过Makefile直接使用它)并不过时,特别是对于使用它的“小型个人项目”而言。

当然,您也可以将其用于大型项目,包括针对多个平台的项目。随着目标特定的变量,你可以轻松地定制你如何建立针对不同的平台。如今,Linux发行版附带交叉编译工具链(例如mingw-w64),因此您可以从Linux构建完整的Windows软件包(如果需要,可以使用安装程序),所有软件包均由 Makefile驱动。

诸如cmakeqmake之类的工具可能很有用,但并非没有问题。它们通常适合与任何库一起构建应用程序本身(尽管我经常在使用qmake进行库和使用它们的程序之间进行适当的依赖检查时遇到问题),但是在进行其余的操作时,我总是会遇到这些工具的约束工作(创建安装程序,生成/安装文档或翻译文件,执行不寻常的操作,例如将存档转换为共享库等)。所有这些都可以在中完成make,尽管诸如依赖跟踪之类的工作可能需要一些努力。

Qt Creator和Eclipse等IDE也可以导入基于Makefile的项目,因此您可以与使用IDE的开发人员共享。我认为Qt Creator IDE作为C ++ IDE而言非常出色,但是花了一些时间使Emacs变得更加有效,并且由于我进行了更多的Ada开发,所以我发现自己更喜欢Emacs。为了回想一下有关问题make,作为Makefile中的链接后步骤,我更新了TAGS文件(用于Emacs中的符号导航),并加载了M-x visit-tags-table

find $(SRC_DIR) $(TEST_DIR) -regex ".*\.[ch]\(pp\)?" -print | etags -

或用于Ada开发:

find $(SRC_DIR) $(TEST_DIR) -name "*.ad?" -print | etags -

2

此答案是@lxrec答案的补充。

Makefile可以用于许多用途,而不仅仅是从源代码创建程序/库。诸如CMake或自动工具之类的构建系统旨在获取代码,并以适合用户平台的方式构建代码(即查找库或指定正确的编译选项)。例如,您可以使用一个makefile来帮助自动执行某些发布任务,例如:构建一个包含代码的zip文件,该代码具有从git派生的版本;针对您的代码运行测试;将上述zip文件上传到某些托管服务。一些构建系统(例如automake)可能提供一种简便的方法来完成此任务,而其他构建系统则可能没有。

这并不是说您需要为此使用makefile,可以将脚本语言(shell,python等)用于此类任务。


1

我认为人工写的Makefile-s不会过时,尤其是在以下情况下:

  1. 使用POSIX make,这为您提供了便携式 Makefile
  2. 或使用GNU make 4,它为您提供了许多非常有趣的功能,特别是GUILE脚本功能,该功能可以有效地编码Makefile生成器提供的精美功能(我相信,可以通过Guile定制GNU make来轻松编写autotools或Cmake的功能)。当然,要付出的代价是要求GNU赚4(恕我直言,没什么大不了的)。

0

Makefile不会过时,就像文本文件不会过时一样。用纯文本存储所有数据并不总是正确的处理方式,但是如果您只需要一个Todo List,那么纯文本文件就可以了。对于更复杂的内容,您可能需要更复杂的格式(例如Markdown或XML)或自定义二进制格式或介于两者之间的任何内容,但在简单情况下,纯文本即可正常工作。

同样,如果您想要的是避免一直写出来的方法g++ -g src/*.c -o blah -W -Wall -Werror && ./blah,那么手写的Makefile就是完美的选择!

如果要构建高度可移植的文件,而不必自己管理可移植性,则可能需要诸如Autotools之类的文件来为您生成正确的Makefile。Autotools将检测各种平台支持的功能。用Autotools构建的用标准C89编写的程序几乎可以在任何地方编译。


“将在几乎所有地方编译”->“将在最新的类Unix系统上编译”。例如,我认为autotools在Windows系统上没有任何相关程度的工作(折扣Cygwin / MingW,这实际上是Windows之上的类Unix系统)。
sleske

它与最近无关。自动工具的优点是它可以在每个类似POSIX的远程系统上运行。Windows在某种程度上符合POSIX。
Miles Rout

是的,我纠正了。实际上,我记得对自动工具的一种批评恰恰是,即使对于非常老的系统,它也包含代码,因此请抓紧“最新的”知识。不过,我仍然支持Windows。
sleske

而这完全归咎于微软。如果他们关心生产高质量的产品,那么Windows将为国际操作系统标准(例如POSIX)提供适当的支持。POSIX不仅仅是“ Unix事物”,它还是所有操作系统可移植操作系统标准。Windows只是一堆不合规的垃圾。
Miles Rout 2015年

@MilesRout的底线仍然是“几乎无处不在”不包括90%的台式计算机
el.pescado

-2

如果您的项目很简单并且包含很少的文件,则不需要make文件。

但是,当项目复杂,使用大量内存区域,有许多文件时,则有必要将每个内存区域放在可寻址内存中的正确位置,非常希望每次进行小改动时都不要重新编译每个文件。制成一个文件,

如果您希望以最小的麻烦和按键错误的机会擦除旧文件/编译/链接/安装,makefile是一个真正的福音。

当您进入“现实世界”项目时,很少会只有1或2个文件,而是数百个文件。一个makefile将始终执行正确的操作,而不会执行不必​​要的操作(在调试之后),因此您只需键入一个简单命令,makefile便会完成所有工作


1
但这并没有回答为什么更喜欢makecmake反之亦然。
Ext3h 2015年

使用makefile并不会每次都重建所有文件。(否则,CMake或自动工具无法使用它)
ideaman42
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.