You can use .SECONDEXPANSION for this. Here is an 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 will get:
g++ -I. -o obj/foo.o -c src/foo.cc g++ -I. -o obj/bar.o -c src/bar.cpp
If you have foo.cc and foo.cpp , this will behave exactly like the version in the question foo.cpp here ( foo.cpp will take precedence over foo.cc , which will be ignored).
The $ signs are doubled for $$(wildcard... to prevent evaluation during the first extension. You can have $$(SRC_DIR) just like $(SRC_DIR) , since that doesn't matter (in the code above), when this variable expands.
Louis source share