Probar una regla Makefile como la siguiente no funcionó (GNU Make 4.0):
foo: [email protected] other.o
bar: bar.o other.o
El archivo foo.c
fue compilado (en foo.o
), pero el comando de enlace era cc -o .o
.
Por el contrario, bar
se compiló y vinculó correctamente como cc bar.o other.o -o bar
.
¿Quién puede explicar la diferencia (o el problema)?
Respuesta1
Esto se aborda en la sección sobreVariables automáticasen el manual GNU Make:
Es muy importante que reconozca el alcance limitado en el que están disponibles los valores de variables automáticas: solo tienen valores dentro de la receta. En particular, no puede utilizarlos en ningún lugar dentro de la lista de objetivos de una regla; no tienen ningún valor allí y se expandirán a la cadena vacía. Además, no se puede acceder a ellos directamente desde la lista de requisitos previos de una regla. Un error común es intentar utilizar
$@
dentro de la lista de requisitos previos; Esto no funcionará.
El resto del párrafo ofrece una posible solución, aunque específica de GNU Make:expansión secundaria. Escribiendo tu Makefile como
.SECONDEXPANSION:
foo: [email protected] other.o
bar: bar.o other.o
permite $$@
que se le dé el valor apropiado, y luego
$ make foo
cc -c -o foo.o foo.c
cc -c -o other.o other.c
cc foo.o other.o -o foo
hace lo que esperas que haga.
(En mi experiencia, normalmente hay mejores formas de abordar un problema que recurrir a una expansión secundaria, pero eso sólo puede determinarse si se comprende el objetivo general de lo que se intenta hacer).