GNU make сгенерирует ассемблер в первую очередь, затем скомпилирует их в .o и ссылку - PullRequest
0 голосов
/ 05 декабря 2018
SOURCE=a.c b.c c.c 
ASM=$(patsubst %.c,%.s, $(SOURCE))

all:%.o
    gcc -o test $^

$(ASM):%.c
    gcc -S -o $@ $<

%.o:%.s
   gcc -c -o$@ $<

Сначала я хочу сгенерировать код сборки (.s), затем скомпилировать код сборки в объект (.o), а затем связать их.Но, похоже, код makefile выше не работает.Какой правильный код?

1 Ответ

0 голосов
/ 05 декабря 2018

Задавая вопросы, не работает никогда не бывает очень полезным ... если бы это сработало, вы, вероятно, не задавали бы вопрос!:-) Вместо этого вы всегда должны показывать команду, которую вы выполнили, и результат, который вы получили (или, по крайней мере, ошибочную часть вывода, если она длинная).Пожалуйста, вырезайте и вставляйте фактический текст, а не перефразируя сообщения.Кроме того, часто полезно указывать версию используемой вами программы make (make --version) и платформу, на которой вы работаете.

К счастью, на этот раз мы можем выяснить проблему без этой информации:

Это:

$(ASM):%.c
        gcc -S -o $@ $<

, где ASM равно a.s b.s c.s, не является правилом шаблона, поскольку цели не содержат символ шаблона %.Это означает, что предварительное условие %.c рассматривается не как шаблон, а как фактическое имя файла, буквально %.c, которого явно не существует.

Аналогично, это:

all: %.o

имеет ту же проблему: all является целью, поэтому это зависит от литерального файла с именем %.o, который не существует и не может быть создан.

Также, как общее правило, каждый рецепткоторый создает цель, должен создать реальную цель, о которой вы сказали, что это будет сделано, так что это all правило неверно, потому что имя цели all, но рецепт создает цель test.

Наконец, этоочень плохая идея назвать вашу программу test, потому что test - это обычная UNIX-программа и встроенная оболочка, поэтому, если вы запустите test, это не будет работать правильно (если вы запустите ./test itбудет работать).

Вы хотите, чтобы all зависело от программы, которую вы хотите построить, скажем mytest, а mytest должно зависеть от фактических .o файлов:

all: mytest

mytest: $(SOURCE:.c=.o)
     gcc -o $@ $^

Далее необходимо определить шаблонное правило, которое знает, как создать сборку.bly файл из исходного файла:

%.s : %.c
        gcc -S -o $@ $<

Это, наряду с другими вашими шаблонными правилами, это все, что вам нужно: make все это изменит.

Наконец, make имеетвстроенное правило, которое говорит ему, как создавать объектные файлы непосредственно из исходных файлов.Лучше всего избавиться от этого, чтобы заставить make использовать ваши правила;добавьте это в ваш make-файл, чтобы удалить его:

%.o : %.c
...