我的目录包含2
源文件:a.c
和b.c
。我想从a
生成可执行文件a.c
,从b
生成b.c
。现在我只能想出一个编写Makefile的方法:
all:
gcc -o a a.c
gcc -o b b.c
看起来有点尴尬,这是更好的方法吗?
答案 0 :(得分:3)
答案很好,但我认为您需要了解make
如何运作:
make
的基本功能是从输入文件创建输出文件(如有必要)。 make
通过比较时间戳来决定必要的内容:如果任何输入文件比从其创建的输出文件更新,则执行此输出文件的配方。
这意味着仅使用名为all
的规则,此规则始终执行(除非您碰巧有一个最近的文件名为 {{1 - 为了防止出现这种情况,您必须将all
列为all
目标,而不是实际创建文件的目标。您的原始Makefile相当于一个简单的shell脚本,因此它没有正确使用.PHONY
。
最小"正确" Makefile的版本应如下所示:
make
所以,all: a b
a: a.c
gcc -o a a.c
b: b.c
gcc -o b b.c
.PHONY: all
是"假的"并取决于all
和a
。 b
仅在a
更改时重建,a.c
仅在b
更改时重建。
在一个真实的项目中,您的程序可能不只是来自一个源文件,在这种情况下,您可以真正利用b.c
:构建翻译单元的目标文件,因此只有实际重建的部件才会重建。对于你的小例子来说这太过分了,但是可以看起来像这样:
make
您只需向a_OBJS:= a.o
b_OBJS:= b.o
all: a b
a: $(a_OBJS)
gcc -o$@ $^
b: $(b_OBJS)
gcc -o$@ $^
%.o: %.c
gcc -c -o$@ $<
clean:
rm -f *.o
.PHONY: all clean
和a_OBJS
添加更多目标文件,即可在构建中添加新的翻译单元。 模式规则 b_OBJS
将与之匹配。还有更多要发现的内容,我建议从GNU make manual开始。
答案 1 :(得分:2)
我认为以下方法更好:
all: a b
a: a.c
gcc -o a a.c
b: b.c
gcc -o b b.c
在您的版本中,无论make all
和gcc
是否被修改,a.c
始终 运行b.c
两次。在此版本中,只有在必要时才会运行gcc
。
当然你可以使用一些魔术(for
- 循环或类似的)来创建规则,但我认为我和你的方法之间的区别很明显。
答案 2 :(得分:1)
给我
all:
gcc -o a a.c
gcc -o b b.c
看起来很好。 或者可能是以下更好的控制
all: a b
a: a.c
gcc -o a a.c
b: b.c
gcc -o b b.c
clean:
-rm a b
在没有makefile
make a #run cc -o a a.c by make or
make b #run cc -o b b.c by make
或生成a
和b
make a b
make
在这里使用隐式规则,就像魔法一样。 但更喜欢带有指定规则的makefile