/ / GNU Make e curingas - arquivos ausentes - makefile, gnu-make

GNU Make e wildcards - arquivos ausentes - makefile, gnu-make

Eu tenho um Makefile com o seguinte tipo de regra:

%.html:
./generate-images.py > $@
make $(patsubst %.png,%.gif,$(wildcard *.png))

o generate-images O script grava não apenas o arquivo HTML (no stdout), mas vários arquivos .png no diretório atual. O objetivo aqui é convertê-los para .gif. (na verdade não, mas este é um exemplo)

Isso funciona se eu invocá-lo diretamente. O problema é: se eu invocá-lo de outra regra em que foo.html é uma dependência, a instrução curinga falha ao encontrar arquivos. Em outras palavras, apenas chamou make sem argumentos, o que não é o que eu quero aqui.

Qual é o problema com o curinga? Ou existe uma maneira melhor de fazer isso?

Respostas:

1 para resposta № 1

Parece que está avaliando todas as $() expressões como ele está processando o Makefile, em vez de executar cada regra. Você pode adicionar uma regra ao seu makefile da seguinte maneira:

images: $(patsubst %.png,%.gif,$(wildcard *.png))
.PHONY: images

e altere seu snippet de exemplo para

%.html:
./generate-images.py > $@
make images

para que o Make avalie o glob no momento certo. Isso é algo sobre o qual verificar o manual pode valer a pena.


3 para resposta № 2

Embora seu problema possa ser diferente, vejo claramente um.

Todo o texto de todos comandos dentro da regra são processados ​​simultaneamente para que as funções e variáveis ​​do make sejam expandidas. Suponha que você não tenha .png arquivos no diretório, e você invoca make, então ele deve gerá-los novamente: a.png e b.png. Então, depois de invocar make, o texto da regra seria efetivamente parecido com este:

file.html:
./generate-images.py > file.html
make

Porque no momento da leitura do makefile não havia .png arquivos! Após a execução da primeira linha, os arquivos aparecerão, mas a próxima linha já foi gerado para ser apenas "fazer".

E somente quando você invocar seu makefile pela segunda vez, ele se expandirá para

file.html:
./generate-images.py > file.html
make a.gif b.gif

Não é isso que você quer. Então, eu sugiro fazer isso da maneira certa.

# If you have batch conversion program, this may be helpful
images.stamp: *.png
convert_all_images $?
touch images.stamp

# OR, if you want convert one-by-one with means of make
images.stamp: $(wildcard *.png)
touch images.stamp

%.gif: %.png
convert_one --from=$^ --to=$@

# HTML would look like
%.html:
./generate-images.py > $@
make images.stamp

Então, quando você invoca make all, ele gera htmls e converte imagens recém-geradas. Observe que só irá converter as imagens que são atualizadas, que é o que você quer.


Graças a Beta para apontar a bagunça com extensões gif / png.