La forma tradicional es tener un Makefile
en cada uno de los subdirectorios (part1
, part2
, etc.) lo que le permite construirlos de forma independiente. Además, tenga un Makefile
en el directorio raíz del proyecto que construye todo. La "raíz" Makefile
sería algo como lo siguiente:
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
Dado que cada línea en un destino de creación se ejecuta en su propio shell, no hay necesidad de preocuparse por recorrer el árbol de directorios o a otros directorios.
Sugiero echar un vistazo a la sección 5.7 del manual de creación de GNU; es muy útil.
Puede agregar reglas a su Makefile raíz para compilar los archivos cpp necesarios en otros directorios. El siguiente ejemplo de Makefile debería ser un buen comienzo para llevarlo a donde quiere estar.
CC=g++ TARGET=cppTest OTHERDIR=../../someotherpath/in/project/src SOURCE = cppTest.cpp SOURCE = $(OTHERDIR)/file.cpp ## End sources definition INCLUDE = -I./ $(AN_INCLUDE_DIR) INCLUDE = -I.$(OTHERDIR)/../inc ## end more includes VPATH=$(OTHERDIR) OBJ=$(join $(addsuffix ../obj/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.o))) ## Fix dependency destination to be ../.dep relative to the src dir DEPENDS=$(join $(addsuffix ../.dep/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.d))) ## Default rule executed all: $(TARGET) @true ## Clean Rule clean: @-rm -f $(TARGET) $(OBJ) $(DEPENDS) ## Rule for making the actual target $(TARGET): $(OBJ) @echo "=============" @echo "Linking the target [email protected]" @echo "=============" @$(CC) $(CFLAGS) -o [email protected] $^ $(LIBS) @echo -- Link finished -- ## Generic compilation rule %.o : %.cpp @mkdir -p $(dir [email protected]) @echo "=============" @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o [email protected] ## Rules for object files from cpp files ## Object file for each file is put in obj directory ## one level up from the actual source directory. ../obj/%.o : %.cpp @mkdir -p $(dir [email protected]) @echo "=============" @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o [email protected] # Rule for "other directory" You will need one per "other" dir $(OTHERDIR)/../obj/%.o : %.cpp @mkdir -p $(dir [email protected]) @echo "=============" @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o [email protected] ## Make dependancy rules ../.dep/%.d: %.cpp @mkdir -p $(dir [email protected]) @echo "=============" @echo Building dependencies file for $*.o @$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^../obj/$*.o^" > [email protected]' ## Dependency rule for "other" directory $(OTHERDIR)/../.dep/%.d: %.cpp @mkdir -p $(dir [email protected]) @echo "=============" @echo Building dependencies file for $*.o @$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^$(OTHERDIR)/../obj/$*.o^" > [email protected]' ## Include the dependency files -include $(DEPENDS)
La opción VPATH puede resultar útil, ya que le dice a make en qué directorios buscar el código fuente. Sin embargo, aún necesitaría una opción -I para cada ruta de inclusión. Un ejemplo:
CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src
OutputExecutable: part1api.o part2api.o part3api.o
Esto encontrará automáticamente los archivos partXapi.cpp correspondientes en cualquiera de los directorios especificados por VPATH y los compilará. Sin embargo, esto es más útil cuando su directorio src está dividido en subdirectorios. Por lo que describe, como han dicho otros, probablemente esté mejor con un archivo MAKE para cada parte, especialmente si cada parte puede ser independiente.
Si tiene código en un subdirectorio que depende del código en otro subdirectorio, probablemente esté mejor con un único archivo MAKE en el nivel superior.
Consulte Recursive Make Considered Harmful para obtener la justificación completa, pero básicamente desea que make tenga la información completa que necesita para decidir si un archivo necesita ser reconstruido o no, y no tendrá eso si solo le dice alrededor de un tercio de tu proyecto.
El enlace de arriba parece no ser accesible. El mismo documento está disponible aquí:
- aegis.sourceforge.net (archivado)
- lcgapp.cern.ch