surpresa do GNU Makefile

2

Eu estou tentando construir um Makefile de projeto de dois estágios simples com o GNU make.

A lógica que quero seguir é

  1. Primeiro eu construo as dependências (por gcc -M )
  2. Eu incluo os arquivos .dep gerados no Makefile em uma segunda compilação de estágio.

A parte relevante do meu projeto é a seguinte:

MAKEDEP:=$(CXX) $(CXXFLAGS) -M
ALL_SRCS:=$(ALL_OBJS:.o:.cc)
CXX_DEPS:=$(patsubst %.o,.%.dep,$(ALL_OBJS))

-include $(CXX_DEPS)

%.o: %.cc .%.dep
        $(CXX) $(CXXFLAGS) -c -o $@ $<

.%.dep: %.cc
        $(MAKEDEP) -o $@ $<

clean:
        $(RM) -vf $(ALL_OBJS) $(ALL_LIBS) $(ALL_APPS)

dep: $(CXX_DEPS)

Tudo funciona bem, com uma única exceção: se eu executar um make clean , ele reconstruirá as dependências! Como se uma linha clean: dep existisse em vez de uma linha simples clean: :

$ make clean
g++ -Wall -std=c++11 -M -o .file1.dep file1.cc
g++ -Wall -std=c++11 -M -o .file2.dep file2.cc
g++ -Wall -std=c++11 -M -o .file3.dep file3.cc
rm -vf file1.o file2.o file3.o app
$

O que está no fundo? Por que precisa reconstruir as dependências antes de uma limpeza? Eu não dei tal dependência.

    
por peterh 27.08.2015 / 22:50

1 resposta

5

Como você pediu para incluir os arquivos, segue as regras para criá-los.

Agora tentarei lembrar como resolvi o problema no meu projeto:

Primeiro, perceba que não nos importamos com dependências extras na primeira vez, já que temos que construir o arquivo objeto de qualquer maneira.

Então, se adicionarmos (ou removermos) dependências, devemos mudar algo que já dependemos (o .cc ou um dos .h existentes).

Em resumo, não precisamos da lista completa de dependências para o estado atual, as dependências do estado anterior são boas o suficiente. Portanto, podemos construir o .dep s ao mesmo tempo que o .o (isso também é mais rápido, pois somente um CC pass é necessário).

[o próximo bit que eu tenho um pouco menos de certeza]

Agora precisamos inicializar as dependências: Escreva uma regra para criar alguns arquivos .dep fictícios (vazios) (sempre que um .cc for criado (isso pode ser muito rápido)).

Agora ainda temos que criar esses arquivos .dep fictícios e, em seguida, limpá-los. Se você evitar a criação recursiva, não precisará de limpeza para contornar erros (só é necessário limpar para economizar espaço em disco).

O último passo foi adicionar um nível de recursão (lembre-se que make recursivo (geralmente) é considerado prejudicial link )

Escreva um makefile simples para regras limpas, que as chamadas façam em outro makefile para qualquer regra que ele não possa fazer.

Você pode precisar apenas deste último passo, mas eu não vou deletar o início da resposta, pois ele mostra como melhorar o makefile.

    
por 27.08.2015 / 23:29

Tags