【问题标题】:Make runs cc and I don't understand why让运行cc,我不明白为什么
【发布时间】:2019-05-28 06:55:10
【问题描述】:

我有以下 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)

【问题讨论】:

  • 有内置的默认配方,比如使用cc编译.s
  • @Barmar,我该如何改变这种行为?
  • 你想让它做什么?
  • 您的第二个 makefile 将 nasm 用于 .asm 文件,而不是 .s 文件。
  • Make gcc the default compiler of make 不是相当重复的,但肯定是相关的。

标签: linux makefile


【解决方案1】:

一个简单的答案是make 的行为。但它并没有让人理解它是如何工作的,所以让我们更深入一点。

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

cc fizzbuzz.s -o fizzbuzz

它等于第一个 Makefile。

现在,我们将使用第二个 Makefile。 当我更改 .asm 上的 .s 扩展名时,它起作用了。有趣的行为,这是因为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 运行来禁用内置规则

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多