Uma regra de destino vazia é um substituto viável para .DEFAULT_GOAL no GNU Make?
Pergunta
GNU Make versão 3.81 introduziu uma variável especial chamada .DEFAULT_GOAL que pode ser usada para informar ao Make qual objetivo (ou destino) deve ser construído se nenhum destino for especificado na linha de comando.Caso contrário, Make simplesmente criará o primeiro alvo que encontrar.
Considerar:
bar: a b c ${MAKE_BAR_COMMANDS} foo: x y z ${MAKE_FOO_COMMANDS}
Com o Makefile hipotético acima, executando make
irá construir "barra", pois é o primeiro alvo que faz encontros.Mas se adicionarmos .DEFAULT_GOAL, assim...
.DEFAULT_GOAL := foo # Build foo by default, even if it's not first. bar: a b c ${MAKE_BAR_COMMANDS} foo: x y z ${MAKE_FOO_COMMANDS}
...então o Make (versão 3.81) irá construir "foo" se executarmos apenas make
.
Eu descobri que esta variável .DEFAULT_GOAL é bastante útil em uma "estrutura" modular e reutilizável do Makefile que eu construí.No entanto, estou descobrindo que muitos sistemas ainda possuem GNU Make 3.80 ou anterior e não suportam esta variável.
Enquanto brincava com as coisas, percebi que simplesmente especificar uma regra de destino vazia parece ter o mesmo efeito que .DEFAULT_GOAL, mesmo em versões anteriores à 3.81 do GNU Make:
foo: # Empty target rule bar: a b c ${MAKE_BAR_COMMANDS} foo: x y z ${MAKE_FOO_COMMANDS}
Eu sei que é válido e legal adicionar regras e/ou pré-requisitos de um destino especificando regras de destino adicionais dessa maneira.No entanto, estou me perguntando se isso pode introduzir alguns efeitos colaterais potencialmente indesejáveis que não ocorrem ao usar .DEFAULT_GOAL.
Acho que estou me perguntando por que .DEFAULT_GOAL foi introduzido se você pode conseguir a mesma coisa com uma simples regra de destino vazia.Isso me faz suspeitar que talvez eles não resultem em exatamente o mesmo comportamento.
Portanto, as questões finais são:existe uma diferença detectável externamente entre usar .DEFAULT_GOAL e uma regra de destino vazia?
Solução
Não posso dar uma resposta definitiva, mas posso sugerir outras razões para a sua introdução:
- É imediatamente óbvio o que
.DEFAULT_GOAL
faz;ou sejao que diz no rótulo.A presença e o significado de um alvo vazio de linha única são facilmente ignorados, especialmente em um Makefile maior. - Você pode realmente ler o valor de
$(.DEFAULT_GOAL)
de volta em outro lugar no Makefile.Os testes sugerem que não faz diferença se é definido explicitamente ou se é determinado pela escolha da primeira regra.
Outras dicas
Seu "foo:# Regra de destino vazia" entra em conflito com regras de dois pontos duplos.
Se você descartar isso (::regras), funciona apenas se for a primeira regra.Portanto, se você "inclui variáveis clear.mk" no início e, em geral, tiver uma rede complicada de arquivos de incluir, este ".default_goal" tornará óbvio & verificado, que apenas 1 regra pode ser padrão.