当前位置:  开发笔记 > 编程语言 > 正文

如何让Makefile自动重建包含已修改头文件的源文件?(在C/C++中)

如何解决《如何让Makefile自动重建包含已修改头文件的源文件?(在C/C++中)》经验,为你挑选了4个好方法。

我有以下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,这有点痛苦.我正在寻找一个可以自己派生头文件依赖的解决方案,我相当肯定我已经在其他项目中看到了.



1> 小智..:

正如本网站其他地方已经指出的那样,请参阅此页面:http: //make.paulandlesley.org/autodep.html

简而言之,gcc可以自动为您创建.d依赖文件,这些文件是包含您编译的.c文件的依赖项的迷你makefile片段.每次更改.c文件并进行编译时,都会更新.d文件.

除了向gcc添加-M标志外,还需要在makefile中包含.d文件(如上面的Chris所述).在页面中有一些更复杂的问题,使用sed解决,但你可以忽略它们并做"清理"以清除.d文件,只要抱怨无法生成不再存在的头文件.


我可能会弄错,但我认为GCC实际上已经添加了一个功能来尝试解决这个问题.请专门查看http://gcc.gnu.org/onlinedocs/gcc-4.3.1/gcc/Preprocessor-Options.html-MP.

2> Martin Fido..:

您可以像其他人所说的那样添加'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.


这不适合我.例如makefile生成并运行:`g ++ -c -Wall -Werror -MM -MF main.d -o main.o main.cpp`我得到了main.d文件,但是main.o是0字节.但是-MMD标志似乎完全符合要求.所以我的工作makefile规则变为:`$(CC)-c $(CFLAGS)-MMD -o $ @ $ <`

3> dmckee..:

这相当于克里斯多德的答案,但使用了不同的命名约定(巧合的是不需要sed魔法.从后来的副本复制.


如果您使用的是GNU编译器,编译器可以为您组装一个依赖项列表.Makefile片段:

depend: .depend

.depend: $(SOURCES)
        rm -f ./.depend
        $(CC) $(CFLAGS) -MM $^>>./.depend;

include .depend

还有工具makedepend,但我从来都不喜欢它gcc -MM


你为什么不拼出来源?不需要特别多的字符,也不像"SRCS"那样混淆,这可能看起来像一个缩写.

4> mipadi..:

您必须为每个C文件创建单独的目标,然后将头文件列为依赖项.您仍然可以使用通用目标,然后放置.h依赖项,如下所示:

%.o: %.c
        @echo Compiling $<...
        $(CC) $(CFLAGS) -c -o $@ $<

foo.c: bar.h
# And so on...

推荐阅读
臭小子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有