Как я могу собрать варианты исполняемого файла с одним make-файлом?
У меня есть один набор исходных файлов, из которого мне нужно создать несколько вариантов исполняемого файла. Например, мне нужно сгенерировать app1.elf, app2.elf, app3.elf из того же main.c и comm.c. Разница между каждым из приложений заключается в адресе узла, параметре, который передается при вызове gcc. то есть:
gcc -DNODE=1 -oapp1.elf main.c
gcc -DNODE=2 -oapp2.elf main.c
gcc -DNODE=3 -oapp3.elf main.c
Давайте предположим, что у меня есть следующие файлы:
- SRC / main.c
- SRC / comm.c
Когда я запускаю Makefile так:
сделать все_узлы
make только собирает app1.elf со следующим выводом:
Встроенное приложение1
Встроенное приложение2
Встроенное приложение3
ПОТЕРПЕТЬ ПОРАЖЕНИЕ! Вывод, кажется, предполагает, что он работал, однако он генерирует только один исполняемый файл, а именно app1.elf. Кто-нибудь хочет указать, что я делаю не так?
Чтобы объяснить мой Makefile, я создал цель cleanobjs для очистки объектов в подкаталоге./obj. Это моя попытка сделать 'make' пересобрать файлы obj с новым адресом узла, но это не удалось. Я использую "make" таким образом, что он не предназначен для использования? Я знаю, что могу также создать командный файл для запуска make (что я сделал успешно), но я хотел бы знать, что я делаю неправильно. Мой Makefile ниже:
obj/%.o: src/%.c
gcc -DNODE=$(NODE) -o$@ $<
app.elf : ./obj/main.o ./obj/comm.o
gcc -oapp$(NODE).elf main.o comm.o
node1 : NODE=1
node1 : cleanobj app.elf
@echo 'Built app1'
node2 : NODE=2
node2 : cleanobj app.elf
@echo 'Built app2'
node3 : NODE=3
node3 : cleanobj app.elf
@echo 'Built app3'
all_nodes : node1 node2 node3
cleanobj :
rm -rf obj/main.o obj/comm.o
.PHONY : cleanobj
5 ответов
Вот что я бы сделал:
SRC = src/main.c
OBJ = $(patsubst src%,obj$(VERSION)%,$(patsubst %.c,%.o,$(SRC)))
C_FLAGS = -DNODE=$(VERSION)
all: app.1 app.2 app.3
#
# For each application just call make with VERSION set correctly
app.%: dir.%
$(MAKE) VERSION=$* app$*.elf
#
# Build each applications objects into a seprate directory
# So we need to make sure the obj directory exists.
dir.%:
@- if ! test -e obj$*; then mkdir obj$*; fi
app%.elf: $(OBJ)
$(CC) -o$@ $(C_FLAGS) $(OBJ)
obj$(VERSION)/%.o: src/%.c
$(CC) -c -o obj$(VERSION)/$*.o $(C_FLAGS) $<
Вам понадобится несколько целей для разных версий. Каждой цели также понадобятся свои собственные цели main.o и comm.o, а это означает, что вам нужно называть их как-то иначе, иначе они будут смешиваться друг с другом. Тогда ваше все должно функционировать, чтобы построить все три.
Аналогичный подход:
ifeq ($(NODE),)
all:
make NODE=1
make NODE=2
make NODE=3
cleanobj:
make NODE=1 cleanobj
make NODE=2 cleanobj
make NODE=3 cleanobj
else
OBJS = main.o comm.o
objs = $(patsubst %.o,obj/$(NODE)/%.o,$(OBJS))
app$(NODE).elf: $(objs)
gcc -o app$(NODE).elf $^
@echo 'Built app$(NODE)'
obj/$(NODE)/%.o: src/%.c
gcc -c -DNODE=$(NODE) -o $@ $<
cleanobj :
rm -rf $(objs)
endif
.PHONY: all cleanobj
Самый простой способ - создать отдельные каталоги для сборки и использовать VPATH
позволить вашему (в основном неизмененному) Makefile создать исходные исходные коды в отдельном каталоге.
Немного сложнее изменить ваш Makefile, чтобы переписать цель .o
и исполняемые файлы должны находиться в подкаталоге. Например:
NODE = 1
OBJDIR = obj.node$(NODE)
SRC = main.c comm.o
OBJ = $(SRC:%.c=$(OBJDIR)/%.o)
Затем ваши цели повторно вызывают ваш Makefile с помощью NODE
задавать.
Создайте командный файл или сценарий оболочки, который может создать все три сборки. Что-то вроде:
make node1
<if needed copy your executable to a different directory>
<clean all objs from make node1>
make node2
<if needed copy your executable to a different directory>
<clean all objs from make node1>
make node3
<if needed copy your executable to a different directory>
<clean all objs from make node1>
Вызовите этот командный файл или сценарий оболочки для all_node
построить правило.