primer - Cómo escribir un Makefile usando diferentes directorios para objetivos y fuentes
makefile ubuntu (1)
El programa bsdmake tiene un muy buen soporte para almacenar los objetivos integrados en un directorio distinto al que contiene las fuentes. Un Makefile
use esta funcionalidad puede ser un poco más difícil de escribir, por lo que revisaré las técnicas más importantes en mi respuesta.
Elegir un directorio para almacenar los objetivos construidos
La variable .OBJDIR
contiene el nombre de un directorio donde se crean los objetivos. Se determina así (extracto de la página man
):
.OBJDIR A path to the directory where the targets are built. Its
value is determined by trying to chdir(2) to the follow‐
ing directories in order and using the first match:
1. ${MAKEOBJDIRPREFIX}${.CURDIR}
(Only if ‘MAKEOBJDIRPREFIX’ is set in the environ‐
ment or on the command line.)
2. ${MAKEOBJDIR}
…
6. ${.CURDIR}
El programa make
will chdir(2)
en .OBJDIR
y establece PWD
en ese directorio antes de ejecutar cualquier objetivo. En ausencia de una preparación adecuada .OBJDIR
es .CURDIR
, por lo tanto, necesitamos crear el directorio deseado - o estructura de árbol - antes de ejecutar make
para construir nuestros objetivos.
Suponga que elige confiar en el primer mecanismo para establecer .OBJDIR
, luego puede organizar su sistema de compilación para que, antes de ejecutar make
para construir sus objetivos,
- La variable de entorno
MAKEOBJDIRPREFIX
se establece en valor adecuado. - Un script especial (puede ser un objetivo de
${MAKEOBJDIRPREFIX}
) prepara el directorio o directorios necesarios bajo${MAKEOBJDIRPREFIX}
.
Arreglos de Makefiles
Consideramos un simple Makefile
y describimos las disposiciones necesarias para que la configuración anterior funcione.
program : a.o b.o c.o
cc a.o b.o c.o -o program
a.o b.o c.o : defs.h
a.o : a.c
cc -c a.c
b.o : b.c
cc -c b.c
c.o : c.c
cc -c c.c
manual.html: manual.css
manual.html: a.c b.c c.c defs.h
manualtool -c manual.css -o manual.html a.c b.c c.c defs.h
Antes de ao
el programa, make
hará chdir(2)
a ${.OBJDIR}
y ejecutará el compilador cc
desde ese directorio. Como la fuente ac
se encuentra en otro directorio, el compilador no la encontrará y la compilación fallará. Este problema se resuelve utilizando las variables locales definidas por make
, por lo make
el Makefile
anterior se traduce en:
program : a.o b.o c.o
cc ${.ALLSRC} -o program
a.o b.o c.o : defs.h
a.o : a.c
cc -c ${.ALLSRC:M*.c}
b.o : b.c
cc -c ${.ALLSRC:M*.c}
c.o : c.c
cc -c ${.ALLSRC:M*.c}
manual.html: manual.css
manual.html: a.c b.c c.c defs.h
manualtool -c ${.ALLSRC:M*.css} -o manual.html ${.ALLSRC:N*.css}
Tenga en cuenta cómo se utilizan los patrones globbing en la última receta para seleccionar adecuadamente las piezas de las fuentes en las diversas ubicaciones de la línea de comandos.
Ejemplos
El sistema de compilación para freebsd , y posiblemente netbsd y openbsd , usa esta funcionalidad para poder construir simultáneamente el sistema operativo para varias arquitecturas. (¡También facilita la limpieza!) Puede estudiar estos Makefiles para obtener una mejor comprensión de las técnicas involucradas.
Mis macros portátiles bsdowl para bdsmake también admiten esta funcionalidad de bsdmake
, puede ver el archivo bps.objdir.mk
y los ejemplos de ocaml .
Estoy escribiendo un Makefile
y me gustaría separar los directorios de compilación y fuente. Mi pensamiento inicial fue solo "Oh, puedo escribir mis reglas anteponiendo la ruta de acceso al nombre del archivo y terminar con esto".
El problema es que esta solución sería súper repetitiva y no se ve muy bien. ¿Cuál sería el mejor enfoque para escribirme un Makefile
que almacena objetivos en un directorio distinto del directorio que contiene mis fuentes?