GNU Makefile автоматическое разрешение зависимостей

Я использую qmake а также CMake В прошлом без проблем генерировались мои make-файлы. Однако недавно я решил, что на некоторых кластерах, где я запускаю свои коды, эти инструменты сложнее найти / установить, поэтому я решил написать голые Makefile. Кроме того, я мог бы также кое-что узнать о Makefiles;)

Мой проект включает в себя несколько каталогов с исходными / заголовочными файлами внутри и чаще всего между ними. Я научился через ТАК использовать -MM флаг для автоматической генерации информации о зависимостях. Мои Makefiles выглядят так

include $(HEAD_DIR)/common.mk

OBJS_DIR = objs
LIBS_DIR = libs

SRCS  = Matrix.cpp MatrixFull.cpp
OBJS  = $(patsubst %,$(OBJS_DIR)/%,$(SRCS:.cpp=.o))
LIB_0 = $(patsubst %, $(LIBS_DIR)/%,libalgebra.a)

DEPS := $(patsubst %,$(OBJS_DIR)/%,$(SRCS:.cpp=.d))
-include $(DEPS)

.PHONY: all
all:
@echo   " ===== Building dependencies in lib/algebra ===== "@$(MKDIR) $(OBJS_DIR)
@$(MAKE)  $(OBJS)
@$(MKDIR) $(LIBS_DIR)
@$(MAKE)  $(LIB_0)
@echo   " ===================== done ===================== "
$(OBJS_DIR)/%.o: %.cpp
@echo " compiling source file:   $< ..."$(CXX) -c $(CXXFLAGS) -I$(INCLUDE_PATH) -MM $< -o $@

$(LIB_0): $($(OBJS_DIR)/%.o)
@echo " generating library file: $(@F) ..."@$(AR) $(AR_FLAGS) $@ $^

.PHONY: clean
clean:
@$(RM) $(OBJS_DIR) $(LIBS_DIR)

Обычно это работает нормально, но я хотел бы улучшить пару вещей:
1) Когда я изменяю заголовочный файл и выдаю make, как-то компилятор не ковыряется all и, кажется, по умолчанию DEPS, Это должно произойти в этом make-файле? Как я могу сделать all правило по умолчанию?
2) Как сделать файлы зависимостей невидимыми? Я старался DEPS := $(patsubst %,$(OBJS_DIR)/.%,$(SRCS:.cpp=.d)) но это не помогло
3) Есть ли какие-то конкретные предложения, которые вы могли бы дать мне, если вы думаете, что этот Makefile можно улучшить каким-либо другим способом?

РЕДАКТИРОВАТЬ: Если честно, я даже не уверен, как make вызывает компилятор для генерации зависимостей: p … Я не вижу явного правила для этого. Это как-то скрыто в DEPS := $(patsubst %,$(OBJS_DIR)/%,$(SRCS:.cpp=.d)) ?

0

Решение

1) Переместить -include $(DEPS) внизу all править. Первое правило является правилом по умолчанию (если вы специально не установили какую-то специальную переменную), так что если include тянет в правиле выше all:, это будет по умолчанию.

2) Я предполагаю, что под «сделать их невидимыми» вы подразумеваете, что хотите .foo.d вместо foo.d, Вы должны изменить правило, которое делает их:

$(OBJS_DIR)/%.o: %.cpp
@echo " compiling source file:   $< ..."$(CXX) -c $(CXXFLAGS) -I$(INCLUDE_PATH) -MM $< -o $@
@mv $(OBJS_DIR)/$*.d $(OBJS_DIR)/.$*.d

а затем переменная, которая находит их:

DEPS := $(patsubst %.cpp,$(OBJS_DIR)/.%.d,$(SRCS))

3) Я бы избавился от рекурсивных звонков ($(MAKE) ...), но вы должны убедиться, что все остальное работает правильно в первую очередь. И я удивлен $(OBJS_DIR)/%.o правило не входит в common.mk, Кроме того, это выглядит довольно хорошо.

4 (?)) Команда компилятора в $(OBJS_DIR)/%.o Правило использует -MM флаг, поэтому компилятор генерирует файлы зависимостей как побочный эффект.

1

Другие решения

Других решений пока нет …