Правильный метод для подстановочных знаков в GNU Make

Я пытаюсь написать 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 
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)  
lt; -o $(COMPILE)/$(@F)

Это, кажется, работает, однако, каждый раз, когда я бегуmake prog он перекомпилирует все объектные файлы.OBJ переменная должна иметьsrc/ перед всеми объектами, иначе я получунет правила, чтобы сделать цель ", С положительной стороны, я могу легко использовать 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 
 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)  
lt; -o $(COMPILE)/$(@F)

Это устраняет перекомпиляцию объектных файлов, но требует, чтобы я добавил другую переменнуюPOJB дляprog цель (так как я могу 'не делать никаких patsubst только для объектных файлов без basedir).

Оба метода работают, и каждый имеет свои преимущества перед другим, но какой из них "правильный" подход, и если нет, то как правильно построить этот тип здания?

Ответы на вопрос(1)

Ваш ответ на вопрос