tutorial make create makefile gnu-make

create - makefile linux c



¿Cuál es la diferencia entre las asignaciones de variables Makefile de GNU=,?=,:=Y+=? (5)

Conjunto perezoso

VARIABLE = value

Configuración normal de una variable: los valores dentro de ella se expanden recursivamente cuando se usa la variable, no cuando se declara

Conjunto inmediato

VARIABLE := value

Configuración de una variable con una simple expansión de los valores internos: los valores dentro de ella se expanden en el momento de la declaración.

Establecer si está ausente

VARIABLE ?= value

Configuración de una variable solo si no tiene un valor

Adjuntar

VARIABLE += value

Anexando el valor suministrado al valor existente (o configurándolo a ese valor si la variable no existía)

¿Alguien puede dar una explicación clara de cómo la asignación de variables realmente funciona en Makefiles?

Cuál es la diferencia entre :

VARIABLE = value VARIABLE ?= value VARIABLE := value VARIABLE += value

He leído la section en el manual de GNU Make, pero todavía no tiene sentido para mí.


Cuando usa VARIABLE = value , si el value es en realidad una referencia a otra variable, entonces el valor solo se determina cuando se usa VARIABLE . Esto se ilustra mejor con un ejemplo:

VAL = foo VARIABLE = $(VAL) VAL = bar # VARIABLE and VAL will both evaluate to "bar"

Cuando usa VARIABLE := value , obtiene el valor de value como está ahora . Por ejemplo:

VAL = foo VARIABLE := $(VAL) VAL = bar # VAL will evaluate to "bar", but VARIABLE will evaluate to "foo"

Usar VARIABLE ?= val significa que solo establece el valor de VARIABLE si VARIABLE no está configurado ya. Si aún no está establecido, la configuración del valor se aplaza hasta que se usa VARIABLE (como en el ejemplo 1).

VARIABLE += value solo agrega value a VARIABLE . El valor real del value se determina como estaba cuando se estableció inicialmente, utilizando = o := .


En las respuestas anteriores, es importante comprender qué se entiende por "los valores se expanden en el momento de la declaración / uso". Dar un valor como *.c no implica ninguna expansión. Es solo cuando esta secuencia es utilizada por un comando que puede desencadenar algunos globos. De manera similar, un valor como $(wildcard *.c) o $(shell ls *.c) no implica ninguna expansión y se evalúa completamente en el momento de la definición, incluso si usamos := en la definición de la variable.

Pruebe el siguiente Makefile en el directorio donde tiene algunos archivos C:

VAR1 = *.c VAR2 := *.c VAR3 = $(wildcard *.c) VAR4 := $(wildcard *.c) VAR5 = $(shell ls *.c) VAR6 := $(shell ls *.c) all : touch foo.c @echo "now VAR1 = /"$(VAR1)/"" ; ls $(VAR1) @echo "now VAR2 = /"$(VAR2)/"" ; ls $(VAR2) @echo "now VAR3 = /"$(VAR3)/"" ; ls $(VAR3) @echo "now VAR4 = /"$(VAR4)/"" ; ls $(VAR4) @echo "now VAR5 = /"$(VAR5)/"" ; ls $(VAR5) @echo "now VAR6 = /"$(VAR6)/"" ; ls $(VAR6) rm -v foo.c

La ejecución de make activará una regla que crea un archivo C adicional (vacío), llamado foo.c pero ninguna de las 6 variables tiene foo.c en su valor.


Te sugiero que hagas algunos experimentos usando "make". Aquí hay una demostración simple, que muestra la diferencia entre = y := .

/* Filename: Makefile*/ x := foo y := $(x) bar x := later a = foo b = $(a) bar a = later test: @echo x - $(x) @echo y - $(y) @echo a - $(a) @echo b - $(b)

make test impresiones de make test :

x - later y - foo bar a - later b - later bar

Ver explicación más elaborada aquí.


Usar = hace que a la variable se le asigne un valor. Si la variable ya tenía un valor, se reemplaza. Este valor se expandirá cuando se use. Por ejemplo:

HELLO = world HELLO_WORLD = $(HELLO) world! # This echoes "world world!" echo $(HELLO_WORLD) HELLO = hello # This echoes "hello world!" echo $(HELLO_WORLD)

Usar := es similar a usar = . Sin embargo, en lugar de expandir el valor cuando se usa, se expande durante la asignación. Por ejemplo:

HELLO = world HELLO_WORLD := $(HELLO) world! # This echoes "world world!" echo $(HELLO_WORLD) HELLO = hello # Still echoes "world world!" echo $(HELLO_WORLD) HELLO_WORLD := $(HELLO) world! # This echoes "hello world!" echo $(HELLO_WORLD)

Usando ?= Asigna un valor a la variable si la variable no fue asignada previamente. Si a la variable se le asignó previamente un valor en blanco ( VAR= ), creo que todavía se considera un conjunto. De lo contrario, funciona exactamente como = .

Usar += es como usar = , pero en lugar de reemplazar el valor, el valor se agrega al actual, con un espacio en el medio. Si la variable se estableció previamente con := , creo que se expandió. El valor resultante se expande cuando se usa , creo . Por ejemplo:

HELLO_WORLD = hello HELLO_WORLD += world! # This echoes "hello world!" echo $(HELLO_WORLD)

¡Si algo como HELLO_WORLD = $(HELLO_WORLD) world! se usaron, se produciría una recursión, lo que probablemente terminaría con la ejecución de su Makefile. Si se utilizara A := $(A) $(B) , el resultado no sería exactamente el mismo que usar += porque B se expande con := mientras que += no causaría que B se expanda.