Forum: Compiler & IDEs Makefile: mehrere Ordner angeben


von spyder (Gast)


Lesenswert?

Hallo!

Ich möchte in meinen Projekten nicht immer oft gebrauchte Dateien, wie 
z.B. "uart.h", "uart.c", "lcd.h", "lcd.c" etc. einzeln aus den 
jeweiligen Ordnern, wo diese liegen, in meinen aktuellen Proejktordner 
kopieren. Außerdem kann ich dann Änderungen in dieser Datei (z.B. 
"lcd.c") zentral in einem Ordner machen und alle Projekte, die diese 
verwenden, müssen bloß neu kompiliert werden.  Wie kann ich im Makefile 
bekanntgeben, dass er diese  Dateien in einem anderen Ordner suchen 
soll? Geht das vielleicht unter dem Punkt EXTRAINCDIRS im Makefile? Ich 
hab das nämlich schon so
1
EXTRAINCDIRS = "C:\dev\Atmega8\mycode\LCDlib\"
 probiert aber es kommt da nur die "No rule to make 
target"-Fehlermeldung beim kompilieren.

Vielen Dank schon mal

lg, spyder

von Günter -. (guenter)


Lesenswert?

Das geht mit vpath, bzw. VPATH.

VPATH gibt an das make neben dem aktuellen Pfad, von dem es aus 
aufgerufen wurde, auch in dem spezifizierten Pfad nach Dateien suchen 
soll. Dabei können mehrere Pfade, leerzeichengetrennt angegeben werden. 
Also z.B.:

VPATH src include

Suche noch in den Pfad ./src und ./include nach Dateien.

Wenn es spezieller sein soll, dann kann mit vpath noch ein Dateimuster 
angegeben werden. Also z.B.:

vpath %.c src
vpath %.h include

Sucht in ./src nach .c-Files und in ./include nach .h-Files.

von spyder (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Günter!

Ich habe einmal testweise einen Ordner "src" in meinem 
Projektverzeichnis erstellt und dort die "lcd-routines.c" reingegeben. 
Im Makefile hab ich dann
1
vpath %.c src
 eingefügt. Kompilieren funktioniert aber beim Linken hat er glaub ich 
seine Probleme
1
make.exe: *** [main.elf] Error 1
 An was könnte das liegen? Und könntest du mir genau aufschreiben, wie 
ich mittels vpath dateien aus den anderen ordner einbinden kann. Meine 
Verzeichnisstruktur sieht so aus:

          |----------------------------------------
          |                    |                  |
aktueler Projektordner      LCD-Library       UART-Library
          |                     |                  |
       Makefile            lcd.c, lcd.h       uart.c, uart.h


lg, spyder

von Peter D. (peda)


Lesenswert?

spyder wrote:
> Ich möchte in meinen Projekten nicht immer oft gebrauchte Dateien, wie
> z.B. "uart.h", "uart.c", "lcd.h", "lcd.c" etc. einzeln aus den
> jeweiligen Ordnern, wo diese liegen, in meinen aktuellen Proejktordner
> kopieren.

Ich hab früher auch immer meine Bibliotheken zentral gehalten, bis ich 
einmal furchtbar drauf reingefallen bin.
Man hat ja immer mal was dran zu erweitern, zu verbesseren oder Bugs zu 
beheben.
Und dann mußte ich schnell mal ein altes Projekt neu compilieren und 
nichts funktionierte mehr.

Seitdem kriegt jedes Projekt seine zu dem Zeitpunkt funktionierende 
Bibliothek mit reinkopiert.

Es ist außerdem keine dumme Idee, sich auch die benutzte Compilerversion 
mit aufzuheben.


Peter

von shanokee (Gast)


Lesenswert?

Hi,

für ein aktuelles Projekt wäre es für mich extrem nützlich, könnte ich 
dem Makefile beibringen, auch Dateien aus einem anderen Ordner zu 
verwenden. Doch leider hat meine intensive Recherche nicht ergeben, wie 
ich das korrekt mache. Ich will einfach nur die die .c- und .h-Dateien 
in einen Ordner legen, der auf der gleichen Höhe wie der aktuelle Ordner 
ist. Also quasi ../zweiterOrdner. Kann mir jemand helfen?

Danke und mfG

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wenn es denn vpath sein soll oder VPATH und keine Kopie:

http://www.gnu.org/software/make/manual/make.html#Directory-Search

von Maruks S (Gast)


Lesenswert?

Hallo,

eigentlich ist das kein größeres Problem wenn man ein Projekt aus 
verschiedenen Source-Ordnern zusammen bauen will.
Da gibt es verschiedenen Möglichkeiten.
Eine Möglichkeit ist diese, dass man einen Hauptmakefile und jeweils 
einen Makefile in den jeweiligen Sourceordnern benutzt. Der 
Hauptmakefile ruft nun die Makefiles in den Sourceordnern auf.

Die nächste Möglichkeit besteht darin ein Makefile zu verwenden, der 
dann die Sourcen aus den verschiedenen Ordnern mit einbindet.

Hier kommt ein Auszug aus meinem letzten Projekt, das dass prinzipielle 
Vorgenen zeigt:

SRC =   .\Applications\main.c \
    .\Applications\timer.c \
    .\System\vectors.c \
    .\System\System.c \
    .\Moduls\TaskMgr\scheduler.c \
    ....weitere Files


COBJS     = $(addsuffix .o, $(basename $(SRC)))

# Default target.
all: begin dirs build finished end

build:   $(COBJS) $(DIR_BIN)\$(TARGET)
  @echo
  @echo "End"

# Compiling Sources
%.o:%.c
  @echo $(MSG_COMPILING) $< ...
  $(CC) $(CFLAGS) $(@:.o=.c) -o $@


Nun das oben ist ein Auszug. Mit dem Makefile habe ich verschiedene 
Compiler verwendet, je nach Projekt verwende ich entweder den GCC oder 
Fujitsu Compiler.


Gruss

Markus S

von Michael Z. (incunabulum)


Angehängte Dateien:

Lesenswert?

Ich bin auch so ein Freund eines zentralen Bilbiotheksverzeichnisses. 
BundleMan mit SVN hilft dabei, bei Änderungen an der zentralen 
Bibliothek auch später noch lauffähige Versionen für die Projekte zu 
bekommen.

Ich häng dir mal ein Makefile an, wie es hier zum Einsatz kommt. Im 
Prinzip angepasst werden muss:

- VPATH + EXTRAINCDIRS: wo liegen ausserhalb des aktuellen 
Verzeichnisses noch Source-Files?
- SRC, CPPSRC: Welche Dateien sollen verwendet werden, logisch
- SUBDIRS: Verzeichnisse, in denen Dateien liegen. Dies wird benötigt, 
da dep-files, build-files und object files in getrennt vom Code 
generiert werden und ich hierfür die Ordnerstruktur in den 
build-Verzeichnissen generieren muss.

von Norgan (Gast)


Lesenswert?

Zu VPATH sollte man vielleicht sagen, dass es ein paar Nachteile hat.

VPATH sucht nach Dateien, das bedeutet, es wird die erste Datei 
genommen, die irgendwo im VPATH rumliegt. Ob das die richtige ist, weiß 
VPATH nicht. Baut man mal irgendwann das Verzeichnis um, so findet VPATH 
eventuell eine andere Datei mit gleichem Namen. Das macht es fast 
unmöglich irgendwann später (Wochen, Monate) nachzuvollziehen, womit 
eine bestimmte Softwareversion denn wirklich gebaut wurde. Es war halt 
eine Datei, die damals(TM) irgendwo im VPATH rumlag.

Archiviert man ein Projekt, sollte man daher tunlichst auch alle 
Verzeichnisse die in VPATH auftreten mit archivieren. Nur, dann kann man 
die richtigen Dateien auch von vorneherein ins Projektverzeichnis 
kopieren.

Wenn einem Reproduzierbarkeit wichtig ist (professionelles Umfeld), dann 
Finger weg von VPATH: bequem aber Scheiße.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

In meinen Projekten erzeuge ich von den Dateien im Quell-Fundus echte 
Kopien:
1
COMMON_FILES = file-1.c file-2.h ...
2
COMMON_DIR   = ...
3
4
$(COMMON_FILES): % : $(COMMON_DIR)/%
5
  cp $< $@

Wenn also das Objekt zu file-1.o zu erzeugen ist, weiß make, daß es von 
file-1.c abhängt. Und f+r file-1.c ist eine Regel angegeben, wie es zu 
erzeugen ist: es wir einfach kopiert.

Zu beachten ist lediglich, daß zur Erstellung der Dependencies die 
Kopien bereis vorhanden sein müssen.

Mit der lokalen Kopie kann man rumexperimentieren und sie verändern. Sie 
wird erst überschrieben, wenn sich die Version im Quell-Archiv ändert 
und damit neuer wird als die lokale Kopie.

Beim Archivieren des Projekts werden immer alle Quellen mit 
hinzugenimmen, die für einen Build notwendig sind. Also auch die lokalen 
Kopien bzw. der jeweilige Stand der jeweils benötigten Quelle im 
Quell-Archiv.

Alternativ referenziert man die SVN-Version, falls man eine 
Versionskontrolle fährt.

Je nachdem, ob man die lokalen Kopien behalten will oder gleich nach dem 
Build wieder in die Tonne treten will, kann man sie kennzeichnen mit 
.PRECIOUS oder .INTERMEDIATE

Das Kopieren ist auch dann angesagt, wenn ein C-Modul aus dem Archiv 
kommt, ein Header aber mit #include "file.h" includet wird. Dann soll 
der Header nämlich aus dem momentane Projekt genommen werden und nicht 
aus dem Archiv.

Solch ein Beispiel ist zB ein Countdown-Zähler, mit dem ich in praktisch 
all meinen Projekten Zeitbasen erzeuge:

Die countdown.c ist für alle Projekte gleich und operiert auf einer in 
countdown.h definierten Struktur. Die countdown.h enthält die Struktur 
mit den 10 ms, 1s, 1min Zählern die runter zu zählen sind, und diese 
sind in jedem Projekt anders.

Ins Quellarchiv sollte man generell nur Quellen aufnehmen, die sich in 
mehreren Projekten bewährt haben und damit hinreichend getestet und 
allgemeingültig sind. Falls dennoch mal eine Quelle im Archiv anzupassen 
ist, geht das meistens aufwärtskompatibel.

Aber prinzipiell hat man mit einem Quell-Fundus das gleiche Problem wie 
mit sich ändernden Bibliotheken wenn sich darin ein Interface ändert 
oder die Spezifikation einer Implementierung.

Allerdings hat man weit mehr Potential zur Optimierung und spart sich 
die teilweise recht umständlichen Build- und Update-Prozesse einer 
Bibliothek, von Multilibs für verschiedene Derivat-Familien ganz zu 
schweigen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.