Build Makefiles-编译到不同的目标文件夹

Build Makefiles-编译到不同的目标文件夹,build,makefile,Build,Makefile,我在make文件中指定了一个库文件夹列表: LIBRARIES = Ethernet \ SPI \ SD 我还有许多规则可以将每个规则编译到项目的本地obj文件夹中: obj/SPI/%.cpp.o: $(LIBS_DIR)/SPI/%.cpp @echo "Compiling $<" obj/SD/%.cpp.o: $(LIBS_DIR)/SD/%.cpp

我在make文件中指定了一个库文件夹列表:

LIBRARIES = Ethernet                \
            SPI                     \
            SD
我还有许多规则可以将每个规则编译到项目的本地obj文件夹中:

obj/SPI/%.cpp.o: $(LIBS_DIR)/SPI/%.cpp
    @echo "Compiling $<"

obj/SD/%.cpp.o: $(LIBS_DIR)/SD/%.cpp
    @echo "Compiling $<"    

obj/Ethernet/%.cpp.o: $(LIBS_DIR)/Ethernet/%.cpp
    @echo "Compiling $<"    

请注意,每个文件夹都使用自己的子文件夹。如何从$LIBRARIES自动生成这些规则,以便不必像这样复制它们?

足够多的新版本GNU make支持eval函数。您可以这样使用它:

define SUBDIR_RULE
obj/$1/%.cpp.o: $(LIBS_DIR)/$1/%.cpp
        @echo "Compiling $$<"
enddef

$(foreach D,$(LIBRARIES),$(eval $(call SUBDIR_RULE,$D)))
如果你不想依赖它,你可以使用自动生成的makefile,这是gnumake的一个特性,已经有很长时间了。但是这种方法使用起来有点麻烦。

您可以只执行以下操作:

obj/%.cpp.o : $(LIBS_DIR)/%.cpp
    g++ -c -o $@ ${CPPFLAGS} ${CXXFLAGS} $<

谢谢Maxim,我最后使用的是二次扩展。
.SECONDEXPANSION:

obj/%.cpp.o : $(LIBS_DIR)/%.cpp | $${@D} # object file depends on its directory
    g++ -c -o $@ ${CPPFLAGS} ${CXXFLAGS} $<

obj/% : # directory creation rule
    mkdir -p $@