Переменные в предпосылках make-файла

Можно ли в предварительных условиях использовать переменные make-файла? Мой пример ниже немного отсталый, но он должен продемонстрировать, чего я пытаюсь достичь:

objects_subsystem1 := $(patsubst %.c,%.o,$(wildcard ../src/ss1/*.c))
objects_subsystem2 := $(patsubst %.c,%.o,$(wildcard ../src/ss2/*.c))

all : subsystem1.elf subsystem2.elf

%.elf : $(objects_%)
    $(LD) $< -o $@

РЕДАКТИРОВАТЬ: я использую GNU Make 3.80, поэтому, к сожалению, ВТОРОЕ РАСШИРЕНИЕ недоступно!


person Chris    schedule 28.04.2013    source источник


Ответы (1)


Да, если вы используете GNUMake:

.SECONDEXPANSION:
%.elf : $$(objects_%)
    $(LD) $< -o $@

ИЗМЕНИТЬ:

Как указывает @bobbogo, есть решение, для которого не требуется .SECONDEXPANSION. Сначала изложим правила:

objects_subsystem1 := $(patsubst %.c,%.o,$(wildcard ../src/ss1/*.c))
objects_subsystem2 := $(patsubst %.c,%.o,$(wildcard ../src/ss2/*.c))
objects_subsystem3 := $(patsubst %.c,%.o,$(wildcard ../src/ss3/*.c))

all : subsystem1.elf subsystem2.elf subsystem3.elf

subsystem1.elf : $(objects_subsystem1)
    $(LD) $< -o $@
subsystem2.elf : $(objects_subsystem2)
    $(LD) $< -o $@
subsystem3.elf : $(objects_subsystem3)
    $(LD) $< -o $@

Потом немного переставляем:

objects_subsystem1 := $(patsubst %.c,%.o,$(wildcard ../src/ss1/*.c))
all : subsystem1.elf
subsystem1.elf : $(objects_subsystem1)
objects_subsystem2 := $(patsubst %.c,%.o,$(wildcard ../src/ss2/*.c))
all : subsystem2.elf
subsystem2.elf : $(objects_subsystem2)
objects_subsystem3 := $(patsubst %.c,%.o,$(wildcard ../src/ss3/*.c))
all : subsystem3.elf
subsystem3.elf : $(objects_subsystem3)

%.elf :
    $(LD) $< -o $@

Затем мы используем функцию eval:

define RULE_TEMPLATE
objects_subsystem$(1) := $(patsubst %.c,%.o,$(wildcard ../src/ss$(1)/*.c))
all : subsystem$(1).elf
subsystem$(1).elf : $$(objects_subsystem$(1))
endef

$(eval $(call RULE_TEMPLATE,1))
$(eval $(call RULE_TEMPLATE,2))
$(eval $(call RULE_TEMPLATE,3))

%.elf :
    $(LD) $< -o $@

Затем завершите цикл (если он того стоит):

define RULE_TEMPLATE
objects_subsystem$(1) := $(patsubst %.c,%.o,$(wildcard ../src/ss$(1)/*.c))
all : subsystem$(1).elf
subsystem$(1).elf : $$(objects_subsystem$(1))
endef

SUBSYSTEMS := 1 2 3 # this can be made automatic...

$(foreach sys,$(SUBSYSTEMS),$(eval $(call RULE_TEMPLATE,$(sys))))

%.elf :
    $(LD) $< -o $@
person Beta    schedule 29.04.2013
comment
Просто указатель, который я искал. Спасибо за ответ. - person Chris; 29.04.2013
comment
Хотя это хороший ответ, он не работает в моей старой версии GNU Make 3.80. Доступно, по-видимому, начиная с 3.81: cmcrossroads.com/article/whats- new-gnu-make-381 К сожалению, моя программа make является частью цепочки инструментов поставщика, и я не могу ее обновить :( - person Chris; 29.04.2013
comment
Тогда будет достаточно простого subsystem1.elf: ${objects_subsystem1} в отдельной строке. Если вам нужна их куча, сделайте петлю с $(eval...). - person bobbogo; 29.04.2013
comment
Не могли бы вы уточнить бобого. Будет ли нужна команда LD для каждого «одного лайнера»? Да, у меня их постоянно растет, поэтому я хочу максимально автоматизировать их. - person Chris; 29.04.2013
comment
Это фантастическая бета. Спасибо за такой подробный ответ :) - person Chris; 29.04.2013