Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make: pattern rule matching multiple extensions

I have duplicated pattern rules for several extensions (eg: cpp and cc):

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
    @$(CXX) $(CPPFLAGS) -I. -o $@ -c $?

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc
    @$(CXX) $(CPPFLAGS) -I. -o $@ -c $?

Is there a way to have one pattern rule which matches on both extensions, rather than having to have two rules?

like image 351
Steve Lorimer Avatar asked Jan 14 '15 21:01

Steve Lorimer


2 Answers

No, you can't combine the two rules. Prerequisites all have to match.

But you can avoid needing to have the recipe specified twice.

Either by using a define for the recipe:

define COMPILE
@$(CXX) $(CPPFLAGS) -I. -o $@ -c $?
endef

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
        $(COMPILE)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc
        $(COMPILE)

Or by using a loop and eval to define the recipes (untested I may have gotten some of the escaping wrong but I prefer the define approach anyway):

$(foreach prereq,cc cpp,$(eval $(OBJ_DIR)/%.o: $(SRC_DIR)/%.$(prereq) ; @$(CXX) $(CPPFLAGS) -I. -o $@ -c $?))
like image 163
Etan Reisner Avatar answered Sep 30 '22 18:09

Etan Reisner


You can use .SECONDEXPANSION for this. Here's an executable example:

OBJ_DIR:=obj
SRC_DIR:=src

TARGETS:=obj/foo.o obj/bar.o

all: $(TARGETS)

.SECONDEXPANSION:
$(OBJ_DIR)/%.o: $$(wildcard $(SRC_DIR)/%.cpp) $$(wildcard $(SRC_DIR)/%.cc)
    @$(CXX) $(CPPFLAGS) -I. -o $@ -c $<

Create src/foo.cc and src/bar.cpp, and issue make -n, and you'll get:

g++  -I. -o obj/foo.o -c src/foo.cc
g++  -I. -o obj/bar.o -c src/bar.cpp

If you have both foo.cc and foo.cpp this will behave just like the version in the question asked here (foo.cpp will have precedence over foo.cc, which will be ignored).

The $ signs are doubled for $$(wildcard... to prevent evaluation during the first expansion. You could have $$(SRC_DIR) just as well as $(SRC_DIR) since it does not matter (in the code above) when this variable is expanded.

like image 45
Louis Avatar answered Sep 30 '22 18:09

Louis