如何在Makefile(gnumake)中获取与目标相关的先决条件?

如何在Makefile(gnumake)中获取与目标相关的先决条件?,makefile,gnu-make,Makefile,Gnu Make,有没有办法获得与Makefile(gnumake)中的目标相对应的先决条件 例如,考虑下面的Mag文件: CXX = g++ CFLAGS = -Wall MODULE_NAME = myRenderer BUILD_DIR = bin SOURCE_FILES = renderer/tracer.cpp renderer/lights/DiffuseLight.cpp renderer/materials/ScatterUtils.cpp OBJECT_FILES = $(patsubst

有没有办法获得与Makefile(gnumake)中的目标相对应的先决条件

例如,考虑下面的Mag文件:

CXX = g++
CFLAGS = -Wall
MODULE_NAME = myRenderer
BUILD_DIR = bin

SOURCE_FILES = renderer/tracer.cpp renderer/lights/DiffuseLight.cpp renderer/materials/ScatterUtils.cpp
OBJECT_FILES = $(patsubst %,$(BUILD_DIR)/%, $(notdir $(SOURCE_FILES:.cpp=.o)))

$(BUILD_DIR)/$(MODULE_NAME): $(OBJECT_FILES)
    $(CXX) -o $@ $^

$(OBJECT_FILES): $(SOURCE_FILES)
    @mkdir -p "$(BUILD_DIR)"
    $(CXX) $(CFLAGS) -I. -c $< -o $@
显然,这无法构建可执行文件,因为它仅使用第一个先决条件,即
renderer/tracer.cpp
生成所有对象文件,因为我使用的是
$,正如您所建议的(至少)两个选项:

  • 汇编规则:

    # $(1): source file
    define MY_RULE
    $$(patsubst %.cpp,$$(BUILD_DIR)/%.o,$$(notdir $(1))): $(1)
        @mkdir -p "$$(BUILD_DIR)"
        $$(CXX) $$(CFLAGS) -I. -c $$< -o $$@
    endef
    $(foreach f,$(SOURCE_FILES),$(eval $(call MY_RULE,$(f))))
    

  • 对每个源目录分别使用
    vpath
    或编写编译规则(可能是隐式规则)(即
    $(BUILD\u DIR)%.o:$1%.cpp;$(CXX).
    )。也可以将
    mkdir
    移动到单独的顺序中,仅适用于先决条件/规则。当然可以!意识到每次生成对象文件时都会运行该命令。谢谢这真的很有用!然而,我想知道这两种方法在构建时间上是否存在差异。我还将阅读有关vpath指令的更多信息。非常感谢你的帮助@Ganesh
    我想知道这两种方法的构建时间是否有差异
    如果只有一种
    $(build\u DIR)
    ,那么应该没有差异。否则,第一个可能会更好。
    g++ -Wall -I. -c renderer/tracer.cpp -o bin/tracer.o
    g++ -Wall -I. -c renderer/lights/DiffuseLight.cpp -o bin/DiffuseLight.o
    g++ -Wall -I. -c renderer/materials/ScatterUtils.cpp -o bin/ScatterUtils.o
    g++ -o bin/myRenderer bin/tracer.o bin/DiffuseLight.o bin/ScatterUtils.o
    
    # $(1): source file
    define MY_RULE
    $$(patsubst %.cpp,$$(BUILD_DIR)/%.o,$$(notdir $(1))): $(1)
        @mkdir -p "$$(BUILD_DIR)"
        $$(CXX) $$(CFLAGS) -I. -c $$< -o $$@
    endef
    $(foreach f,$(SOURCE_FILES),$(eval $(call MY_RULE,$(f))))
    
    vpath %.cpp $(dir $(SOURCE_FILES))
    
    $(BUILD_DIR)/%.o: %.cpp
        @mkdir -p "$(BUILD_DIR)"
        $(CXX) $(CFLAGS) -I. -c $< -o $@