Mam binarny, że muszę budować wiele razy z różnymi flagami kompilatorowymi. Dlatego mam makefile, który stwierdza coś w rodzaju:

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

Definiuję również zasadę, aby zmienić flagi dla każdego obiektów_x:

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

I właśnie tam pojawia się problem: jeśli stwierdzę cele oddzielnie, jak:

$(OBJFOLDER)/%.a.o: %.cpp
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $@

$(OBJFOLDER)/%.b.o: %.cpp
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $@

$(OBJFOLDER)/%.c.o: %.cpp
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $@

Wszystkie prace. Jeśli jednak łączę wszystkie zasady do jednego, tylko pierwszy jest oceniany:

$(OBJFOLDER)/%.a.o $(OBJFOLDER)/%.b.o $(OBJFOLDER)/%.c.o: %.cpp
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $@

Na suchym biegu jest to, że tylko $ (objfolder) /%. Obiekty A.O są budowane, ale na zasadzie łączącej każdy binarny wymaga jego obiektów (i binarnych B i C nie gromadzą).

Jakieś pomysły? Dziękuję Ci!

2
chronos 16 luty 2017, 13:22

2 odpowiedzi

Najlepsza odpowiedź

Możesz to osiągnąć za pomocą Rozbudowa wtórna:

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

Należy zauważyć, że nie jest to bardzo idiomatyczny sposób robienia tego, bardziej zwykłe define / call / eval / eval Combo może być użyty do generowania reguł, jak w pierwszym rozwiązaniu:

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 $$@

endef

$(eval $(foreach variant,$(VARIANTS),$(call make_target,$(variant))))
5
A. Monti 16 luty 2017, 14:34

Innym sposobem jest stworzenie symboli danych do plików źródłowych i skompilowania tych z różnych flag. W ten sposób, ta sama ogólna reguła wzoru (OBJFOLDER)/%.o: %.cpp może zbudować wszystkie Twoje cele:

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 $< $@

%.b.cpp : %.cpp
    ln -s $< $@

%.c.cpp : %.cpp
    ln -s $< $@

$(OBJFOLDER)/%.o: %.cpp
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c -o $@ $< 
0
Maxim Egorushkin 16 luty 2017, 14:43