Я плохо знаком с Make-файлами и g ++, и я поражен проблемой при генерации зависимостей использования файлов проекта - флаг MM. Я отправляю Make-файл, который я использую для Вашего внимания. Смотрите.
OUTPUT_ROOT := output/
SOURCE_ROOT := source/
TITLE_NAME := TestProj
SOURCES := \
MyFile.cpp \
stdAfx.cpp \
Main.cpp \
OUT_DIR := $(OUTPUT_ROOT)
OUT_O_DIR := $(OUT_DIR)
OBJS = $(SOURCES:%.cpp=$(OUT_O_DIR)%.o)
DEPS = $(OBJS:%.o=%.d)
DIRS = $(subst /,/,$(sort $(dir $(OBJS))))
SOURCE_TARGET = $(SOURCES:%.cpp=$(SOURCE_ROOT)%.cpp)
OUTPUT_TARGET = $(OUT_DIR)$(TITLE_NAME)
#---------------------------------------------------------------------
# executables
#---------------------------------------------------------------------
MD := mkdir -p
RM := rm
CC := g++
#---------------------------------------------------------------------
# rules
#---------------------------------------------------------------------
.PHONY: clean directories objects title
all: directories objects title
directories:
@$(MD) $(DIRS)
clean:
$(RM) -rf $(OUT_DIR)
$(OBJS): $(SOURCE_TARGET)
@$(CC) -c $< -o $@
$(DEPS): $(SOURCE_TARGET)
@$(CC) -c -MM $< > $(DEPS)
-include $(DEPS)
objects:$(OBJS) $(DEPS)
title: $(OBJS)
@$(CC) $< -o $@
Я много раз пробовал несколько опций и sooo. Я погуглил для решения, но не мог найти никого.
Использует "-MM" флаг для генерации зависимостей правильная опция?? Если не предложите меня правильный способ генерировать зависимости. Я хотел к сгенерированным зависимостям автоматически, потому что мой проект будет иметь sooo многими файлами. Я думал, что это - более оптимальный вариант, чем записать evey зависимость вручную.
Это ошибки, которые я получаю
g++: stdAfx.d: No such file or directory
g++: Main.d: No such file or directory
make: *** No rule to make target `stdAfx.d', needed by `objects'. Stop.
Заранее спасибо.
Похоже, что вы пытаетесь сгенерировать файл зависимости (называемый *.d, по вашим правилам makefile) для каждого .cpp файла. Я не понимаю, как используется файл зависимостей.
Используйте опцию -M, чтобы сгенерировать один файл зависимостей для вашего проекта, а затем включить файл зависимостей.
DEPS = $(OUR_DIR)/make.dep
$(DEPS): $(SOURCE_TARGET)
@$(CC) -M $(SOURCE_TARGET) > $(DEPS)
include $(DEPS)
edit Ваш файл зависимостей также должен зависеть от ваших заголовков
$(DEPS): $(SOURCE_TARGET) $(HEADER_TARGET)
@$(CC) -M $(SOURCE_TARGET) > $(DEPS)
где HEADER_TARGET определяется так же, как и SOURCE_TARGET. Таким образом, при изменении заголовочного файла файл зависимости перестраивается.
.Для новичка ты делаешь экзотические вещи. Вы должны начать с простого и использовать в Makefile только тот код, который вы на 100% понимаете и которому доверяете. Даже в большом проекте с сотнями файлов вы не потратите много времени на поддержку Makefile.
Переменные, присваиваемые с :=, сразу расширяются - все значения $(VAR) подставляются в значение переменной при присваивании. Переменные, которым присваивается значение =, при их использовании расширяются, поэтому они могут делать такие вещи, как обращение к переменным, которые еще не определены.
Флаг -MM для g++ сгенерирует строку зависимости от Makefile, например, foo.o: foo.cc foo.hh, но я никогда не находил ее полезной. У меня была фальшивая цель "зависимости", которая генерировала один файл зависимости. Ваша идея сделать кучу *.d файлов с этими однострочными зависимостями может сработать, но в итоге вы получите много таких файлов.
Ошибка, которую вы получаете, это от g++, а не от make. Это потому, что вы используете $(DEPS), как если бы это был один файл, когда это весь список *.d файлов. Происходит следующее:
@$(CC) -c -MM $< > $(DEPS)
расширяется до:
g++ -c -MM MyFile.cpp > MyFile.d stdAfx.d Main.cpp
mcdave только что выложил код, который я использовал для генерации файла зависимости. Вы можете либо переключиться на стиль одиночного файла зависимости, либо изменить вашу команду -MM на:
@$(CC) -MM $< > $@
Вам также может потребоваться исправить оператор -include, потому что я не думаю, что он поддерживает список файлов для включения.
.