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
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.
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%.csrc
eingefügt. Kompilieren funktioniert aber beim Linken hat er glaub ich
seine Probleme
1
make.exe:***[main.elf]Error1
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
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
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
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
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.
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.
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.