Makefile. Шаблон задачи для проекта с вложенными каталогами
Пусть у меня будет примерно такая структура:
-
src
- main.cpp
-
dir
- two.cpp
-
build
- Makefile
Мой Makefile сейчас:
CC = g++
FLAGS = -MD
ROOT_DIR = ../src/
SUB_DIR = dir/
DIRS = $(ROOT_DIR) $(addprefix $(ROOT_DIR), $(SUB_DIR))
SRC = $(wildcard $(addsuffix *.cpp, $(DIRS)))
OBJ = $(patsubst $(ROOT_DIR)%.cpp, %.o, $(SRC))
build: $(OBJ)
$(CC) $(FLAGS) -o main $(OBJ)
%.o : $(ROOT_DIR)%.cpp
$(CC) $(FLAGS) -c $< -o $@
dir/%.o : $(ROOT_DIR)dir/%.cpp
$(CC) $(FLAGS) -c $< -o $@
clean:
rm -rf main *.o *.d $(SUB_DIR)
@-mkdir $(SUB_DIR)
Здесь переменная OBJ содержит:
main.o dir/two.o
Он работает, но проблема в том, что у меня для исходников из директорий /src и /src/dir/ разные задачи:
%.o : $(ROOT_DIR)%.cpp
$(CC) $(FLAGS) -c $< -o $@
dir/%.o : $(ROOT_DIR)dir/%.cpp
$(CC) $(FLAGS) -c $< -o $@
Я пытаюсь объединить их просто убрав второй вариант, но тогда он не хочет находить two.cpp. Вот это работает:
%.o : $(ROOT_DIR)dir/two.cpp
@echo $<
@echo $@
$(CC) $(FLAGS) -c $< -o $@
А это нет:
%.o : $(ROOT_DIR)%.cpp
$(CC) $(FLAGS) -c $< -o $@
Падает с ошибкой:
make: *** No rule to make target 'dir/two.o', needed by 'build'. Stop.
Не создавать же для каждого подкаталога отдельный шаблон задач?
Ответы (1 шт):
Автор решения: Neutrino Zh
→ Ссылка
Ещё немного почитав, понял как правильно использовать VPATH, что и сделал:
CC = g++
FLAGS = -MD -I src
ROOT_DIR = ../src/
SUB_DIR = dir/
DIRS = $(ROOT_DIR) $(addprefix $(ROOT_DIR), $(SUB_DIR))
SRC = $(wildcard $(addsuffix *.cpp, $(DIRS)))
OBJ = $(patsubst $(ROOT_DIR)%.cpp, %.o, $(SRC))
build: directory $(OBJ)
$(CC) $(FLAGS) -o main $(OBJ)
directory:
@mkdir -p $(SUB_DIR)
VPATH := ../src/
%.o : %.cpp
$(CC) $(FLAGS) -c $< -o $@
clean:
rm -rf main *.o *.d $(SUB_DIR)
Теперь всё работает как и должно!