使运行cc,我不明白为什么

时间:2019-01-01 01:49:05

标签: linux makefile

我有以下Makefile:

SRC = $(wildcard *.s)
BIN = $(SRC:.s=)

all: $(BIN)
    echo 4

当前目录中有一个汇编程序文件(fizzbuzz.s)。当我执行make命令时,它会运行

cc fizzbuzz.s -o fizzbuzz

我不明白为什么会这样?怎么了?

更新

当我使用另一个Makefile时,也会发生同样的情况:

.PHONY: clean all

AS = nasm
LNK = ld 
SRC = $(wildcard *.s)
BIN := $(SRC:.s=)

all: $(BIN)

%: %.o
    $(LNK) -melf_i386 $< -o $@
%.o: %.s
    $(AS) -f elf $< -o $@
clean:
    rm -f $(BIN)

1 个答案:

答案 0 :(得分:2)

一个简单的答案是make的行为。但这并不能理解其工作原理,因此让我们更深入。

我们从第一个Makefile开始。由于我的目录只有一个文件fizzbuzz.s,因此变量BIN将等于fizzbuzzMake搜索fizzbuzz目标,但没有目标。因此,make处理内置规则。它搜索带有扩展名添加到fizzbuzz目标的文件,如果已搜索文件,它将处理自己的规则。我试图删除Makefile并运行命令:make fizzbuzz,它运行另一个

cc fizzbuzz.s -o fizzbuzz

它等于第一个Makefile。

现在,我们将使用第二个Makefile。 当我在.s上更改了.asm扩展名时,它起作用了。有趣的行为是因为make没有内置.asm扩展规则。我想了解一下,所以我将.asm返回到.s。 我的第二个Makefile有一个没有扩展名的目标规则:

%: %.o
    $(LNK) -melf_i386 $< -o $@

但是它不能按预期工作,并且像没有Makefile一样工作。我想这是因为%具有内置规则之后的最后优先级执行。我们可以通过在Makefile中添加MAKEFLAGS += --no-builtin-rules来更改行为,一切正常。

但是我注意到没有选择的一件奇怪的事情。我执行了命令make fizzbuzz.o,它已经建立fizzbuzz.o(它处理我的Makefile中的命令)。那么好吧。让我们再次运行make。运行它,它为我建立了最终的fizzbuzz目标。惊喜!

所以规则

%: %.o
    $(LNK) -melf_i386 $< -o $@
当前目录中有目标文件(.o)时,

工作。我不知道它是什么,一个错误或一个功能(恕我直言,这是一个奇怪的功能),但它确实可以正常工作。

最后,我们有两种解决方案可以使第二个Makefile工作,它们是:

  • 通过将.s扩展名替换为.asmmake中没有内置规则的其他扩展名,来省略内置规则
  • 通过在Makefile中添加选项MAKEFLAGS += --no-builtin-rules或使用make -Rmake -r来运行内置规则