使用 make,如何在程序集项目中使用 .c 文件防止这种行为?

Using make, how do I protect against this behavior with .c files in an assembly project?

我正在做一个超级简单的NASMx86_64汇编程序mytest.asm

BITS 64
GLOBAL _start

SECTION .text
    _start:
        mov  rax, 60   ; 'exit' system call
        mov  rdi, 42   ; exit with error code 42
        syscall

这个程序所做的就是以状态 42 退出。我为它制作了一个非常简单的 Makefile,

AS=nasm
ASFLAGS=-f elf64

.PHONY: all

all: mytest

%.o : %.asm
    $(AS) $(ASFLAGS) -o "$@" "$<"

% : %.o
    $(LD) $(LDFLAGS) -o "$@" "$<"

执行时,效果很好,

nasm -f elf64 -o "mytest.o" "mytest.asm"
ld -m elf_x86_64 -o "mytest" "mytest.o"
rm mytest.o

除非有与.c同名的文件,例如这里mytest.c

// exits with status 66
int main () {
  __asm__ (
    "mov , %%rax\n\t"
    "mov , %%rdi\n\t"
    "syscall\n\t"
    ::: "%rax", "%rdi"
  );
}

如果我 运行 make 使用以下文件,C 代码实际上会编译为 mytest

尴尬的是,$(LDARGS) 被发送到 $(CC) 而不是 $(LD)。这对我来说似乎不安全,任何具有这种非常典型的 Makefile 的人都可以通过插入具有相同名称的 .c 文件来从代号生成可执行文件?

GNU Make 是否记录了此行为?

GNU Make 4.1
Built for x86_64-pc-linux-gnu

理想情况下,.c 文件的存在不会影响程序集构建流。

这来自Make’s built-in rules。 Make 知道如何从 C 文件构建可执行文件,所以当你要求它构建 mytest(这是 make 所做的,因为你有一个需要 mytestall 目标),它建立了它的依赖树并注意到:

  • 它可以根据其内置规则从 mytest.c 构建 mytest
  • 它可以根据您指定的规则从 mytest.o 构建 mytest
  • 它可以根据其内置规则从 mytest.c 构建 mytest.o
  • 它可以根据您指定的规则从 mytest.asm 构建 mytest.o

第一个规则获胜(我不确定优先级是多少),这就是它的作用。

您可以使用 -r 选项禁用此功能:

make -r mytest

将始终使用您的规则来构建程序。

您也可以cancel built-in rules

  • 单独重新定义它们:

    % : %.c
    

    在您的 Makefile 末尾将禁用该内置规则并导致您所追求的行为;

  • 全局通过在你的 Makefile 中指定 MAKEFLAGS += -r