cartitas.com

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

Véase también