Working with multiple source file extensions in a

2019-02-17 03:00发布

问题:

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.

回答1:

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.