GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Makefiles mit Quelldateien in verschiedenen Verzeichnissen

Der traditionelle Weg ist ein Makefile in jedem der Unterverzeichnisse (part1 , part2 , usw.), sodass Sie sie unabhängig voneinander erstellen können. Außerdem haben Sie eine Makefile im Stammverzeichnis des Projekts, das alles erstellt. Der "Stamm" Makefile würde in etwa so aussehen:

all:
    +$(MAKE) -C part1
    +$(MAKE) -C part2
    +$(MAKE) -C part3

Da jede Zeile in einem make-Target in ihrer eigenen Shell ausgeführt wird, müssen Sie sich keine Gedanken darüber machen, den Verzeichnisbaum oder andere Verzeichnisse zu sichern.

Ich schlage vor, einen Blick in den Abschnitt 5.7 des GNU-Make-Handbuchs zu werfen; es ist sehr hilfreich.


Sie können Ihrem Root-Makefile Regeln hinzufügen, um die erforderlichen cpp-Dateien in anderen Verzeichnissen zu kompilieren. Das folgende Makefile-Beispiel sollte ein guter Anfang sein, um Sie dorthin zu bringen, wo Sie sein möchten.

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)


Die VPATH-Option könnte nützlich sein, die make mitteilt, in welchen Verzeichnissen nach Quellcode gesucht werden soll. Sie benötigen jedoch immer noch eine -I-Option für jeden Include-Pfad. Ein Beispiel:

CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src

OutputExecutable: part1api.o part2api.o part3api.o

Dadurch werden automatisch die passenden partXapi.cpp-Dateien in einem der vom VPATH angegebenen Verzeichnisse gefunden und kompiliert. Dies ist jedoch nützlicher, wenn Ihr src-Verzeichnis in Unterverzeichnisse aufgeteilt ist. Für das, was Sie beschreiben, sind Sie, wie andere gesagt haben, wahrscheinlich besser dran mit einem Makefile für jeden Teil, besonders wenn jeder Teil alleine stehen kann.


Wenn Sie Code in einem Unterverzeichnis haben, der von Code in einem anderen Unterverzeichnis abhängig ist, sind Sie wahrscheinlich mit einem einzigen Makefile auf oberster Ebene besser dran.

Die vollständige Begründung finden Sie unter Rekursives Make gilt als schädlich, aber im Grunde möchten Sie, dass make alle Informationen hat, die es benötigt, um zu entscheiden, ob eine Datei neu erstellt werden muss oder nicht, und das wird es nicht haben, wenn Sie ihm nur etwa ein Drittel davon mitteilen Ihr Projekt.

Der obige Link scheint nicht erreichbar zu sein. Das gleiche Dokument ist hier erreichbar:

  • aegis.sourceforge.net (archiviert)
  • lcgapp.cern.ch

Linux
  1. Größte Dateien oder Verzeichnisse finden?

  2. Dateien durch Lesen ihrer Dateinamen in verschiedene Verzeichnisse verschieben?

  3. Linux – Verschiedene Formate von Objektdateien in Linux?

  4. CloudCross – Synchronisieren Sie Dateien und Verzeichnisse mit mehreren Cloud-Speichern

  5. Vergleichen Sie alle Dateien unter allen verschachtelten Verzeichnissen mit Shell-Globing

So schließen Sie Dateien und Verzeichnisse mit Rsync aus

Erstellen Sie Verzeichnisse oder Dateien, die nach aktuellem Datum / Uhrzeit / Monat / Jahr benannt sind

Linux-Dateien und -Verzeichnisse mit rsync synchron halten

Grundlagen der Linux-Befehlszeile – Arbeiten mit Dateien und Verzeichnissen

Verzeichnisse mit allen Dateien finden, die älter als X sind?

Erstellen Sie einen neuen leeren Verzeichnisbaum aus einem vorhandenen Baum mit Dateien