1
votes

Any idea why something like this wouldnt work in makefile ?

all : $(GOAL_DB) $(GOAL)

%.d: %.cpp      
    $(CC) $(CPPFLAGS_DB) $<  > $@
%.o : %.cpp
    $(CC) $(FLAGS_DB) $< -o $@

$(GOAL_DB) : $(OFILES)
        $(CC) $(LFLAGS_DB) -o $@ $^ $(LIBS_DB)
    strip $(GOAL_DB)
    rm -f *.o *.d

%.d: %.cpp     
    $(CC) $(CPPFLAGS) $<  > $@
%.o : %.cpp
    $(CC) $(FLAGS) $< -o $@
$(GOAL) : $(OFILES)
        $(CC) $(LFLAGS) -o $@ $^ $(LIBS)
    strip $(GOAL)
    rm -f *.o *.d

I'm just trying to build two different targets using make all , GNU make.

The first target builds fine , but it not creating new objects files for another target.

1

1 Answers

3
votes

A makefile is not like a standard program that is executed sequentially. It seems you've made the assumption that new rules appearing before a new target will apply to that target. This is not the case. The makefile is fully evaluated for variables, targets, dependencies, and more, before it starts applying rules.

Make is going to match those $(OFILES) against only one of those %.d: targets, probably the first target pattern it finds.

The reason you are not getting new objects for the other target is that to make it looks like you are building the same set of files twice, thus skipping the second build because it's already complete.

A solution is to use 'target specific variables':

all : $(GOAL_DB) $(GOAL)

$(GOAL): BUILD_FLAGS=$(FLAGS)
$(GOAL): BUILD_CPPFLAGS=$(CPPFLAGS)
$(GOAL): BUILD_OUTDIR=./outdir
$(GOAL): $(OFILES)

$(GOAL_DB): BUILD_FLAGS=$(FLAGS_DB)
$(GOAL_DB): BUILD_CPPFLAGS=$(CPPFLAGS_DB)
$(GOAL_DB): BUILD_OUTDIR=./outdir_db
$(GOAL_DB): $(OFILES)

%.d: %.cpp      
    mkdir -p $(BUILD_OUTDIR)
    $(CC) $(BUILD_CPPFLAGS) $<  > $(BUILD_OUTDIR)/$@

%.o : %.cpp
    mkdir -p $(BUILD_OUTDIR)
    $(CC) $(BUILD_FLAGS) $< -o $(BUILD_OUTDIR)/$@