我目前正在尝试构建一个合适的 Makefile。
我想要的是完全控制正在发生的事情,所以我不想要任何第三方软件。
我目前的尝试对我来说似乎是合乎逻辑的,但由于依赖生成无效,我有点卡住了。
为了更好的可读性,完整的 Makefile 被分成小块。如果有需要改进的地方,我将不胜感激任何部分的评论。
首先,我有以下静态定义
CXX = g++
CXXFLAGS = -Wall \
-Wextra \
-Wuninitialized \
-Wmissing-declarations \
-pedantic \
-O3 \
-p -g -pg
LDFLAGS = -p -g -pg
DEPFLAGS = -MM
Afaik 这应该没问题。将分析标志设为可选是完美的,但这并不重要。
SRC_DIR = ./src
OBJ_DIR = ./obj
SRC_EXT = .cpp
OBJ_EXT = .o
TARGET = ./bin/my_target
SRCS = $(wildcard $(SRC_DIR)/*$(SRC_EXT))
OBJS = $(subst $(SRC_DIR), $(OBJ_DIR), $(SRCS:$(SRC_EXT)=$(OBJ_EXT)))
DEP = depend.main
基本上,这应该只是*.cpp
从子文件夹中提取所有文件,并src
另外替换./src
为对象名称。./obj
.cpp
.o
.PHONY: clean all depend
all: $(TARGET)
$(TARGET): $(OBJS)
@echo "-> linking $@"
@$(CXX) $^ $(LDFLAGS) -o $@
$(OBJ_DIR)/%.$(EXT_OBJ):
@echo "-> compiling $@"
@$(CXX) $(CXXFLAGS) -c $< -o $@
Afaik,这个块 - 如果存在有效的依赖文件 - 应该进行所有必要的编译和链接。
clean:
@echo "removing objects and main file"
@rm -f $(OBJS) $(TARGET)
应该是不言自明和正确的,还是我在这里遗漏了什么?
$(SRC_DIR)/%.$(SRC_EXT):
$(CXX) $(DEPFLAGS) -MT \
"$(subst $(SRC_DIR),$(OBJ_DIR),$(subst $(SRC_EXT),$(OBJ_EXT),$@))" \
$(addprefix ,$@) >> $(DEP);
clear_dependencies:
@echo "-> (re-)building dependencies";
@$(RM) $(DEP)
depend: clear_dependencies $(SRCS)
这是非功能部分。我打算做的是使用g++
Compiler 标志-MM
来自动创建依赖项并使用-MT
与默认路径不同的路径。产生的依赖应该看起来像
./obj/main.o: ./src/main.cpp ./src/some_header_file.h
不幸的是,这永远不会被调用,我不知道为什么会这样。在一个类似的问题中,用户 Beta 很高兴地通过添加 a 提供了一个临时解决方案,.Phony
但这对重建每个对象而不做任何更改有副作用。
最后,只有一行
-include $(DEP)
包含依赖文件,一旦创建。
非常欢迎提供有关任何部分的一些提示的任何答案。所以我的问题是:我可以做得更好或者“更清洁”,为什么依赖生成不起作用?