Я видел, что ваш make-файл работает, но я просто хотел добавить несколько вещей, которые вы могли бы рассмотреть для будущих проектов. Я рекомендую использовать переменную vpath, а не указывать $(OBJDIR)/%.o
в ваших рецептах make-файла. На самом деле я где-то читал, что это не «пушка» - создавать объектные файлы в отдельном каталоге, но в ходе простого поиска, который я проводил перед публикацией, я не смог найти документ.
Как говорится, я написал make-файл, который делает то, что вы хотели; он создает выходную папку, генерирует зависимости и компилирует программу. Я специально включил определение $(COMPILE.cpp)
, чтобы вы могли видеть, из чего оно состоит. $(CC)
- это конкретно компилятор C, а $(CFLAGS)
- это флаги для компилятора C. Очевидно, что это просто переменные, так что вы можете изменить их, как сделали, и это будет работать нормально, но главное, что нужно помнить, это то, что тот, кто использует ваши программы, будет ожидать, что он сможет настроить компиляцию так, как считает нужным. Это означает, что они установят $(CXX)
и $(CXXFLAGS)
, ожидая установить компилятор C ++ и флаги. $(CPPFLAGS)
обозначает флаги препроцессора C / C ++.
Это не самый чистый make-файл, и если бы я хотел что-то изменить, я бы просто скомпилировал объектные файлы на месте и избавил себя от этой головной боли. Это сокращает ненужный взлом, но для ответа на ваш вопрос, вот оно. В любом случае, я надеюсь, что это поможет вам, дайте мне знать, если у вас есть какие-либо вопросы.
<ч />
О да, я почти забыл; обратите внимание, что я изменил ваш make clean
скрипт. Я использовал $(RM)
вместо простого rm -f
. Когда вы используете утилиты в ваших make-файлах, вы хотите использовать их как переменные . Опять же, это дает вашим пользователям как можно больше свободы и гибкости при компиляции вашей программы.
<ч />
vpath %.cpp src
vpath %.hpp include
vpath %.o build/objs
vpath %.d build/objs
.SUFFIXES:
.SUFFIXES: .cpp .hpp .o .d
SRCDIR = src
INCLUDESDIR = include
BUILDDIR = build
OBJDIR = $(BUILDDIR)/objs
SRCS = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS)))
DEP_FILES = $(patsubst %.o, %.d, $(OBJS))
INCLUDE_DIRS = -I $(INCLUDESDIR)
CXX = g++
CPPFLAGS =
CXXFLAGS = -Wall -Wextra -g -std=c++11
PROGRAM = hello.out
COMPILE.cpp = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDE_DIRS) $(TARGET_ARCH)
all: $(PROGRAM)
$(PROGRAM): %: $(OBJS)
$(LINK.cpp) $(INCLUDE_DIRS) $(addprefix $(OBJDIR)/, $^) $(LOADLIBES) $(LDLIBS) -o $@
%.o: %.cpp
$(COMPILE.cpp) -c -o $(OBJDIR)/$@ $<
%.d: %.cpp
mkdir -p $(OBJDIR)
$(COMPILE.cpp) $^ -MM -MT $(addprefix $(OBJDIR)/, $(@:.d=.o)) > $(OBJDIR)/$@
include $(DEP_FILES)
.PHONY: clean
clean:
@echo $(RM)
$(RM) $(BUILDDIR) -r
$(RM) *~
$(RM) $(PROGRAM)