根据我在互联网上阅读的内容,您可以说:A 依赖于 B 而 B 依赖于 C -> A 依赖于C
因此,如果我们有一个如下所示的 makefile:
CC=g++
OUTPUT=app.exe
SOURCES=$(wildcard *.cpp)
OBJECTS=$(patsubst %.cpp, %.o, $(SOURCES))
$(OUTPUT): $(OBJECTS)
$(CC) -o $(OUTPUT) $(OBJECTS)
main.o: main.cpp a.hpp
$(CC) -c main.cpp
a.hpp: b.hpp
我希望 main.o
依赖于 b.hpp
,因此如果 b.hpp
在 之后被改变,我应该编译>main.o
是最后编译的。但这并没有发生。
我是不是完全误解了它根本不像我描述的那样工作?如果是这样,main.o 的目标应该是什么样的?我是否必须检查文件包含的所有 header 并使其依赖于所有这些 header ?
编辑:
正如 Sam Miller 所说,即使 b.hpp
已更改,a.hpp
的时间戳也不会更改,因为没有更新 a.hpp< 的命令
。
Sam Miller 建议使用 touch
命令。但由于我在 Windows 上找不到简单的等效程序,所以我编写了一个名为 WinTouch
的小程序。效果很好,谢谢大家。
EDIT2
Chnossos 向我展示了在 makefile 方面我还有很多东西要学。我尝试了他提出的示例 makefile,它运行良好,似乎它会让我以后的生活更轻松。
最佳答案
Have I entirely misunderstood and it doesn't work the way I've described at all?
你几乎完全明白了,@Sam Miller 的 answer解释你的尝试中遗漏了什么。您需要告诉 make a.hpp
也已更改。
我想解决这个问题:
Do I have to go through all headers a file includes and also make it dependent off of all of those?
现在 GCC 或 clang 都可以自动为您处理:
让我们构建一个简单的工作示例
EXE := app.exe
SRC := $(wildcard *.cpp)
OBJ := $(SRC:.cpp=.o)
DEP := $(OBJ:.o=.d)
CPPFLAGS += -MMD -MP # built-in variable meant for preprocessor flags, like -I
$(EXE): $(OBJ)
# Linker phase
# LDFLAGS is a built-in variable meant for linker flags such as -L
# LDLIBS is a built-in variable meant for linker flags such as -l
# Their order in the next line IS IMPORTANT to avoid undefined references
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@
# Makefile include command, litteraly copy and paste its arguments' content into
# the makefile. The dash in the beginning prevent outputting an error if a file
# cannot be found.
-include $(DEP)
这就是您所需要的。现在,对于文件夹中给定的 .cpp
文件,您将有一个相应的 .o
文件和一个 .d
文件为您跟踪 header 依赖项。
如果您想将这些额外的文件隐藏在文件夹中,方法如下:
EXE := app.exe
SRC := $(wildcard *.cpp)
DIR := build
OBJ := $(SRC:%.cpp=$(DIR)/%.o) # toto.cpp => build/toto.o
DEP := $(OBJ:.o=.d) # build/toto.o => build/toto.d
CPPFLAGS += -MMD -MP # built-in variable meant for preprocessor flags, like -I
$(EXE): $(OBJ)
# Linker phase
# LDFLAGS is a built-in variable meant for linker flags such as -L
# LDLIBS is a built-in variable meant for linker flags such as -l
# Their order in the next line IS IMPORTANT to avoid undefined references
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@
# We need to override the implicit rule for .o files since we want a special
# destination. The right side of the pipe will only be evaluated once, it is
# called "order-only prerequisite".
$(DIR)/%.o: %.cpp | $(DIR)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
$(DIR):
@mkdir -p $@
# Makefile include command, litteraly copy and paste its arguments' content into
# the makefile. The dash in the beginning prevent outputting an error if a file
# cannot be found.
-include $(DEP)
如果您有任何问题。
关于c++ - makefile - 依赖的依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25098380/