Предположим, у нас есть исходный файл $(SRC_DIR)/longpath/source/foo.cpp
, и мы хотим построить объектный файл $(OBJ_DIR)/foo.o
. Мы могли бы wi sh для этого правила:
$(OBJ_DIR)/foo.o: $(SRC_DIR)/longpath/source/foo.cpp
... $< -o $@
Но мы не знаем путь, когда пишем make-файл, поэтому мы должны попросить Make выяснить это во время сборки.
Есть несколько способов сделать это. Самый простой - использовать директиву vpath
.
Если мы заранее определим путь, мы могли бы написать это:
vpath %.cpp $(SRC_DIR)/longpath/source
$(OBJ_DIR)/foo.o: foo.cpp
... $< -o $@
Make будет использовать vpath
для поиска исходного файла и использования его полного пути в качестве предварительного условия (и, следовательно, $<
).
Директива vpath
может принимать несколько каталогов, и хотя мы не знаем путь заранее мы знаем, как их вычислить:
vpath %.cpp $(dir $(SRC_FILES))
$(OBJ_DIR)/foo.o: foo.cpp
... $< -o $@
И как только мы подтвердим, что это работает, мы можем переключиться на шаблонное правило:
$(OBJ_DIR)/%.o: %.cpp
... $< -o $@
и изменить OBJ_FILES
соответственно:
OBJ_FILES += $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(notdir $(SRC_FILES)))
all: $(OBJ_FILES)
... $^