#makefile #gnu-make
Вопрос:
SOURCE = aaa.c bbb.c ggg.c fff.c
OBJECT = $(SOURCE:.c=.o)
EXECUTION:
gcc -c aaa.c -o aaa.o
gcc -c bbb.c -o bbb.o
gcc -c ggg.c -o ggg.o
gcc -c fff.c -o fff.o
Возможно ли иметь одну строку в ярлыке ВЫПОЛНЕНИЯ, которая создает объектный файл для всего исходного файла, а не пишет компиляцию для каждого исходного файла
Ответ №1:
GNU make знает, как компилировать исходные файлы на языке Си. Так:
SOURCE := aaa.c bbb.c ggg.c fff.c
OBJECT := $(SOURCE:.c=.o)
.PHONY: all
all: $(OBJECT)
Уже делает то, что ты хочешь. Если вы хотите полностью управлять командой компиляции, вы можете использовать правило шаблона:
%.o: %.c
<the compilation command>
Это объясняет make, как создать foo.o
объектный файл из foo.c
исходного файла C, если это необходимо, передав <the compilation command>
его в оболочку. Это заменяет неявное правило, которое уже знает make.
Конечно, в команде вы должны обратиться к соответствующим файлам. Это делается с помощью автоматических переменных make: $@
для целевого объекта (объектный файл) и $<
для первого (и единственного) предварительного условия (исходный файл C). Перед передачей команды в оболочку make заменяет их соответствующими именами файлов.
Таким образом, в вашем случае вы могли бы использовать следующий файл Makefile:
SOURCE := aaa.c bbb.c ggg.c fff.c OBJECT := $(SOURCE:.c=.o) .PHONY: all all: $(OBJECT) %.o: %.c gcc -c
lt; -o $@
Обратите внимание, что make имеет множество других автоматических переменных, а также множество других переменных, представляющих интерес, особенно для компиляции C (CC
,CPPFLAGS
,CFLAGS
,LDFLAGS
,LDLIBS
…). Эти переменные используются неявными правилами, которые make уже знает. Неявное правило, используемое для компиляции C, например, таково:$(CC) $(CPPFLAGS) $(CFLAGS) -c
lt; -o $@
Таким образом, если вы хотите изменить значение по умолчанию для компиляции C, вы также можете играть с этими переменными, вместо того, чтобы добавлять свои собственные правила шаблонов.:SOURCE := aaa.c bbb.c ggg.c fff.c OBJECT := $(SOURCE:.c=.o) CC := gcc CFLAGS = -DSOME_MACRO .PHONY: all all: $(OBJECT)
Документация GNU make очень хорошо написана. Если вы хотите узнать больше о GNU make, это подходящее место для посещения.
Комментарии:
1. если я хочу передать какой-то макрос-DSOME_MACRO во время компиляции
2. Почти:
gcc -DSOME_MACRO -c $< -o $@
3. один вопрос, кто вызовет %.o кто-то должен вызвать его правильно ?
4. Огромное спасибо 🙂 , по ошибке я удалил свой комментарий
5. Да, именно поэтому я добавил
all
цель, которая зависит от всех объектных файлов. Если вы введетеmake all
, make создаст все необходимые объектные файлы (потому что они еще не существуют или старше исходного файла). И если вы наберетеmake foo.o
make, то будете строить толькоfoo.o
(при необходимости). И, какall
и первая явная (не шаблонная) цель в файле Makefile, если вы просто наберетеmake
, она будет такой же, какmake all
.