此Makefile如何使C程序甚至不指定编译器?


41

我正在使用《高级Linux编程(2001)》[代码]一书中的Makefile 。看到GNU make确实正确编译了代码,甚至没有在Makefile中指定编译器,我感到很奇怪。这就像没有任何食谱的烘烤!

这是代码的最低版本:

测试

int main(){}

生成文件

all:            test

并使其真正起作用!这是它执行的命令:

cc     test.c   -o test

我找不到任何有用的文档。这怎么可能?


PS另加一点注意:甚至没有指定语言;因为test.c可用,所以GNU make使用cc。如果存在test.cpptest.cc(不存在test.c),则使用g++(而不是c++)。


4
“就像没有任何食谱的烘烤!” 食谱会告诉您要烧开水,而不是告诉您是否应该使用煤气炉上的锅,电磁炉上的锅,电热水壶或放在火上的三脚架上的大锅烧开水。它甚至都不会告诉您应该在哪里取水。这就像告诉make我们烧开水,并使用其内部规则,make只会弄清楚如何;)
Rhymoid

1
@Rymoid就像大喊大叫:我要蛋糕!然后一个叫做的机器人make检查您的冰箱,发现有面粉可用,然后从其内部食谱为您烤一个默认的蛋糕。:-)
Ho1

@ Ho1:机器人可能会问,先生,您想吃哪个蛋糕?:):D
Suchhi'1

Answers:


68

Make使用其内置规则进行此操作。这些特别告诉它如何编译C代码以及如何链接单对象程序。

您实际上甚至不需要Makefile:

make test

没有一个就可以工作。

要查看使所有这些成为可能的隐藏规则,请使用-p不带Makefile 的选项:

make -p -f /dev/null

正如alephzero指出的那样,Make内置了很长时间的规则(如果不是总是这样的话)。Stuart Feldman在Unix V7中的第一个版本在中定义了它们files.c他在1979年的论文中提到了它们。它们也是POSIX规范的一部分。(这并不意味着Make的所有实现都支持它们-旧的Borland Make for DOS不支持,至少在3.0版之前。)


2
我是这么认为的,但是POSIX也指定了它们
斯蒂芬·基特

5
@KingZoingo Make实际上是一种推理引擎:它具有一组规则(内置的和来自Makefile的规则),现有的工件(当前目录中的文件或Makefile中的名称)和请求的工件(目标文件中的目标)。 Makefile); 它只是尝试匹配规则和现有工件,以确定是否可以使用它们来获取请求的工件。内置规则告诉它test.c可以用于产生testmake -d将向您详细介绍该过程...
Stephen Kitt 2016年

4
@ Ho1 @StephenKitt在make发明GNU或POSIX之前很久了。第一个版本是将近40年前编写的,甚至在此之前,还有一些由Shell脚本构建的原型版本。
alephzero

3
@jamesqf CPP仍会调用预处理器(cc -E通常);C ++编译器是CXX
史蒂芬·基特

3
CXX在这种情况下,@ Ho1 是Make变量,而不是命令-Makefile 中的命令$(CXX)将替换为运行C ++编译器的命令。
史蒂芬·基特
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.