Erro "Sem destino" usando Make

12

Estou aprendendo a usar makee makefiles, então escrevi este pequeno arquivo:

%.markdown: %.html
    pandoc -o $< $@

Mas quando corro make, tudo o que recebo é o make: *** No targets. Stop.que está acontecendo?

ahmed
fonte
São esses espaços ou uma guia na frente do pandoccomando. Make é notoriamente exigente quanto a esses itens serem uma tabulação e não espaços.
Slm
@ SLM: é uma guia. Li em algum lugar que o EOL do Windows não é compatível, então converti para o arquivo inteiro em EOL compatível com Unix.
ahmed

Respostas:

17

Problema:

Seu problema é que makenão sabe sobre seus alvos.

Você pode executar o Makefile acima com, make stackoverflow.markdownpor exemplo, e ele funcionará.

make somente, no entanto, falhará, pois você especificou apenas como criar seus destinos, mas não quais.

Como o leiaz aponta, a regra padrão acima é chamada de regra implícita .

Makefile:

SRC = $(wildcard *.html)
TAR = $(SRC:.html=.markdown)

.PHONY: all clean

all: $(TAR)

%.markdown: %.html
    pandoc -o $< $@

clean:
    rm -f $(TAR)

Explicação:

SRCget é todos os arquivos de origem (aqueles que terminam em .html) via Makefile wildcard.

O TAR substitui cada arquivo de origem listado SRCpor um destino que termina com em .markdownvez de .html.

.PHONY lista destinos não físicos que estão sempre desatualizados e, portanto, são sempre executados - geralmente são alle clean.

O destinoall tem como dependência (arquivos listados no lado direito da :) todos os *.markdownarquivos. Isso significa que todos esses destinos são executados.

%.markdown: %.html
    pandoc -o $< $@

Este trecho diz: Cada destino que termina com .markdowndepende de um arquivo com o mesmo nome, exceto que a dependência está terminando com .html. O curinga% deve ser visto como um *shell. O %lado direito, no entanto, é comparado ao jogo do lado esquerdo. Fonte .

Observe que a sequência de espaço em branco na frente de pandocé a TAB, pois makedefine isso como um padrão.

Finalmente, o cleanalvo falso mostra como limpar seu sistema dos arquivos que você criou com este Makefile. Nesse caso, está excluindo todos os destinos (os arquivos que foram nomeados *.markdown.

polym
fonte
1
Ótima resposta e esses são outros links que eu encontrei ao tentar entender melhor: função curinga , referências de substituição e destinos falsos .
ahmed
Mais uma pergunta: por favor, makefilecrie arquivos do zero ou atualize apenas os arquivos existentes? Porque quando eu excluo os arquivos gerados, ele pára de funcionar. Pergunta boba, eu sei, mas isso é Terra Nova para mim ^^ "
ahmed
1
quer dizer, se não houver arquivos .markdown, eles serão criados? sim ele deve fazer isso, tanto quanto eu sei
polímer
1
Tudo bem então. Eu vou fazer mais algumas escavações. Obrigado por suas respostas, graças a você, estou no caminho certo agora
:)
1
Só queria agradecer pela ótima resposta. A maneira como você explicou é muito fácil de entender a razão por trás do comando não estava funcionando e instruções muito detalhadas sobre como proceder. Obrigado novamente.
Zanona 26/08/16
5

Regras padrão são regras implícitas.

Você não possui destinos definidos no seu Makefile. Você pode especificar o alvo na linha de comando: make something.markdownvai usar a receita para criar something.markdowna partir something.html.

Ou você pode adicionar ao seu Makefile uma regra especificando destinos padrão.

all: file1.markdown file2.markdown

Ou com um curinga:

all: *.markdown

Quando você executa apenas make, o primeiro destino da primeira regra é o objetivo padrão . Não precisa ser chamado all.

Portanto, o destino alltem todos os arquivos que você deseja criar como pré-requisitos; portanto, quando você make allcriará todos os arquivos listados.

Leiaz
fonte