0

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

例如,考虑以下 Makefile:

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 $@

当我运行 make 时,我可以看到以下命令被执行:

g++ -Wall -I. -c renderer/tracer.cpp -o bin/tracer.o
g++ -Wall -I. -c renderer/tracer.cpp -o bin/DiffuseLight.o
g++ -Wall -I. -c renderer/tracer.cpp -o bin/ScatterUtils.o
g++ -o bin/myRenderer bin/tracer.o bin/DiffuseLight.o bin/ScatterUtils.o

显然,这无法构建可执行文件,因为它只使用第一个先决条件,即renderer/tracer.cpp生成所有目标文件,因为我$<在目标的配方命令中使用自动变量$(OBJECT_FILES)

我想知道如何修复我的 Makefile 以便能够执行这些命令:

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

我似乎找不到正确的自动变量或获取正确源文件以构建给定目标文件的方法。

4

1 回答 1

1

正如马特所建议的,你有(至少)两个选择:

  1. 编译规则:

    # $(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))))
    

    注意$$用于转义第一个扩展(请参阅eval 函数以获得详细说明)。

  2. vpath指令:_

    vpath %.cpp $(dir $(SOURCE_FILES))
    
    $(BUILD_DIR)/%.o: %.cpp
        @mkdir -p "$(BUILD_DIR)"
        $(CXX) $(CFLAGS) -I. -c $< -o $@
    
于 2019-03-17T08:22:41.943 回答