Forum: Compiler & IDEs Eigene Header und Source Dateien in mehrern Projekten nutzen?


von Mike (Gast)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Oliver (Gast)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

von Volker Z. (vza)


Lesenswert?

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

von Volker Z. (vza)


Lesenswert?

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"

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Oliver (Gast)


Lesenswert?

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

von Volker Z. (vza)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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 ;-)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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? ;-)

von Peter D. (peda)


Lesenswert?

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

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

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

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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.

von Mike (Gast)


Lesenswert?

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

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.