2017-02-16 2 views
0

У меня есть двоичный файл, который мне нужно создать несколько раз с разными флагами компилятора. Поэтому, у меня есть Makefile, который гласит, что-то вроде:Makefile несколько целей из того же исходного файла, с разными флагами

OBJECTS_A := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.a.o)) 
OBJECTS_B := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.b.o)) 
OBJECTS_C := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.c.o)) 

Я также определить правила, чтобы изменить флаги для каждого OBJECTS_x:

$(OBJECTS_B): DEFINES+=-D_B 
$(OBJECTS_C): DEFINES+=-D_C 

И это где проблема происходит: Если я заявить Цели отдельно, как:

$(OBJFOLDER)/%.a.o: %.cpp 
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o [email protected] 

$(OBJFOLDER)/%.b.o: %.cpp 
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o [email protected] 

$(OBJFOLDER)/%.c.o: %.cpp 
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o [email protected] 

Все работы. Однако, если я объединить все правила в один, только первый оценивается:

$(OBJFOLDER)/%.a.o $(OBJFOLDER)/%.b.o $(OBJFOLDER)/%.c.o: %.cpp 
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o [email protected] 

Что я получаю на всухую, что только $ (OBJFOLDER) /% объектов ао строятся, но на правиле связывания. поэтому каждый бинарный объект требует своих объектов (и двоичные файлы b и c не могут быть построены, следовательно).

Любые идеи? Спасибо!

+0

Правило модели с несколькими целевых шаблонами означает, точно так, как вы испытали: он ожидает один вызова рецепта для создания _все_ целей , Он используется, когда программа создает несколько выходных файлов. См. Https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html (последний абзац) – MadScientist

ответ

3

Вы можете добиться этого с помощью secondary expansion:

.SECONDEXPANSION: 
$(OBJFOLDER)/%.o: $$(basename $$*).cpp 
     $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o [email protected] 

Обратите внимание, что это не очень идиоматический способа сделать это, более обычный define/call/eval комбо может быть использована для создания правил, как в вашем первом решение:

VARIANTS=a b c 

DEFINES_FOR_a= 
DEFINES_FOR_b=-D_B 
DEFINES_FOR_c=-D_C 

define make_target = 
$$(OBJFOLDER)/%.$(1).o: %.cpp 
     $$(COMPILER) $$(CFLAGS) $$(INCFOLDER) $$(DEFINES_FOR_$(1)) -c $$< -o [email protected] 

endef 

$(eval $(foreach variant,$(VARIANTS),$(call make_target,$(variant)))) 
+0

Почему назначение назначений для конкретных задач больше не работает? – MadScientist

+0

Мой плохой, он работает отлично, я отредактировал ответ –

0

Другой способ - создать символические ссылки на исходные файлы и скомпилировать их с разными флагами. Таким образом, тот же один общее шаблонное правило (OBJFOLDER)/%.o: %.cpp может построить все свои цели:

OBJECTS_A := $(SOURCES:%.cpp=$(OBJFOLDER)/%.a.o) 
OBJECTS_B := $(SOURCES:%.cpp=$(OBJFOLDER)/%.b.o) 
OBJECTS_B := $(SOURCES:%.cpp=$(OBJFOLDER)/%.c.o) 
$(OBJECTS_B): DEFINES+=-D_B 
$(OBJECTS_C): DEFINES+=-D_C 

%.a.cpp : %.cpp 
    ln -s $< [email protected] 

%.b.cpp : %.cpp 
    ln -s $< [email protected] 

%.c.cpp : %.cpp 
    ln -s $< [email protected] 

$(OBJFOLDER)/%.o: %.cpp 
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c -o [email protected] $< 
Смежные вопросы