GNU/Linux >> Tutoriales Linux >  >> Linux

Makefiles con archivos fuente en diferentes directorios

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

Linux
  1. Encuentra archivos y directorios en Linux con el comando de búsqueda

  2. Copiar archivos y directorios en Linux

  3. ¿Archivos Cat con directorio?

  4. ¿Encontrar archivos o directorios más grandes?

  5. CloudCross:sincronice archivos y directorios con múltiples almacenamientos en la nube

Cómo excluir archivos y directorios con Rsync

Cómo comprimir archivos y directorios en Linux (con ejemplos)

Crear directorios o archivos nombrados con fecha/hora/mes/año actual

Mantener los archivos y directorios de Linux sincronizados con rsync

Conceptos básicos de la línea de comandos de Linux:trabajar con archivos y directorios

¿Archivos con el mismo contenido pero con diferentes md5sums cuando gzip'd?