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 № 1Parece 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.