我该如何编写一个适用于单个C文件的最简单的MAKEFILE?

15
我有一个名为"main.c"的文件。请问最简单的Makefile,以便将此文件编译成可执行文件,我可以像./blah一样运行它?

在向我们提问之前,请努力完成你的作业。你的教授要求你使用Makefile是有原因的——这样你可以学习如何为更有用的项目编写Makefile。 - Chris Lutz
7
对不起,我并不是想惹怒作业警察。我已经尝试过在谷歌上搜索,但显然Makefile非常强大,可能会非常复杂。我承认我对其中很多内容都不太理解。这个主题不是一个编程主题,但评估需要使用C代码调用本地操作系统函数。我以前从未接触过C语言,并且这项任务将在几个小时内到期。我感到沮丧、绝望,需要一些帮助。如果我让你不高兴了,我很抱歉。 - Ash
5个回答

16
all:
     gcc -o blah main.c

你不需要Makefile,一个简单的Shell脚本就可以。


任务表要求我们必须包含一个Makefile。 - Ash
当我使用这个并运行make时,它返回"Makefile:2: *** missing separator. Stop." - Ash
1
@Ash:gcc前面的那一段必须是一个制表符,而不是空格。(如果你使用空格就会出现那个错误。) - T.J. Crowder
1
makefile规则的目标应该是blah而不是all,因为这是实际命令生成的文件名。否则,make无法正确计算依赖关系。 - CB Bailey

11

如果你正在使用GNU Make,并且不需要链接额外的库,那么最简单的makefile就是没有任何makefile。尝试:

make main

如果您不想指定main,那么可以使用以下单行Makefile:

all: main

GNU Make有几个隐式规则,如果您没有自己定义它们,它就会使用它们。使此工作的规则类似于:

%: %.c
        $(CC) $^ -o $@

更多信息请参见:http://www.gnu.org/software/make/manual/make.html#Using-Implicit


显然,这个任务要求输出为“blah”,而不是“main”,因此他需要一个Makefile。上面的信息仍然有用,但实际上并不适用于这里。 - T.J. Crowder
1
如果你的可执行文件应该被称为 blah,最简单的方法就是将你的源文件重命名为 blah.c(如果允许的话)。 - Jens Gustedt
@T.J.Crowder: blah 似乎不是一个要求,而是一个例子:OP说“我可以像运行./blah一样运行”。因此,这个单行的 Makefile 看起来很好。 - MestreLion

5
all: blah
blah: main.c
    gcc main.c -o blah

我在任何其他内容显示之前编写并发布了我的答案,并且我没有看到“作业”标签。我同意Chris Lutz的观点; 在这样可怜的任务上寻求帮助是毫无意义的,你将一事无成。 - Arnaud Meuret
1
all: blah 让这个过程变得比必要的复杂,并且如果存在一个名为 all 的文件,它也可能会破坏一些东西。除了这一点,这是最好的答案。 - CB Bailey
实际上,经过进一步的思考,在这种简单的情况下,名为“all”的文件可能不会破坏依赖关系检查;但它仍然是多余的,因为无论如何,make都会将第一个目标视为默认目标。 - CB Bailey
我完全同意Charles的看法,即我的提议并不是最简单的,但我选择了这种折衷方案,因为我认为它在简洁和易懂之间取得了良好的平衡。我认为Make已经有太多黑魔法了。 - Arnaud Meuret

2
我建议的最简单方法是:
myprog: myprog.o
        $(CC) -o $@ @^

通过隐式规则,这将导致在链接之前将myprog.c编译为myprog.o的单独步骤。我喜欢这种方式胜过其他答案(Arnaud提供的),因为它适用于更多的源文件,而不需要显著扩大makefile:
myprog: myprog.o foo.o bar.o helper.o my.o your.o his.o her.o
        $(CC) -o $@ @^

应该是 $^ 而不是 @^ 吗? - user2023370

1
正如Jander所说,如果你的源文件是一个名为blah.c的单个文件,你可以使用以下命令输出一个名为blah的可执行文件:
all: blah

甚至包括:


blah:

使用GNU make 时,其他一切都是隐含的。

虽然这非常简单,但它比一些更复杂的答案具有一些优点:

  • 编译器没有硬编码:让您的环境为您选择gcc
  • 您的程序名称仅设置一次,这是良好的DRY编程实践。
  • 不会创建不需要的中间*.o文件,适用于此简单项目。

话虽如此,我强烈建议您通过添加至少cleanall规则以及-Wall标志来改进您的Makefile。 这可以使用以下Makefile完成,同时保留上述所有优点:

TARGET=blah
CFLAGS=-Wall
.PHONY: all clean
all: $(TARGET) $(TARGET):
clean: rm -f $(TARGET)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接