Как получить предпосылки относительно цели в Makefile (GNU Make)? - PullRequest
0 голосов
/ 17 марта 2019

Есть ли способ получить предварительное условие, соответствующее цели в 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

Iне может найти нужную автоматическую переменную или способ получить правильный исходный файл для создания заданного объектного файла.

1 Ответ

1 голос
/ 17 марта 2019

Как предлагает Мэтт , у вас есть (как минимум) два варианта:

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