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 example@unixlinux.online"
@echo "============="
@$(CC) $(CFLAGS) -o example@unixlinux.online $^ $(LIBS)
@echo -- Link finished --
## Generic compilation rule
%.o : %.cpp
@mkdir -p $(dir example@unixlinux.online)
@echo "============="
@echo "Compiling $<"
@$(CC) $(CFLAGS) -c $< -o example@unixlinux.online
## 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 example@unixlinux.online)
@echo "============="
@echo "Compiling $<"
@$(CC) $(CFLAGS) -c $< -o example@unixlinux.online
# Rule for "other directory" You will need one per "other" dir
$(OTHERDIR)/../obj/%.o : %.cpp
@mkdir -p $(dir example@unixlinux.online)
@echo "============="
@echo "Compiling $<"
@$(CC) $(CFLAGS) -c $< -o example@unixlinux.online
## Make dependancy rules
../.dep/%.d: %.cpp
@mkdir -p $(dir example@unixlinux.online)
@echo "============="
@echo Building dependencies file for $*.o
@$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^../obj/$*.o^" > example@unixlinux.online'
## Dependency rule for "other" directory
$(OTHERDIR)/../.dep/%.d: %.cpp
@mkdir -p $(dir example@unixlinux.online)
@echo "============="
@echo Building dependencies file for $*.o
@$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^$(OTHERDIR)/../obj/$*.o^" > example@unixlinux.online'
## 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