Aunque a lo largo de este capítulo hemos hecho evolucionar nuestro Makefile ( 3.1.1, pág ) hasta un estado mucho más profesional y elegante ( 3.6.1, pág ), todavía se le pueden aplicar algunas mejoras que nos van a permitir manejarnos cómodamente cuando nos enfrentemos a proyectos mucho más grandes.
Cuando se crean programas complejos es muy habitual que los fuentes se distribuyan por una estructura de directorios, ordenados según su autor, propósito y versión. Es por esto que es muy interesante el poder ejecutar make recursivamente sobre estructuras de directorios, conteniendo cada uno un Makefile independiente, en vez de un único Makefile que lo haga todo.
Por ejemplo, si revisamos nuestro Makefile de la página , vemos cómo algunos de los fuentes necesarios para su compilación están en un directorio específico, en vez de estar en el directorio actual. Esto se preparó intencionadamente desde el principio, argumentando que el programa principal lo haría uno de los miembros del proyecto y las bibliotecas otro. Ésta es una situación muy común en proyectos avanzados de programación.
En la figura 3.1 (pág ) podemos ver un ejemplo de distribución de ficheros de nuestro proyecto, según esto, podríamos crear los siguientes Makefiles:
#Makefile de mi práctica, situado en /home/alcortes/practica1 MI_LIB_DIR = lib/ COMPI_DIR = /home/compañero/lib/ MI_LIB = $(MILIBDIR)mi_biblioteca1.o COMPI_LIB = $(COMPIDIR)mi_biblioteca2.o OBJS = $(MI_LIB) $(COMPI_LIB) mi_programa.o all: mi_ejecutable bibliotecas mi_ejecutable: mi_programa.o bibliotecas $(CC) -o $@ $(OBJS) bibliotecas: cd $(MI_LIB_DIR) ; make all cd $(COMPI_DIR) ; make all prueba: mi_ejecutable bibliotecas mi_script_de_prueba clean: - rm -f *.o - rm -f *~ cd $(MI_LIB_DIR) ; $(make) clean cd $(COMPI_DIR) ; $(make) clean
#Makefile de mi biblioteca, situado en /home/alcortes/practica1/lib all: mi_biblioteca1.o mi_biblioteca1.o: mi_biblioteca1.c $(CC) -c $? clean: - rm -f *.o - rm -f *~
#Makefile de la biblioteca de mi compi situado en /home/compañero/lib all: mi_biblioteca2.o mi_biblioteca2.o: mi_biblioteca2.c $(CC) -c $? clean: - rm -f *.o - rm -f *~
Nótese que para ejecutar make de forma recursiva, no llamamos a make al hacer un cambio de directorio, llamamos a $(make). La diferencia estriba en que $(make) contiene todos aquellos parámetros con los que se llama al make original; si no, estos parámetros no se propagarán por la estructura de directorios.