Reputation: 918
I have a c++ project with various extensions for the source files (.cpp, .c, .cc) and various extensions for the header files (.hpp, .h, .hh). The source files are located in a directory called SRC, and the header files are predictably in a directory called INC.
I would like to compile the source with a rule like
vpath %.c $(SRC)
%.o: %.c
$(COMPILER) $(FLAGS) $< $(INCFLAG)$(INC)
This of course works if I know the source file will be of the form %.c, but in the case of multiple possible file extensions, I would need to build a similar rule for %.cpp and %.cc as well. Of course three rules isn't a big deal to write, but it would be nice to be able to use this makefile as a drag and drop for any project, even in a different language, without having to re-write the rules.
So how can I write a rule (or some other construct that accomplishes the same goal) that works like:
SRC_EXT = cpp c cc
vpath %.$(SRC_EXT) $(SRC)
%.o: %.$(SRC_EXT)
$(COMPILER) $(FLAGS) $< $(INCFLAG)$(INC)
Thanks for your help.
Upvotes: 7
Views: 5457
Reputation: 100866
You can't in standard POSIX make. However since you mention vpath I'll assume you're using GNU make. If you have a sufficiently new version (3.81 or newer), you can do this easily enough with call and eval:
SRC_EXT = cpp c cc
define compile_rule
%.o : %.$1
$$(COMPILER) $$(FLAGS) $$< $$(INCFLAG)$$(INC)
endef
$(foreach EXT,$(SRC_EXT),$(eval $(call compile_rule,$(EXT))))
If you don't have sufficiently new GNU make, or would prefer an alternate solution, you can do the same thing with generated makefiles.
Upvotes: 4