¿Cómo incluir un archivo MAKE en otro archivo MAKE?

¿Cómo incluir un archivo MAKE en otro archivo MAKE?

Estoy bastante seguro de que eso no es posible. Sus archivos MAKE deben ser independientes, en cuyo caso puede hacer que los archivos de nivel superior invoquen make en directorios de nivel inferior de forma recursiva (así que no include ellos) o puede tener un único archivo MAKE no recursivo formado al incluir otros archivos MAKE. No creo que sea posible hacer ambas cosas.

La única respuesta válida es "usando el include directiva" (aparte del habitual "depende".) Cualquier otro consejo depende de la estructura de los archivos MAKE. Archivos MAKE diseñados ser incluido obviamente será más fácil de incluir. Solo incluir un archivo MAKE aleatorio y esperar que funcione ... no funcionará. Consulte Implementación de make no recursivo y Boilermake para saber cómo hacer que funcionen los archivos MAKE no recursivos.

Tenga en cuenta que no es necesario incluirlos en la parte superior del archivo y hacerlo puede ser una mala idea, ya que el destino predeterminado se convierte en el primero en el archivo incluido.


Gracias a @Jonathan-wakely por brindar los conceptos iniciales para esta solución.

Probablemente hay muchas cosas que se pueden mejorar, pero funciona.

Resumen de requisitos:

  • Los Makefiles deberían funcionar de forma independiente
  • El makefile principal incluirá sub-makefiles
  • No debería aparecer ningún conflicto o problema de ruta.

Una solución simple es llamar recursivamente a los archivos MAKE:

  • Cree un script "normal" para archivos MAKE de hoja
  • Uso de un objetivo vacío permitir ejecutar siempre realizar llamadas, por ejemplo, "sub-make:" sin ningún requisito después de ":"
  • Use el "-C " parámetro para establecer el directorio raíz para realizar la llamada.
  • Cree el enlace final con archivos binarios creados por sub-makefiles.

Ejemplo para el makefile principal:

#all make recursive calls
sub-make:
    make -C Vector3D
    make -C Color

#final linking
CPP      = g++
FLAGS = $(CXXINCS) -Wall -O0

all: main

main: main.o Vector3D/Vector3D.o Color/Color.o
    $(CPP) main.o Vector3D/Vector3D.o Color/Color.o -o main

main.o: main.cpp
    $(CPP) -c main.cpp -o main.o $(FLAGS)

Probablemente haya una mejor manera de proporcionar binarios *.o al enlazador sin escribir toda la ruta completa, pero ese es otro problema.

Creando el objetivo limpio. Para los archivos MAKE de hoja, no hay que tomar consideraciones especiales, pero para el archivo MAKE principal, debe invocar reglas de sublimpieza.

clean:
    make -C Vector3D clean
    make -C Color clean
    rm -f *.o main

EDICIÓN:

Aquí está la estructura del archivo MAKE que he hecho, por si le puede ser útil a alguien.

Para trabajar, todas las clases deben estar en su propia carpeta con:

  • Encabezado .hpp
  • código .cpp
  • main.cpp para pruebas
  • El directorio de clases requeridas (LIBS) se especifica con "$(LIBSPATH)LibName" en relación con este archivo MAKE.

Makefile

#Following configuration may be set with a parameter:
#   e.g: make FLAGS="-Wall -O0"
FLAGS = $(CXXINCS) -Wall -O0

#Configurable variables
EXEC     = main
CLASS    = World
LIBS     = Color Vector3D Triangle
LIBSPATH = ../

#Static content
CPP      = g++
OBJS     = $(foreach dir, $(LIBS), $(LIBSPATH)$(dir)/$(dir))

all: $(EXEC)

clean: 
    rm -f *.o $(EXEC)
    $(foreach dir,$(LIBS),make clean --no-print-directory -C $(LIBSPATH)$(dir);)

$(EXEC): $(CLASS).o $(EXEC).o $(OBJS:=.o)
    $(CPP) $(CLASS).o $(OBJS:=.o) $(EXEC).o -o $(EXEC)

$(EXEC).o: $(EXEC).cpp
    $(CPP) -c $(EXEC).cpp -o $(EXEC).o $(CXXFLAGS)

$(CLASS).o: $(CLASS).cpp $(CLASS).hpp
    $(CPP) -c $(CLASS).cpp -o $(CLASS).o $(CXXFLAGS)

$(OBJS:=.o): $(OBJS:=.cpp) $(OBJS:=.hpp)
    make --no-print-directory -C $(LIBSPATH)$(strip $(foreach dir,$(LIBS),$(if $(findstring $(dir),[email protected]),$(dir))))