Сделай пробежки сс и я не понимаю почему - PullRequest
0 голосов
/ 01 января 2019

У меня есть следующий 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 голосов
/ 01 января 2019

Простой ответ - поведение make.Но это не дает понимания, как это работает, поэтому давайте углубимся.

Мы начнем с первого Makefile.Поскольку в моем каталоге есть только один файл fizzbuzz.s, переменная BIN будет равна fizzbuzz.Make ищет цель 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.Это происходит, я полагаю, потому что % имеет последний приоритет выполнения после встроенных правил.Мы можем изменить поведение, добавив MAKEFLAGS += --no-builtin-rules в Makefile, и все работает отлично.

Но я заметил одну странную вещь без опции.Я выполнил команду make fizzbuzz.o, и она была построена fizzbuzz.o (она обрабатывает команду из моего Makefile).Итак, ок.Давайте снова запустим make.Я запускаю его, и он построил мне окончательную цель fizzbuzz.Сюрприз!

Так что правило

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

работает, когда в текущем каталоге есть объектные файлы (.o).Я не знаю, что это, ошибка или функция (ИМХО странная функция), но она работает так.

Наконец, у нас есть два решения, чтобы заставить работать второй Makefile, и они следующие:

  • опустите встроенные правила, заменив расширение .s на .asm или любое другое, которое не имеет встроенных правил, в make
  • отключите встроенные правиладобавив в Makefile параметр MAKEFLAGS += --no-builtin-rules или запустите с make -R или make -r
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...