Sabores de variables en Make
10 de marzo de 2023
Las variables en GNU Make funcionan un poco diferente a las de otros lenguajes. Primero, Make no es tan estricto con el contexto dónde se usan las variables. Y segundo, hay dos versiones, o sabores, de variables: las de evaluación inmediata y evaluación aplazada.
Sustituciones de variables
No pienses de Make en términos de lenguajes de programación como C++ o Python. Make tiene más en común con un motor de plantillas, como Mustache.
Al usar una variable en un Makefile
, se hace una sustitución muy simple.
Básicamente, sería como si abrieras un editor de texto y hicieras un “buscar y
reemplazar todo” a un archivo. No se toma en cuenta el contexto de la variable.
La primera lectura de un Makefile
toma esto
nombre_bin := hola
src := $(nombre_bin).c
bin/$(nombre_bin): $(src)
gcc -o $(nombre_bin) $(src)
y lo convierte en esto.
bin/hola: hola.c
gcc -o hola hola.c
Ya en la seguna pasada se ejecuta la receta de la regla.
Asignación simple, evaluación inmediata
Bueno, ya viste la asignación simple en la sección anterior, con el operador
:=
. Esta asignación debería ser la que usas por defecto. Este comportamiento
de asignación es el que se usa en muchos lenguajes de programación.
Aquí el ejemplo de nuevo.
nombre_bin := hola
src := $(nombre_bin).c
bin/$(nombre_bin): $(src)
gcc -o $(nombre_bin) $(src)
Comportamiento: el valor de las variables se evalúa inmediatamente, al momento de la asignación. La evaluación nada más ocurre una vez.
Asignación de expansión recursiva, evaluación aplazada
Otra asignación que existe es la asignación de expansión recursiva, o la que
usa evaluación aplazada. Su operador es =
.
Yo sugiero que casi nunca uses esta asignación. Si la usas, deberías tener una buena razón para hacerlo.
Su uso es parecido a la asignación simple. La diferencia es un su comportamiento.
nombre_bin = hola
src = $(nombre_bin).c
# Espera, voy a cambiar el nombre.
nombre_bin = adiós
bin/$(nombre_bin): $(src)
gcc -o $(nombre_bin) $(src)
Comportamiento: el valor de las variables se evalúa al momento de su uso. El valor se puede calcular cero o muchas veces, dependiendo en cuántas referencias se haga a la variable.
En el ejemplo de arriba, en cada lugar donde se encuentra $(nombre_bin)
o
$(src)
, Make tiene que volver a calcular el valor de las variables.
Resumen
- Make es como un motor de plantillas y hace sustituciones de texto simples
- Usa
:=
para declarar variables