Mik*_*ike 90 dependencies makefile header-files
假设我有一个带有规则的makefile
%.o: %.c
gcc -Wall -Iinclude ...
Run Code Online (Sandbox Code Playgroud)
我想要在头文件更改时重建*.o.无论何时/include更改任何头文件,都必须重建dir中的所有对象,而不是计算出依赖项列表.
我想不出一个改变规则以适应这个的好方法,我愿意接受建议.如果标题列表不必硬编码,则奖励积分
dmc*_*kee 113
如果您使用的是GNU编译器,编译器可以为您组装一个依赖项列表.Makefile片段:
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^ -MF ./.depend;
include .depend
Run Code Online (Sandbox Code Playgroud)
要么
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^ > ./.depend;
include .depend
Run Code Online (Sandbox Code Playgroud)
where SRCS是指向整个源文件列表的变量.
还有工具makedepend,但我从来都不喜欢它gcc -MM
Sop*_*hie 63
大多数答案都令人惊讶地复杂或错误.然而,其他地方已经发布了简单而强大的示例[ codereview ].不可否认,gnu预处理器提供的选项有点令人困惑.但是,记录了从构建目标中删除所有目录,-MM而不是bug [ gpp ]:
默认情况下,CPP获取主输入文件的名称,删除任何 目录组件和任何文件后缀(如".c"),并附加平台的常用对象后缀.
(稍微更新)-MMD选项可能是你想要的.为了完整性,支持多个src目录并使用一些注释构建目录的makefile示例.对于没有构建目录的简单版本,请参阅[ codereview ].
CXX = clang++
CXX_FLAGS = -Wfatal-errors -Wall -Wextra -Wpedantic -Wconversion -Wshadow
# Final binary
BIN = mybin
# Put all auto generated stuff to this build dir.
BUILD_DIR = ./build
# List of all .cpp source files.
CPP = main.cpp $(wildcard dir1/*.cpp) $(wildcard dir2/*.cpp)
# All .o files go to build dir.
OBJ = $(CPP:%.cpp=$(BUILD_DIR)/%.o)
# Gcc/Clang will create these .d files containing dependencies.
DEP = $(OBJ:%.o=%.d)
# Default target named after the binary.
$(BIN) : $(BUILD_DIR)/$(BIN)
# Actual target of the binary - depends on all .o files.
$(BUILD_DIR)/$(BIN) : $(OBJ)
# Create build directories - same structure as sources.
mkdir -p $(@D)
# Just link all the object files.
$(CXX) $(CXX_FLAGS) $^ -o $@
# Include all .d files
-include $(DEP)
# Build target for every single object file.
# The potential dependency on header files is covered
# by calling `-include $(DEP)`.
$(BUILD_DIR)/%.o : %.cpp
mkdir -p $(@D)
# The -MMD flags additionaly creates a .d file with
# the same name as the .o file.
$(CXX) $(CXX_FLAGS) -MMD -c $< -o $@
.PHONY : clean
clean :
# This should remove all generated files.
-rm $(BUILD_DIR)/$(BIN) $(OBJ) $(DEP)
Run Code Online (Sandbox Code Playgroud)
此方法有效,因为如果单个目标有多个依赖关系,则只需连接依赖关系,例如:
a.o: a.h
a.o: a.c
./cmd
Run Code Online (Sandbox Code Playgroud)
相当于:
a.o: a.c a.h
./cmd
Run Code Online (Sandbox Code Playgroud)
Mar*_*ido 25
正如我在这里发布的那样gcc可以创建依赖项并同时编译:
DEPS := $(OBJS:.o=.d)
-include $(DEPS)
%.o: %.c
$(CC) $(CFLAGS) -MM -MF $(patsubst %.o,%.d,$@) -o $@ $<
Run Code Online (Sandbox Code Playgroud)
'-MF'参数指定用于存储依赖项的文件.
'-include'开头的破折号告诉Make在.d文件不存在时继续(例如在第一次编译时).
注意gcc中似乎存在关于-o选项的错误.如果将对象文件名设置为obj/_file__c.o,则生成的文件 .d仍将包含文件 .o,而不是obj/_file__c.o.
Mic*_*son 23
怎么样的:
includes = $(wildcard include/*.h)
%.o: %.c ${includes}
gcc -Wall -Iinclude ...
Run Code Online (Sandbox Code Playgroud)
您也可以直接使用通配符,但我倾向于发现我需要它们不止一个地方.
请注意,这仅适用于小型项目,因为它假定每个目标文件都依赖于每个头文件.
马丁的上述解决方案效果很好,但不能处理驻留在子目录中的 .o 文件。Godric 指出 -MT 标志可以解决这个问题,但它同时会阻止 .o 文件被正确写入。下面将解决这两个问题:
DEPS := $(OBJS:.o=.d)
-include $(DEPS)
%.o: %.c
$(CC) $(CFLAGS) -MM -MT $@ -MF $(patsubst %.o,%.d,$@) $<
$(CC) $(CFLAGS) -o $@ $<
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
97104 次 |
| 最近记录: |