blah: blah.o
cc blah.o -o blah # Runs third
blah.o: blah.c
cc -c blah.c -o blah.o # Runs second
blah.c:
echo "int main() { return 0; }" > blah.c # Runs first
Quando eu executo make
o comando, ele dá a saída esperada. Agora, se eu touch
o arquivo blah.c, a saída é cc -c blah.c -o blah.o cc blah.o -o blah
, mas quando eu executo o delete
arquivo blah.c, ele continua a criá-lo e a saída é echo "int main() {return 0; }" > blah.c cc -c blah.c -o blah.o cc blah.o -o blah
.
Agora o que não consigo entender é como o 'blah' soube que blah.c não está disponível. Ele apenas verificou blah.o cujo carimbo de data/hora não mudou. É que o próprio blah.o verifica blah.c para qualquer atualização quando foi verificado por 'blah'. De qualquer forma, por que as duas saídas são diferentes? É que touch
ing o arquivo blah.c não o removeu, e blah.o está ciente disso, então ele apenas atualizou seu carimbo de data/hora. O que está realmente acontecendo?
Ok: para responder à sua pergunta real sobre excluir ou alterar um arquivo:
Quando você cria
touch
um arquivo (ou o atualiza editando, baixando uma fonte de um repositório, aplicando patches, etc.), ele se torna mais novo que qualquer outro arquivo. A execuçãomake
executará os comandos que são afetados por essa situação e garantirá que cada dependência seja avaliada na ordem determinada pela árvore de dependências.Quando você
delete
um arquivo, ele é tratado como sendo infinitamente antigo (ou possivelmente 01-Jan-1970 00:00:00). A execuçãomake
executará quaisquer regras que sejam afetadas por essa situação diferente.make
consertará tudo o que o Makefile escolher. Por exemplo, se você alterar um.h
arquivo que é mencionado em sete dos seus dezoito.c
arquivos (e as regras apropriadas estiverem corretas), entãomake
executará as compilações para esses sete.c
arquivos, e também as regras onde qualquer coisa depende dos.o
arquivos deles.Sua linha de dependência for
blah.c
não lista nenhuma dependência, então make não tem um arquivo para comparar para decidir reconstruí-lo. Então ele só o reconstruirá se ele não existir.Como tudo para criar blah.c está no próprio makefile, eu sugeriria tornar o makfile uma dependência.
E então toda vez que você editar (ou mexer) no Makefile, ele reconstruirá o blah.c.
Para maior sofisticação, em vez de escrever diretamente em blah.c, escreva em blah.c.new e, se forem diferentes, substitua blah.c e, se forem iguais, exclua blah.c.new.