Правильный m, метод для подстановочных знаков в 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
target (так как я не могу сделать patsubst только для объектных файлов без basedir).
Оба метода работают, и у каждого есть свои преимущества перед другим, но какой из них является «правильным» подходом, и если нет, каков правильный способ достижения этого типа здания?