Las variables en Make son una herramienta fundamental para simplificar y optimizar nuestros Makefiles, permitiéndonos gestionar de forma más eficiente los archivos, definiciones y configuraciones sin necesidad de repetir código constantemente. Al igual que en otros lenguajes de programación, las variables nos permiten asignar un nombre a un valor, facilitando la reutilización y el mantenimiento del código.
Un ejemplo claro de su utilidad es la gestión de los archivos objeto. En lugar de escribir repetidamente la lista completa de archivos .o en diferentes partes del Makefile, podemos agruparlos en una variable, por ejemplo objs, y luego referirnos a ella siempre que necesitemos esa lista. Para declarar una variable en Make, simplemente escribimos su nombre seguido de un signo igual y el valor que queremos asignarle. Por ejemplo:
objs = main.o salida.o calculadora.o
Luego, para usar esta variable, escribimos $ seguido del nombre entre paréntesis:
$(objs)
Esto hace que el Makefile sea mucho más limpio y fácil de modificar, ya que si añadimos o quitamos archivos objeto, solo tendremos que actualizar la variable objs en un único lugar.
Además de variables para archivos, podemos definir otras para elementos como el nombre del programa que queremos generar. Por ejemplo:
binary = mi_programa
Y luego usarla en las reglas correspondientes para compilar o limpiar:
clean:
rm -f $(binary) $(objs)
Un aspecto importante a tener en cuenta es que Make imprime por defecto los comandos que ejecuta, lo que puede resultar en una salida muy verbosa. Para evitar que se muestre el comando en sí y solo su resultado, podemos anteponer una arroba @ al comando:
imprimir:
@echo $(x) $(y)
Esto hace que el comando echo se ejecute silenciosamente, mostrando solo su salida.
En cuanto a las variables, existen dos tipos principales: las de expansión recursiva y las de expansión simple. Las variables de expansión recursiva almacenan una referencia a otra variable y se expanden en el momento en que se utilizan. Esto significa que si cambiamos el valor de una variable referenciada, la variable que la contiene reflejará ese cambio al ser evaluada.
Por ejemplo, si definimos:
x = hola
y = $(x) adiós
Al ejecutar:
make imprimir
y luego cambiamos el valor de x a adiós, la variable y reflejará ese cambio porque se expande recursivamente.
Por otro lado, las variables de expansión simple se expanden en el momento de la asignación, y no cambian aunque modifiquemos las variables que referencian posteriormente. Para declararlas, usamos := en lugar de =:
x := hola
y := $(x) adiós
En este caso, aunque cambiemos el valor de x después, y mantendrá el valor que tenía en el momento de la asignación.
Además de las variables personalizadas, existen variables convencionales muy utilizadas en Makefiles, como CFLAGS y LDFLAGS. CFLAGS se usa para definir las opciones que se pasan al compilador de C, por ejemplo, para activar la generación de información de depuración o mostrar todos los avisos:
CFLAGS = -g -Wall
Por su parte, LDFLAGS se utiliza para especificar opciones del enlazador, como librerías que queremos vincular:
LDFLAGS = -lsdl2 -lsdl2main
Estas variables facilitan la configuración del proceso de compilación y enlace, y son ampliamente reconocidas y utilizadas en proyectos que emplean Make.
Para profundizar en el uso de variables y otras características de Make, la documentación oficial es un recurso imprescindible. Está elaborada por los propios autores de Make y ofrece explicaciones detalladas y claras sobre todos los aspectos del programa, incluyendo capítulos específicos sobre variables, reglas y dependencias. Consultarla nos ayudará a resolver dudas y a aprovechar al máximo las capacidades de Make en nuestros proyectos.