Сделайте файл oneline для компиляции нескольких исходных файлов

#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 .