Использование целевой переменной в make-файле - PullRequest
2 голосов
/ 15 ноября 2011

У меня есть следующий make-файл:

OUTPUTDIR = build

all: v12target v13target
v12target: INTDIR = v12
v12target: DoV12.avrcommontargets
v13target: INTDIR = v13
v13target: DoV13.avrcommontargets

%.avrcommontargets: $(OUTPUTDIR)/%.elf
    @true

$(OUTPUTDIR)/%.elf: $(OUTPUTDIR)/$(INTDIR)/main.o
    @echo TODO build ELF file from object file: destination $@, source $^
    @echo Compiled elf file for $(INTDIR) > $@

$(OUTPUTDIR)/$(INTDIR)/%.o: %.c
    @echo TODO call GCC to compile C file: destination $@, source $<
    @echo Compiled object file for $<, revision $(INTDIR) > $@

$(shell rm -rf $(OUTPUTDIR))
$(shell mkdir -p $(OUTPUTDIR)/v12 2> /dev/null) $(shell mkdir -p $(OUTPUTDIR)/v13 2> /dev/null)

.SECONDARY:

Идея состоит в том, что есть несколько различных конфигураций кода, которые должны быть скомпилированы из одного и того же исходного кода. Цель "all" зависит от цели v12target и v13, которые устанавливают количество переменных для этой конкретной сборки. Это также зависит от шаблона avrcommontargets, который определяет, как на самом деле выполнять компиляцию. Затем avrcommontargets зависит от ELF-файла, который, в свою очередь, зависит от объектных файлов, созданных из исходного кода C.

Каждый скомпилированный файл C приводит к объектному файлу (* .o). Поскольку каждая конфигурация (v12, v13 и т. Д.) Приводит к разным выходным данным, файл C должен быть собран несколько раз, а выходные данные помещены в разные подкаталоги. Например, «build / v12 / main.o», «build / v13 / main.o» и т. Д.

Пример вывода:

TODO call GCC to compile C file: destination build//main.o, source main.c
TODO build ELF file from object file: destination build/DoV12.elf, source build//main.o
TODO build ELF file from object file: destination build/DoV13.elf, source build//main.o

Проблема в том, что объектный файл не попадает в правильный подкаталог. Например, «build // main.o» вместо «build / v12 / main.o». Это затем препятствует корректному перестроению main.o для генерации версии main.o v13.

Я предполагаю, что проблема в том, что $ (INTDIR) является целевой переменной, и, возможно, ее нельзя использовать в целях шаблона, которые я определил для% .elf и% .o.

Правильный вывод будет:

TODO call GCC to compile C file: destination build/v12/main.o, source main.c
TODO build ELF file from object file: destination build/DoV12.elf, source build/v12/main.o
TODO call GCC to compile C file: destination build/v13/main.o, source main.c
TODO build ELF file from object file: destination build/DoV13.elf, source build/v13/main.o

Что мне нужно сделать, чтобы настроить этот make-файл так, чтобы он генерировал правильный вывод?

1 Ответ

1 голос
/ 15 ноября 2011

Вы перенаправили строки «Скомпилированный файл эльфа» из вашего вывода, которые выглядят так:

Compiled elf file for v13

Хотя подстановка переменных, специфичная для цели, в целом работает, кажется, что это происходит после выбора целей, что достаточно справедливо, поскольку в противном случае было бы довольно сложно реализовать.

Вы можете использовать $(foreach) и $(eval), чтобы создать одно правило для каждой цели. Тем не менее, я хотел бы еще раз отметить, что вы реорганизуете сборки дерева. Лучшая альтернатива - продолжать использовать автоинструменты. Во-вторых, лучше всего сделать свою логику сборки вне дерева и использовать одно дерево сборки для каждой цели с небольшим скриптом configure sh, вставляющим флаги компиляции в Makefile.

Разработка второго решения:

Пусть обычный make запускается в подкаталогах, по одному на цель. Имейте переключатель в вашем главном make-файле, который управляет выполнением суб-make. Ваш основной Makefile выглядит так:

TARGETS = v12 v13

CFLAGS_v12 = -foo
CFLAGS_v13 = -bar

ifeq ($(TARGET),)
all :
    mkdir --parents $(TARGETS)
    $(foreach t,$(TARGETS),SRCDIR=.. CFLAGS="$(CFLAGS_$t)" TARGET=$t $(MAKE) -C $t -f ../Makefile &&) true
clean :
    rm -rf $(TARGETS)
else
all : main.elf
endif

%.elf : %.o
    echo "Linking $@ from $< with $(CFLAGS)"

%.o : $(SRCDIR)/%.c
    echo "Compiling $@ from $< with $(CFLAGS)"

.PHONY : all
...