Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working with multiple source file extensions in a makefile

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.

like image 605
user487100 Avatar asked Jan 23 '12 08:01

user487100


1 Answers

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.

like image 70
MadScientist Avatar answered Sep 28 '22 08:09

MadScientist