O que .PHONY
significa em um Makefile? Eu já passei por isso , mas é muito complicado.
Alguém pode me explicar em termos simples?
fonte
O que .PHONY
significa em um Makefile? Eu já passei por isso , mas é muito complicado.
Alguém pode me explicar em termos simples?
Por padrão, os destinos do Makefile são "destinos de arquivos" - são usados para criar arquivos de outros arquivos. Make assume que seu destino é um arquivo, e isso facilita a escrita de Makefiles:
foo: bar
create_one_from_the_other foo bar
No entanto, às vezes você deseja que o Makefile execute comandos que não representam arquivos físicos no sistema de arquivos. Bons exemplos para isso são os alvos comuns "limpo" e "todos". Provavelmente, esse não é o caso, mas você pode ter um arquivo com o nome clean
no diretório principal. Nesse caso, o Make ficará confuso porque, por padrão, o clean
destino estaria associado a esse arquivo e o Make só o executará quando o arquivo não parecer atualizado com relação às dependências.
Esses alvos especiais são chamados de falsos e você pode dizer explicitamente que eles não estão associados aos arquivos, por exemplo:
.PHONY: clean
clean:
rm -rf *.o
Agora make clean
será executado conforme o esperado, mesmo se você tiver um arquivo chamado clean
.
Em termos de Make, um destino falso é simplesmente um destino sempre desatualizado; portanto, sempre que você solicitar make <phony_target>
, ele será executado independentemente do estado do sistema de arquivos. Alguns comuns make
alvos que estão muitas vezes falsa são: all
, install
, clean
, distclean
, TAGS
, info
, check
.
Vamos supor que você tenha um
install
alvo, o que é muito comum em makefiles. Se você não usar.PHONY
, e um arquivo nomeadoinstall
existir no mesmo diretório que o Makefile,make install
não fará nada . Isso ocorre porque Make interpreta a regra como "execute tal e qual receita para criar o arquivo chamadoinstall
". Como o arquivo já está lá e suas dependências não foram alteradas, nada será feito.No entanto, se você criar o
install
alvo PHONY, ele informará à ferramenta make que o alvo é fictício, e esse make não deve esperar que ele crie o arquivo real. Portanto, ele não verifica se oinstall
arquivo existe, o que significa: a) seu comportamento não será alterado se o arquivo existir eb) extrastat()
não será chamado.Geralmente todos os alvos em seu Makefile que não produzem um arquivo de saída com o mesmo nome que o nome do alvo devem ser PHONY. Isso normalmente inclui
all
,install
,clean
,distclean
, e assim por diante.fonte
.sh
ou.bash
dos "programas" executados como se tivessem uma função principal e reserve adicionar uma extensão para as bibliotecas que você inclui (source mylib.sh
). Na verdade, eu comecei a esta pergunta SO porque eu tinha um script no mesmo diretório como o meu Makefile chamadoinstall
.PHONY
o tempo todo ....PHONY
versão.NOTA : A ferramenta make lê o makefile e verifica os carimbos de data / hora da modificação dos arquivos ao lado do símbolo ':' em uma regra.
Exemplo
Em um diretório 'test', os seguintes arquivos estão presentes:
No makefile, uma regra é definida da seguinte maneira:
Agora, suponha que o arquivo 'hello' seja um arquivo de texto que contenha alguns dados, que foram criados após o arquivo 'hello.c'. Portanto, o carimbo de data / hora de modificação (ou criação) de 'hello' será mais novo que o de 'hello.c'. Portanto, quando chamaremos 'make hello' na linha de comando, ela será impressa como:
Agora acesse o arquivo 'hello.c' e coloque alguns espaços em branco, o que não afeta a sintaxe ou a lógica do código, e salve e saia. Agora, o carimbo de data / hora da modificação do hello.c é mais recente que o do 'hello'. Agora, se você chamar 'make hello', ele executará os comandos como:
E o arquivo 'olá' (arquivo de texto) será substituído por um novo arquivo binário 'olá' (resultado do comando de compilação acima).
Se usarmos .PHONY no makefile da seguinte maneira:
e depois invoque 'make hello', ele ignorará qualquer arquivo presente no pwd 'test' e executará o comando sempre.
Agora, suponha que o destino 'hello' não tenha dependências declaradas:
e o arquivo 'hello' já estiver presente no pwd 'test', então 'make hello' sempre será exibido como:
fonte
make
como finalmente faz com que o todo faça sentido, é tudo sobre os arquivos! Obrigado por esta resposta.fonte
É um destino de construção que não é um nome de arquivo.
fonte
A melhor explicação é o próprio manual do GNU make: 4.6 Seção de alvos falsos .
.PHONY
é um dos nomes de destino internos especiais do make . Você pode estar interessado em outros alvos, por isso vale a pena examinar essas referências.Você também pode estar interessado nos destinos padrão da marca , como
all
eclean
.fonte
Há também um tratamento complicado e importante de ".PHONY" - quando um alvo físico depende de um alvo falso que depende de outro alvo físico:
TARGET1 -> PHONY_FORWARDER1 -> PHONY_FORWARDER2 -> TARGET2
Você simplesmente esperaria que, se atualizasse o TARGET2, o TARGET1 fosse considerado obsoleto contra o TARGET1, portanto, o TARGET1 deve ser reconstruído. E realmente funciona dessa maneira .
A parte complicada é quando o TARGET2 não está obsoleto contra o TARGET1 - nesse caso, você deve esperar que o TARGET1 não deva ser reconstruído.
Surpreendentemente, isso não funciona porque: o alvo falso foi executado de qualquer maneira (como os destinos falsos normalmente fazem) , o que significa que o alvo falso foi considerado atualizado . E por causa disso, o TARGET1 é considerado obsoleto contra o alvo falso .
Considerar:
Você pode brincar com isso:
Você pode ver que o arquivo filiall depende indiretamente do arquivo1 através de um destino falso - mas ele sempre é reconstruído devido a essa dependência. Se você alterar a dependência
fileall
defilefwd
parafile
, agorafileall
não será reconstruído todas as vezes, mas apenas quando algum dos destinos dependentes estiver obsoleto como um arquivo.fonte
O alvo especial
.PHONY:
permite declarar alvos falsos, para quemake
não os verifique como nomes de arquivo reais: funcionará o tempo todo, mesmo que esses arquivos ainda existam.Você pode colocar vários
.PHONY:
em seuMakefile
:Existe outra maneira de declarar alvos falsos: basta colocar '::'
O '::' tem um significado especial: os alvos são falsos e podem aparecer várias vezes:
Os blocos de comando serão chamados um após o outro.
fonte
Costumo usá-los para dizer ao alvo padrão para não disparar.
Sem FALSO,
make superclean
iria dispararclean
,andsomethingelse
ecatcher superclean
; mas com PHONY,make superclean
não vai disparar ocatcher superclean
.Não precisamos nos preocupar em dizer que o
clean
alvo é PHONY, porque não é completamente falso. Embora nunca produza o arquivo limpo, ele possui comandos para acionar, portanto, o make pensará que é um alvo final.No entanto, o
superclean
alvo é realmente falsa, então make vai tentar empilhar-lo com qualquer outra coisa que fornece deps para osuperclean
alvo - o que inclui outrassuperclean
metas e o%
alvo.Note que não dizemos nada sobre
andsomethingelse
oublah
, então eles claramente vão para o coletor.A saída é mais ou menos assim:
fonte