我有以下makefile用于构建我正在处理的程序(实际上是内核).它从头开始,我正在学习这个过程,所以它并不完美,但我认为它在这一点上足够强大,因为我在编写makefile时的经验水平.
AS = nasm CC = gcc LD = ld TARGET = core BUILD = build SOURCES = source INCLUDE = include ASM = assembly VPATH = $(SOURCES) CFLAGS = -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions \ -nostdinc -fno-builtin -I $(INCLUDE) ASFLAGS = -f elf #CFILES = core.c consoleio.c system.c CFILES = $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) SFILES = assembly/start.asm SOBJS = $(SFILES:.asm=.o) COBJS = $(CFILES:.c=.o) OBJS = $(SOBJS) $(COBJS) build : $(TARGET).img $(TARGET).img : $(TARGET).elf c:/python26/python.exe concat.py stage1 stage2 pad.bin core.elf floppy.img $(TARGET).elf : $(OBJS) $(LD) -T link.ld -o $@ $^ $(SOBJS) : $(SFILES) $(AS) $(ASFLAGS) $< -o $@ %.o: %.c @echo Compiling $<... $(CC) $(CFLAGS) -c -o $@ $< #Clean Script - Should clear out all .o files everywhere and all that. clean: -del *.img -del *.o -del assembly\*.o -del core.elf
我对makefile的主要问题是,当我修改一个或多个C文件包含的头文件时,不会重建C文件.通过让我的所有头文件都是我所有C文件的依赖项,我可以很容易地解决这个问题,但是这会在我更改/添加头文件时有效地导致项目的完全重建,这不会非常优雅.
我想要的只是包含我改变的头文件的C文件重建,以及整个项目再次链接.我可以通过使所有头文件成为目标的依赖项来进行链接,但是当我们包含的头文件较新时,我无法弄清楚如何使C文件失效.
我听说GCC有一些命令可以使这成为可能(因此makefile可以以某种方式找出需要重建的文件)但我不能在我的生活中找到一个实际的实现示例来查看.有人可以发布一个解决方案,在makefile中启用此行为吗?
编辑:我应该澄清,我熟悉将各个目标放入并拥有每个目标的概念.o需要头文件.这要求我每次在某处包含头文件时都要编辑makefile,这有点痛苦.我正在寻找一个可以自己派生头文件依赖的解决方案,我相当肯定我已经在其他项目中看到了.
正如本网站其他地方已经指出的那样,请参阅此页面:http: //make.paulandlesley.org/autodep.html
简而言之,gcc可以自动为您创建.d依赖文件,这些文件是包含您编译的.c文件的依赖项的迷你makefile片段.每次更改.c文件并进行编译时,都会更新.d文件.
除了向gcc添加-M标志外,还需要在makefile中包含.d文件(如上面的Chris所述).在页面中有一些更复杂的问题,使用sed解决,但你可以忽略它们并做"清理"以清除.d文件,只要抱怨无法生成不再存在的头文件.
您可以像其他人所说的那样添加'make depend'命令,但为什么不让gcc创建依赖项并同时编译:
DEPS := $(COBJS:.o=.d) -include $(DEPS) %.o: %.c $(CC) -c $(CFLAGS) -MM -MF $(patsubst %.o,%.d,$@) -o $@ $<
'-MF'参数指定用于存储依赖项的文件.
'-include'开头的破折号告诉Make在.d文件不存在时继续(例如在第一次编译时).
注意gcc中似乎存在关于-o选项的错误.如果你设置对象文件名,obj/_file__c.o
那么生成的_file_.d
仍将包含_file_.o
,而不是obj/_file_c.o
.
这相当于克里斯多德的答案,但使用了不同的命名约定(巧合的是不需要sed
魔法.从后来的副本复制.
如果您使用的是GNU编译器,编译器可以为您组装一个依赖项列表.Makefile片段:
depend: .depend .depend: $(SOURCES) rm -f ./.depend $(CC) $(CFLAGS) -MM $^>>./.depend; include .depend
还有工具makedepend
,但我从来都不喜欢它gcc -MM
您必须为每个C文件创建单独的目标,然后将头文件列为依赖项.您仍然可以使用通用目标,然后放置.h
依赖项,如下所示:
%.o: %.c @echo Compiling $<... $(CC) $(CFLAGS) -c -o $@ $< foo.c: bar.h # And so on...