Как я могу собрать варианты исполняемого файла с одним 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 построить правило.

Другие вопросы по тегам