Я использую 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))
?
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
флаг, поэтому компилятор генерирует файлы зависимостей как побочный эффект.
Других решений пока нет …