Eu tenho o seguinte makefile que uso para construir um programa (um kernel, na verdade) no qual estou trabalhando. É do zero e estou aprendendo sobre o processo, então não é perfeito, mas acho que é poderoso o suficiente neste ponto para o meu nível de experiência escrevendo makefiles.
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
Meu principal problema com este makefile é que quando eu modifico um arquivo de cabeçalho que um ou mais arquivos C incluem, os arquivos C não são reconstruídos. Posso consertar isso facilmente fazendo com que todos os meus arquivos de cabeçalho sejam dependências de todos os meus arquivos C, mas isso efetivamente causaria uma reconstrução completa do projeto sempre que eu alterasse / adicionasse um arquivo de cabeçalho, o que não seria muito elegante.
O que eu quero é que apenas os arquivos C que incluem o arquivo de cabeçalho que alterei sejam reconstruídos e que todo o projeto seja vinculado novamente. Posso fazer a vinculação fazendo com que todos os arquivos de cabeçalho sejam dependências do destino, mas não consigo descobrir como fazer com que os arquivos C sejam invalidados quando seus arquivos de cabeçalho incluídos são mais recentes.
Ouvi dizer que o GCC tem alguns comandos para tornar isso possível (para que o makefile possa de alguma forma descobrir quais arquivos precisam ser reconstruídos), mas não consigo encontrar um exemplo de implementação real para examinar. Alguém pode postar uma solução que permitirá esse comportamento em um makefile?
EDIT: Devo esclarecer, estou familiarizado com o conceito de colocar os destinos individuais e ter cada destino.o exigir os arquivos de cabeçalho. Isso requer que eu edite o makefile toda vez que incluo um arquivo de cabeçalho em algum lugar, o que é um pouco chato. Estou procurando uma solução que possa derivar as dependências do arquivo de cabeçalho por conta própria, o que tenho quase certeza de ter visto em outros projetos.