Hallo,
sicherlich fragt sich der ein oder andere, was diese womöglich einfrache
Frage soll. Ich will es kurz erläutern.
Ich habe mir einige kleine "Bibliotheken" für z.B. UART, I2C,
Taster/LED/LCD, Motortreiber, etc. zusammengestellt.
Hierbei existieren immer ein Header und ein Source-File.
Jetzt nutze ich AVR Studio 5 und möchte diese Bibliotheken nutzen. Eine
Möglichkeit wäre der Import aller benötigter Dateien und dann die
Headerfiles includieren. Hierbei habe ich jedoch das Problem, dass ich
dann in jedem Projekt, welches ich erstelle eine Kopie der
Bibliotheksdateien habe.
Wenn ich jetzt feststelle, dass in einer Bibliothek doch noch ein Fehler
existiert oder ich zusätzliche Funktionen brauche müsste ich alle Kopien
der Bibliotheksdateien ändern. Dies ist ja nicht im Sinne von
Bibliotheken.
Wie kann ich es nun schaffen, dass meine Dateien an einer zentralen
Stelle liegen und ich bei Änderungen durchführen kann.
Da ich ferner alle Daten auf einem SVN speichere, ist doppelter
Datenbestand fatal.
Ich habe auch schon mal gehört, man müsste .lib Dateien mit avr-ar
erzeugen, aber da kenne ich mich noch nicht aus.
Daher bin ich über alle Lösungsvorschläge dankbar.
Ich hoffe ich habe mein Problem einigermaßen schildern können.
Gruß Mike
Zunächst: Arbeite an Deiner Terminologie. Das sind keine Bibliotheken.
Ansonsten dürfte auch die Projektverwaltung des AVR Studio es
ermöglichen, Dateien aus einem anderen Verzeichnis zu einem Projekt
hinzuzufügen.
Um die zugehörigen Headerdateien zu nutzen, musst Du entweder den
globalen Include-Pfad erweitern oder aber bei deren Gebrauch einen
relativen Pfad angeben.
Beispiel:
projekte/allgemeines
bla.c
bla.h
projekte/weltmaschine
main.c
In main.c steht entweder
#include "bla.h"
(wenn der globale Include-Pfad zusätzlich auf "projekte/allgemeines"
verweist)
oder
#include "../allgemeines/bla.h"
Und zu Deinem "weltmaschine"-Projekt musst Du natürlich noch "bla.c"
hinzufügen, was mit der relativen Pfad "../allgemeines/bla.c" auch die
Projektverwaltung des AVR Studio hinbekommen sollte.
Das ganze hat so mit Bibliotheken (Libraries) noch gar nichts zu tun,
und das ist für diese Art der Vorgehensweise auch nicht zwingend
erforderlich.
Mike schrieb:> Wenn ich jetzt feststelle, dass in einer Bibliothek doch noch ein Fehler> existiert oder ich zusätzliche Funktionen brauche müsste ich alle Kopien> der Bibliotheksdateien ändern. Dies ist ja nicht im Sinne von> Bibliotheken.
Das ist aber duchaus in deinem Sinne, denn ohne lokale Kopien müsstest
du bei jeder Änderung an einer der globalen Dateien alle betroffenen
Projekte erneut compilieren und testen, auch schon längst
abgeschlossene.
Insofern ist es gar nicht so verkehrt, in jedem Projekt lokale Kopien
der Dateien zu haben. Enthalten deine Module hardwareabhängige
Funktionen (Prozessortyp, Taktfrequenzen, Pinbelegungen, ...) geht es
sowieso nicht anders.
Oliver
Oliver schrieb:> Insofern ist es gar nicht so verkehrt, in jedem Projekt lokale Kopien> der Dateien zu haben. Enthalten deine Module hardwareabhängige> Funktionen (Prozessortyp, Taktfrequenzen, Pinbelegungen, ...) geht es> sowieso nicht anders.
Doch, es geht auch dann anders.
Ordner Weltprojekt:
main.c - mein Hauptprogramm, welches zeitmaschine
aus der "lib" verwendet
zeitmaschine-cfg.c - Beschreibung der Hardware, diese besteht z.B.
aus folgenden Zeilen:
#define LED_AN_ZEITMASCHINE_PORT PORTD
#define LED_AN_ZEITMASCHINE_DDR DDRD
#define LED_AN_ZEITMASCHINE_PIN 3
#include "../lib/zeitmaschine.h"
#include "../lib/zeitmaschine.c"
Ordner lib:
zeitmaschine.h
zeitmaschine.c
So liegen die "Bibliotheks-Quelltexte" in einem gemeinsamen Ordner und
sie lassen sich sich trotzdem at-compile-time noch an die jeweilige
Hardware anpassen.
Es ist zwar etwas unschön, dass hier irgendwas.c per include angezogen
wird, aber das ist meines Erachtens die einzige Möglichkeit, die
Hardware außerhalb des lib-Ordners at-compile-time zu beschreiben.
Gruß,
Frank
Hallo
es gibt drei Möglichkeiten:
1) externes Verzeichnis (sowie Rufus es beschrieben hat)
Vorteile:
flexible in der Konfiguration (durch Kompiler-Schalter)
Nachteile:
Langsam, muss immer mit kompiliert werden.
schlecht zu reversieren.
2) echte Bibliotheken
das ist einen eigenes "Projekt", wo du die Vorkompilierten Liberies in
dein Hauptprojekt nur dazu linkst.
Vorteile:
unflexible in der Konfiguration
Nachteile:
Schnell, muss nur gelinkt werden.
Liberies (Binärdateien müssen versioniert werden).
3) eigenes Verzeichnis in SVN
du erstellst ein separaten Pfad in SVN und bindest ihn als "extern"
unter dein Quellverzeichnis ein.
Vorteile:
flexible in der Konfiguration (durch Kompiler-Schalter)
Volle Unterstützung der Version durch SVN.
Nachteile:
Langsam, muss immer mit kompiliert werden.
Welche für dich die beste Variante ist, hängt unter anderem, von der
Größe deine Projekte, und der Notwendigkeit genau eine Version wieder
herzustellen ab.
Gruß Volker
Frank M. schrieb:> #define LED_AN_ZEITMASCHINE_PORT PORTD> #define LED_AN_ZEITMASCHINE_DDR DDRD> #define LED_AN_ZEITMASCHINE_PIN 3>> #include "../lib/zeitmaschine.h"> #include "../lib/zeitmaschine.c"
Sehr unschön.
Der Vorteil der, das immer nur kleine "Häpchen" bei Änderungen
kompiliert werden geht verloren. Versuch Sowas mal bei einem großen
Projekt.
Besser:
Ordner Weltprojekt:
config.h :
#define LED_AN_ZEITMASCHINE_PORT PORTD
#define LED_AN_ZEITMASCHINE_DDR DDRD
#define LED_AN_ZEITMASCHINE_PIN 3
main.c
#include "../lib/zeitmaschine.h"
Ordner lib:
zeitmaschine.h
zeitmaschine.c
#include "config.h"
#include "../lib/zeitmaschine.h"
Volker Zabe schrieb:> Der Vorteil der, das immer nur kleine "Häpchen" bei Änderungen> kompiliert werden geht verloren.
Dann dauert der Compilier-Vorgang halt 6 statt 2 Sekunden. Wohlgemerkt:
ich mache sowas nur bei Mikrocontroller-Projekten, wo es auf jedes Byte
ankommt, und man seine "Bibliotheks-Quelltexte" durch
Preprozessor-defines perfekt auf das jeweilige Projekt abstimmen kann.
> Versuch Sowas mal bei einem großen Projekt.
Ich habe teilweise Projekte, wo ich über ein Dutzend dieser
"Bibliotheks-Quelltexte" so verwende. Hier mal eine Liste:
base.[ch]
i2c-eeprom.[ch]
i2c-master.[ch]
i2c-rtc.[ch]
irmp.[ch]
jumper.[ch]
keys.[ch]
lcd.[ch]
led.[ch]
relais.[ch]
rf12.[ch]
rfid.[ch]
rs232.[ch]
rs485.[ch]
serlcd.[ch]
softclock.[ch]
softuart.[ch]
> Besser:>> Ordner Weltprojekt:> config.h :> #define LED_AN_ZEITMASCHINE_PORT PORTD> #define LED_AN_ZEITMASCHINE_DDR DDRD> #define LED_AN_ZEITMASCHINE_PIN 3>> main.c> #include "../lib/zeitmaschine.h">> Ordner lib:> zeitmaschine.h>> zeitmaschine.c> #include "config.h"> #include "../lib/zeitmaschine.h"
Wo ist da der Unterschied? Ich halte Deine Variante sogar für
aufwändiger. Wenn ich Deine config.h ändere, wird nicht nur
zeitmaschine.c übersetzt sondern auch alle anderen "LIB-Quelltexte", die
ich verwende. Wenn ich zum Beispiel lediglich eine Konfig-Zeile für
lib/beamer.c in config.h geändert habe, wird auch zeitmaschine.c neu
übersetzt. Das ist unnötig.
Bei meiner Variante wird zeitmaschine.c nur dann neu compiliert, wenn
sich auch zeitmaschine-cfg.c geändert hat.
EDIT:
Ich bezweifle, dass Dein #include "config.h" so "um die Ecke" überhaupt
technisch funktioniert. Vermutlich wirst Du den Pfad auf Weltprojekt
angeben müssen. Damit ist dann der Source unter lib aber nicht mehr
allgemein verwendbar.
Frank M. schrieb:>> Versuch Sowas mal bei einem großen Projekt.>> Ich habe teilweise Projekte, wo ich über ein Dutzend dieser> "Bibliotheks-Quelltexte" so verwende. Hier mal eine Liste:
Na ja, "große" Projekte sind was anderes. Solange wir hier über AVRs
reden, gibt es gar keine großen Projekte.
Oliver
Frank M. schrieb:> Ich halte Deine Variante sogar aufwändiger.> Wenn ich Deine config.h ändere, wird nicht nur zeitmaschine.c übersetzt> sondern auch alle anderen "LIB-Quelltexte", die ich verwende. Wenn ich> zum Beispiel lediglich eine Konfig-Zeile für lib/beamer.c in config.h> geändert habe, wird auch zeitmaschine.c neu übersetzt. Das ist unnötig.
In die config.h kommen nur hardwareabhängige Defines.
Wie oft änderst du deine Hardware innerhalb eines Projektes?
Und wie oft machst du Änderungen an deinen Funktionen?
> EDIT:> Ich bezweifle, dass Dein #include "config.h" so "um die Ecke" überhaupt> technisch funktioniert. Vermutlich wirst Du den Pfad auf Weltprojekt> angeben müssen.
Natürlich funktioniert es. Ja, man kann den Pfad im Projekt angeben.
Da ich alle allgemeinen Funktionen bei mir im Unterverzeichnis
(SVN:extern) "shared" liegen kann man aber auch:
#include "..\config.h"
schreiben.
> Damit ist dann der Source unter lib aber nicht mehr> allgemein verwendbar.
Denn Zusammenhang verstehe ich nicht.
@Oliver
Das kann so sein. Ich programmiere hauptsächlich Renesas-µC.
Volker
Oliver schrieb:> Na ja, "große" Projekte sind was anderes. Solange wir hier über AVRs> reden, gibt es gar keine großen Projekte.
ACK. Ich habe auch nicht von "großen" Projekten gesprochen. Das war
Volker ;-)
Volker Zabe schrieb:> Natürlich funktioniert es. Ja, man kann den Pfad im Projekt angeben.
Okay.
> Da ich alle allgemeinen Funktionen bei mir im Unterverzeichnis> (SVN:extern) "shared" liegen kann man aber auch:> #include "..\config.h"> schreiben.
Das mit dem Backslash meinst Du jetzt aber nicht im Ernst, oder? ;-)
Mike schrieb:> Hierbei habe ich jedoch das Problem, dass ich> dann in jedem Projekt, welches ich erstelle eine Kopie der> Bibliotheksdateien habe.
Das ist kein Problem, sondern ein Vorteil.
Damit stellst Du sicher, daß sich alte Projekte weiterhin compilieren
lassen und auch funktionieren.
Eine Bibliothek sollte man nur dann zentral halten, wenn sicher ist, daß
sie nie mehr geändert wird.
Auf private Bibliotheken trifft das aber in der Regel nicht zu. Man
findet immer wieder Verbesserungen oder sogar Bugs.
Peter
Peter Dannegger schrieb:> Damit stellst Du sicher, daß sich alte Projekte weiterhin compilieren> lassen und auch funktionieren.
Dafür gibt es in SVN Tags/Branches.
Würde es nicht funktionieren einfach für jedes Projekt einen eingenen
Outputfolder zu definieren in den die Bibliotheken dann
(projektspezifisch) gebaut werden?
Läubi .. schrieb:> Dafür gibt es in SVN Tags/Branches.
Puh.
Also wenn ich zu jedem Projekt auch noch ne zentrale Bibliothek mit
einchecken müßte, würde ich komplett den Überblick verlieren.
Peter
Peter Dannegger schrieb:> Also wenn ich zu jedem Projekt auch noch ne zentrale Bibliothek mit> einchecken müßte, würde ich komplett den Überblick verlieren.
Na so ist das ja auch nicht gedacht.
Angenommen alle Projekte sind in einem Repro:
- Änderungen nimmst du einfach im Trunk vor und bastelst fröhlich vor
dich hin.
- Wenn dein Projekt "fertig" ist erzeugst du einen Branch
- Änderungen an dem "fertigem" Projekt nimmst du im Branch vor
- neue Projekte wiederum im Trunk fortsetzen.
Optimalerweise mergst du natürliche kritische Bufixes vom Trunk in die
Branches wenn nötig, oder halt auch nicht.
So kannst du aber auf einfache weise sehen wo und wann sich deine Lib
eventuell aufsplittet, hast immer noch deinen alten Stand und kannst
wenn du das Projekt eh nochmal anfasst z.B. aus dem Trunk reinmergen und
dann die nötigen Anpassungen vornehmen um deinen aktuellen Stand zu
reintegrieren.
Man kann sich sicher andere Versionsverwaltungen (z.B. GIT) und andere
Szenarien überlegen, aber mit etwas gutem Willen ist es zumindest nicht
nötig immer alle Biliotheken mehrfach zu kopieren, dann weiß man nacher
so überhauptnichtmehr was welche Version ist und kann auch nicht
wirklich konsitent seine Bugfixes verfolgen.
Also erst mal ein riesen Dank für all die konstruktiven Beiträge.
Nachdem was ich jetzt hier alles gelesen habe muss ich sagen, werde ich
wohl zur gewohnten Art zurückkehren und einfach keine "Bibliotheken"
anlegen bzw. zentral verwalten.
Jedes Projekt bekommt eine Kopie der immer wieder benötigten Funktionen
und gut ist.
Wenn jetzt doch irgendwann mal was nimmer geht hab ich ja eh das SVN wo
ich auf alle Versionen noch zugreifen kann wenn doch mal was
verprogrammiert ist.
Vielen Dank nochmal.
Mike