Я пытаюсь написать Makefile с разделяемыми исходными и объектными файлами, и я не могу понять, как это сделать. У меня есть два метода, которые работают, но я надеюсь, что кто-то может указать "правильный" способ сделать это.
Мой проект разделяется на папку src
и obj
с Makefile на том же уровне, что и эти.
Первый метод использует подстановочную функцию для поиска исходных файлов в src
, затем использует замену текста для определения соответствующих объектных файлов.
SRC = $(wildcard src/*.cpp)
OBJ = $(SRC:.cpp=.o)
prog: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(patsubst src/,obj/,$(OBJ))
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)
Кажется, что это работает, но каждый раз, когда я запускаю make prog
, он перекомпилирует все объектные файлы. Переменная obj
должна иметь src/
перед всеми объектами, иначе я получаю "no rule to make target". С положительной стороны я могу легко использовать patsubst в целевом prog
для указания объектных файлов.
Второй метод аналогичен, но использует переменные vpaths и текста в переменной obj
:
vpath = %.cpp src
vpath = %.o obj
SRC = $(wildcard src/*.cpp)
OBJ = $(subst src/,,$(SRC:.cpp=.o))
POBJ = $(patsubst src/,obj/$(SRC:.cpp=.o))
prog: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(POBJ)
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)
Это устраняет повторную компиляцию объектных файлов, но требует добавить еще одну переменную POJB
для prog
target (так как я не могу делать какие-либо patsubst только для объектных файлов без оснований).
Оба метода работают, и каждый из них имеет свои преимущества перед другими, но какой из них является "правильным", и если ни один из них не является правильным способом для достижения такого типа здания?