Как Makefile может использовать отдельные каталоги для исходного кода и двоичных файлов?
Я хочу, чтобы иметь возможность разбить мой bin и мои файлы кода на отдельные каталоги, поскольку в этом текущем состоянии становится трудно управлять.
Я идеально хотел бы иметь
project_dir
|-Makefile
|-run_tests.sh
|
|__source
| |-program1.cpp
| |-program2.cpp
|
|__bin
|-program1
|-program2
Однако я не могу заставить это работать с моей текущей системой без необходимости вручную выписывать правила для каждой программы (помните, что каждая программа представляет собой отдельную программу, а не ряд связанных между собой объектов)
#Current make system
BIN=./bin/
SOURCE=./source/
LIST=program1 program2...
all: $(LIST)
%: $(SOURCE)%.cpp
$(CC) $(INC) $< $(CFLAGS) -o $(BIN)[email protected] $(LIBS)
это работает, за исключением того, что он не может видеть цель в текущем пути, поэтому он считает, что он всегда восстанавливает двоичные файлы, даже если исходные файлы не изменились.
Моя единственная мысль на данный момент - написать программу для создания make файла, но я не хочу этого делать.
Ответы
Ответ 1
Ты был почти там...
#Current make system
BIN=./bin/
SOURCE=./source/
LIST=$(BIN)/program1 $(BIN)/program2...
all: $(LIST)
$(BIN)/%: $(SOURCE)%.cpp
$(CC) $(INC) $< $(CFLAGS) -o [email protected] $(LIBS)
Вы также можете сделать LIST
проще, используя следующие
PROG=program1 program2
LIST=$(addprefix $(BIN)/, $(PROG))
Ответ 2
Простое решение: используйте automake
.
Если вы хотите сделать это вручную, вам понадобится использовать директиву vpath
или переменную среды vpath
. В руководстве GNU есть раздел о них. Поместите свой Makefile непосредственно в каталог bin
, установите vpath
в исходный каталог, а неявные правила снова будут работать.
Ответ 3
Вот полная готовая версия Makefile.
Подготовьте свою папку со следующим каталогом
для .o файлов: /build/
для .cpp файлов: /src/
для двоичных файлов: /bin/
Затем используйте следующий Makefile в /
CC = g++
LD = g++
CFLAG = -Wall
PROG_NAME = prog
SRC_DIR = ./src
BUILD_DIR = ./build
BIN_DIR = ./bin
SRC_LIST = $(wildcard $(SRC_DIR)/*.cpp)
OBJ_LIST = $(BUILD_DIR)/$(notdir $(SRC_LIST:.cpp=.o))
.PHONY: all clean $(PROG_NAME) compile
all: $(PROG_NAME)
compile:
$(CC) -c $(CFLAG) $(SRC_LIST) -o $(OBJ_LIST)
$(PROG_NAME): compile
$(LD) $(OBJ_LIST) -o $(BIN_DIR)/[email protected]
clean:
rm -f $(BIN_DIR)/$(PROG_NAME) $(BUILD_DIR)/*.o
Ваша последняя программа будет называться как prog в /bin/
, каждый раз, когда вы скомпилируете код, двоичные файлы будут разделены на /build/
, чтобы каталог исходного кода был очень аккуратным и чистым.