Используя make, как мне защитить от этого поведения файлы .c в сборочном проекте? - PullRequest
0 голосов
/ 30 сентября 2018

Я делаю очень простую программу сборки NASM x86_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 $60, %%rax\n\t"
    "mov $66, %%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 не повлияет на поток сборки сборки.

1 Ответ

0 голосов
/ 30 сентября 2018

Это взято из Встроенных правил Make .Make знает, как создавать исполняемые файлы из файлов C, поэтому, когда вы просите его собрать mytest (что и делает make, поскольку у вас есть цель all, требующая mytest), она создает дерево зависимостей и примечания.что:

  • он может построить mytest из mytest.c, следуя своему встроенному правилу;
  • он может построить mytest из mytest.o, следуя правилу, которое вы
  • он может построить mytest.o из mytest.c, следуя своему встроенному правилу;
  • он может построить mytest.o из mytest.asm, следуя правилу, которое вы 'мы указали.

Первое правило выигрывает (я не уверен, что это за приоритет), и вот что оно делает.

Вы можете отключить это с помощью опции -r:

make -r mytest

всегда будет использовать ваши правила для сборки программы.

Вы также можете отменить встроенные правила либо

  • индивидуально, переопределив их:

    % : %.c
    

    в конце вашего Makefile отключит это встроенное правило и приведет к поведению, которое вы испытываетеr;

  • глобально, указав MAKEFLAGS += -r в вашем Makefile.

...