O que @: (no símbolo dois pontos) significa em um Makefile?

155

O que o seguinte faz em um Makefile?

rule: $(deps)
    @:

Não consigo encontrar isso no manual do make.

cdwilson
fonte

Respostas:

206

Significa "não faça eco deste comando na saída". Portanto, esta regra está dizendo "execute o comando shell :e não faça eco da saída.

É claro que o comando shell :é um no-op, então isso está dizendo "não faça nada e não conte".

Por quê?

O truque aqui é que você tem uma combinação obscura de duas sintaxes diferentes. A sintaxe make (1) é o uso de uma ação iniciada por @, que simplesmente não é para ecoar o comando. Então, uma regra como

always:
       @echo this always happens

não vai emitir

   echo this always happens
   this always happens

Agora, a parte de ação de uma regra pode ser qualquer comando do shell, inclusive :. A ajuda do Bash explica isso, assim como em qualquer lugar:

$ help :
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.
Charlie Martin
fonte
21
Não tire sarro da minha digitação, você também ficará velho um dia.
Charlie Martin
4
Esta é uma excelente explicação do que isso faz, mas você sabe por que você faria isso em um makefile?
Charles Keepax 13/10/12
8
Não é o mais nebuloso.
Charlie Martin
2
Pode ser útil em makefiles que exigem uma grande quantidade de programas externos, e onde você quiser usar eco muito para torná-la agradável, como este
dwcoder
1
@ charles-keepax, se você está perguntando especificamente em referência a @:(não apenas @), além da resposta do @ guestolio, também pode ser um restante do desenvolvimento. É como escrever uma função em Python que contém apenas pass. Pode ser útil para remover blocos de código para copiar / colar, mas eles geralmente não devem existir por muito tempo. Quando arrancar desta forma o arquivo ainda seria compilar, linting passagem, etc.
boweeb
40

Para aqueles curiosos sobre o motivo de fazer isso, é útil se você quiser fingir que algo foi feito, para que o Make não produza "Nada a ser feito" para o seu destino.

Um exemplo é se você tem um alvo falso que você sempre executa, e nele há um monte de condicionais no comando. Você deseja ter pelo menos alguma coisa, caso essas condições sejam falsas e nada seja feito.

Por exemplo (dos scripts do Linux / Makefile.clean):

__clean: $(subdir-ymn)
ifneq ($(strip $(__clean-files)),)
    +$(call cmd,clean)
endif
ifneq ($(strip $(__clean-dirs)),)
    +$(call cmd,cleandir)
endif
ifneq ($(strip $(clean-rule)),)
    +$(clean-rule)
endif
    @:
Guestolio
fonte