Pregunta

Assume a file structure like the following:

a/a1.cpp
a/a2.cpp
b/b1.cpp
b/b2.cpp
Makefile

My goal is to build two object files a.o and b.o where a.o depends on a1.cpp and a2.cpp and b.o depends on b1.cpp and b2.cpp. However, it turns out I am unable to epxress this in a Makefile. Here is what I tried:

SOURCES := a/a1.cpp a/a2.cpp b/b1.cpp b/b2.cpp
TARGETS := a.o b.o
RELEVANT = $(filter $(1)/%.cpp,$(SOURCES))
$(TARGETS): %.o: $(call RELEVANT,%)
    @echo $^

I would have expected that when using the call function % is replaced by either a or b and RELEVANT returns the needed dependencies. However, $^ just returns an empty string indicating that obviously the filter function did not work as expected. Basically, this problems seems to be caused by functions being evaluated before pattern matching rules, as stated here: Makefile, Regex and multiple dependencies. Still, I am not able to transfer the solution given there to my case. Additionally, it looks kind of hackish and I am hoping for a clearer solution that does not require bash functionality.

Is anybody able to come up with a solution for this problem?

¿Fue útil?

Solución

There are a number of ways you can do this. If you really want to do it with a function in the prerequisites list then you can use secondary expansion:

.SECONDEXPANSION:

$(TARGETS): %.o: $$(call RELEVANT,%)
        @echo $^

I'm not quite sure how you're compiling multiple .cpp files into a single object file, though.

Otros consejos

Here's another one:

all : ${TARGETS}

define RULE
${1}.o: $(2)
        echo "$$(1) : $$@ :  $$^"
endef

$(foreach tgt, $(TARGETS), $(eval $(call RULE, $(basename $(tgt)), $(filter $(basename $(tgt))/%.cpp, $(SOURCES)) )))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top