Tentar uma regra Makefile como a seguinte não funcionou (GNU Make 4.0):
foo: [email protected] other.o
bar: bar.o other.o
O arquivo foo.c
foi compilado (para foo.o
), mas o comando do link era cc -o .o
.
Por outro lado, bar
foi compilado e vinculado corretamente como cc bar.o other.o -o bar
.
Quem pode explicar a diferença (ou o problema)?
Responder1
Isto é abordado na seção sobreVariáveis automáticasno manual do GNU Make:
É muito importante que você reconheça o escopo limitado em que os valores das variáveis automáticas estão disponíveis: eles só possuem valores dentro da receita. Em particular, você não pode usá-los em nenhum lugar da lista de destinos de uma regra; eles não têm valor e serão expandidos para a string vazia. Além disso, eles não podem ser acessados diretamente na lista de pré-requisitos de uma regra. Um erro comum é tentar usar
$@
dentro da lista de pré-requisitos; isso não funcionará.
O restante do parágrafo fornece uma solução possível, embora específica do GNU Make:expansão secundária. Escrevendo seu Makefile como
.SECONDEXPANSION:
foo: [email protected] other.o
bar: bar.o other.o
permite $$@
receber o valor apropriado e, em seguida,
$ make foo
cc -c -o foo.o foo.c
cc -c -o other.o other.c
cc foo.o other.o -o foo
faz o que você espera que faça.
(Na minha experiência, geralmente existem maneiras melhores de resolver um problema do que recorrer à expansão secundária, mas isso só pode ser determinado pela compreensão do objetivo geral do que você está tentando fazer.)