Dos o tres cosas más que posiblemente no sepas sobre GNU make

Algunas reglas definidas en un Makefile https://github.com/geneura-papers/2015-GPUS/blob/master/makefile

Después de estas primeras reglas, me han surgido bastantes más que puede venir bien usar en la vida diaria. make ha evolucionado muchísimo en sus muchos años de vida y ahora permite trabajar de forma muy flexible con todo tipo de ficheros. Vamos a ver qué más cosas se pueden hacer con él.

Meter en una variable todos los ficheros con una extensión

Los comodines como * son del intérprete de la línea de órdenes, así que cosas como

cfiles = *.c

no va a funcionar. Para eso está la orden wildcard:

$(MAKEFILES) va a contener los nombres de todos los ficheros con la extensión .mk. Para verlos, usamos un par de trucos más de Makefile: con el ; podemos poner directamente una orden tras el objetivo, count en este caso. Además, si ponemos @ delante esa orden no aparecerá en la línea de órdenes cuando ejecutemos el Makefile. El resultado:

Ejecutando el makefile en make-is-fun http://github.com/JJ/make-is-fun

Convirtiendo nombres de ficheros para crear objetivos

Lo más normal es que se trate de hacer algo en concreto con esos ficheros. Por ejemplo, ejecutarlos, o, en la mayor parte de los casos, procesarlos para dar algún otro tipo de fichero. Podemos escribir a mano el nombre de los mismos, o podemos dejar que make lo haga.

Aparte de la orden wildcard que ya hemos visto, usamos los operadores de tratamiento de cadenas implícitos de Make. Unos simples : te indican que la extensión que hay a la izquierda del = se tiene que sustituir por la que hay a la derecha.

O podemos hacerlo de una sola pasada

El resultado es exactamente el mismo, pero si no vamos a usar la variable inicial, con esto creamos simplemente una variable $(HTML) que contiene los nombres de ficheros en los que se van a convertir los que tenemos. patsubst es la orden de Make a la que se le pasa primero las extensiones que se van a substituir separadas por coma, y como último parámetro los nombres de todos los ficheros, generados como antes. El resultado será

Ejecutándolo sobre el repo habitual

Escogiendo diferentes programas según si están o no.

Finalmente habrá que hacer algo con los ficheros en el Makefile. Por ejemplo, usar pandoc para generar html

También aquí usamos un nuevo formato de regla. Tenemos que generar todos los HTML que necesitemos, pero en la regla le indicamos que para generar un HTML necesitamos el markdown correspondiente.

Generando todos los ficheros si están modificados

Este Makefile generará los HTML sólo si se han modificado los markdown, que es el caso. Pero estamos suponiendo que está pandoc instalado; no es una herramienta estándar y puede que todavía no se haya instalado. Y ¿qué ocurre si es otra herramienta la instalada, tal como markdown-html?

Algunos programas como CMake o Configure se usan de forma habitual para generar Makefiles dependiendo de lo que esté, o no, presente en el sistema. Sin embargo, el propio Make tiene también cierta capacidad de configuración automática, pudiendo escoger el programa que se va a usar. make en realidad tiene su propio mini-lenguaje, que le permite tomar este tipo de decisiones. En concreto, puede usar if como aquí:

shell es también una orden de Make que te ejecuta una orden del shell. En este caso, usa command que devolverá una cadena nula si no existe tal orden.

Diferentes resultados de ejecutar command sobre las dos órdenes para generar HTML desde markdown

La orden ifneq es de Make, por eso comienza en la primera columna, no tras un tabulador como la que efectivamente se ejecuta. Esa sequencia primero comprobará si existe pandoc, si es así lo ejecutará. Si no, pasará a la comprobación siguiente: ¿está instalado markdown-html? Lo ejecutará si es así. Y si no, pues no se puede hacer gran cosa. Se sale y no se ejecuta nada.

Además, ambas órdenes usan las variables de make, $< (que es el fichero de entrada) y $@, que es el fichero de salida. Los nombres de los ficheros de entrada se generarán con la regla de sustitución %.html: %.md. Esto permite reusar este tipo de makefile en cualquier situación en los que tengamos que generar HTML desde Markdown, como cuando se esté trabajando en un tutorial, un libro o lo que sea.

Conclusiones

Los Makefiles cuanto más genéricos, mejor. Se pueden reusar fácilmente y una vez que uno tenga una panoplia de ficheros para varias circunstancias, es sólo cuestión de copiarlos al directorio correspondiente.

Aunque primitivos, los Makefiles han tenido un gran recorrido y lo seguirán teniendo. Y aprender unos cuantos trucos básicos te ahorrará teclear un montón con lo que podrás dedicarte a lo que verdaderamente te gusta, que es teclear un montón.