Forum: Compiler & IDEs Fertige Objektdatein in neuem Projekt nutzen


von Jürgen S. (jsachs)


Lesenswert?

Hallo,

kurz zu dem was ich vor habe:
Ich habe ein Projekt für eine Busanbindung. Nun möchte ich einzelne 
Teile (Die Busanbindung selbst und was dazu gehört) in einem neuen 
Projekt nutzen.

Ich möchte im neuen Projekt nicht die Source Codes einbinden ! Es wäre 
sonst nicht mehr zu überschauen was aktuell gepflegt wurde und was nicht 
:-)

Wie macht man sowas am einfachsten ?
- Die zugehörigen Objektdateien ins neue Projekt kopieren und einfach 
dazu linken (wie geht das ?) und wie könnte ich vermeiden, das diese 
Dateien per "make clean" auch gelöscht werden.
- Eine Lib erstellen (wie geht das ?)
Oder gibt es dafür noch eine einfachere oder bessere Variante ?
Wie habt Ihr sowas bisher gelöst ?

Vielleicht könnt Ihr da einem Makefile und gcc Novice weiterhelfen.

Ich nutze avr-gcc 3.4.5 unter Linux, falls das relevant ist.

Auf die schnelle hab ich hierzu nichts gefunden.

Danke
Juergen

von Ulrich (Gast)


Lesenswert?

im wiki ist glaube ich beschrieben wie man eigene Libs macht. schaue dir 
das mal an. könnte dass sein was du suchst....

von Peter D. (peda)


Lesenswert?

Sofern keine Anpassungen (andere Delays, Baudraten, Pins, Quarztakt 
usw.) nötig sind, kannst Du natürlich auch fertige Objekte linken.


Peter

von Jürgen S. (jsachs)


Lesenswert?

Das mit dem Quarztakt und Pins ist ein guter Hinweis, Danke Peter.

Nach ein wenig Reserche ist mir nun klar, das eine Linkerlib im Prinzip 
nichts anderes ist eine Objektdatei mit speziellen pre und suffix.

Ich habe daher mein Makefile ergänzt:
-----------
# Compile: create object files from C source files.
%.o : %.c
  @echo
  @echo $(MSG_COMPILING) $<
  $(CC) -c $(ALL_CFLAGS) $< -o $@
  $(CC) -c $(ALL_CFLAGS) $< -o $@_$(MCU).a # <-- ergaenzt
-----------

Nun werden zusätzliche Objektdatein erzeugt, die den CPU Namen 
beinhalten.
In dem anderen Makefile werden diese dann mit
-----------
LDFLAGS += file1_$(MCU).a file2_$(MCU).a file3_$(MCU).a
-----------
hinzugefügt.

Durch den anderen Fileprefix ".a" werden diese Dateien hier nicht mehr 
mit "make clean" gelöscht.

Was jetzt noch fehlen würde, wäre, wenn ich im Ursprungsprojekt die Libs 
für eine Liste von CPUs erzeugen könnte, sobald sich die Quelle ändert, 
oder per Makefile Parameter z.B. "make libs".
Kann man sowas ähnliches in einem Makefile machen (Pseudocode)
-----------
CPUS="mega8515 mega16 mega32"
MCU_ORG=$MCU
FOR MCU IN $CPUS
{
   $(CC) -c $(ALL_CFLAGS) $< -o $@_$(MCU).a
}
MCU=$MCU_ORG
-----------
Und das ganze sobald sich die Zuständige Source Datei geändert hat ?
Vielleicht kann mir ja ein Makefile Spezialist weiterhelfen.

Ach ja, in welchem Wiki soll die Beschreibung sein ? (URL) Ich hab 
nichts gefunden.

Gruss
Juergen

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Nach ein wenig Reserche ist mir nun klar, das eine Linkerlib im Prinzip
> nichts anderes ist eine Objektdatei mit speziellen pre und suffix.

Nein, nicht ganz. Eine Library besteht üblicherweise aus mehreren 
Objektdateien, von denen sich der Linker nur die zur Auflösung der 
verwendeten Symbole erforderlichen herauspickt. Diese mehreren 
Objektdateien sind in einem Archivdateiformat zusammengefasst - daher 
das Suffix .a (bei gcc).

> Durch den anderen Fileprefix ".a" ...

<pedanterie>
Suf-, nicht Pre.
</pedanterie>


von Andreas Paulin (Gast)


Lesenswert?

Ich hatte das Problem letzthin:
- Immer ähnliche Codeteile für den ADC eines uC
- Immer je nach Projekt und uC-Derivat kleine Unterschiede,
- Keine Lust auf aufwendiges Library-erstellen und -pflegen
- Flaues Gefühl, was die Rückwärtskompatibilität angeht

Ich habs so gemacht:

1. Ein C-Sourcefile "adc.c" wird erstellt und eingebunden
2. Dieses File wird projektunabhängig gespeichert (z.B. im Include-Dir)
3. Für jedes neue Projekt, welches nun den ADC verwendet, definiere ich 
in Header (z.B."Neuprojekt.h") eine Konstante, einmalig und auf dem 
Projektname basierend: #define ADC_NEUPROJEKT
4. In adc.c erstelle ich einen neuen #ifdef-Abschnitt, kopiere mir den 
im letzten Abschnitt/Projekt verwendeten Code der ADC-Routinen und passe 
die Kleinigkeiten an.
das sieht dann so aus:

# ifdef ADC_NICD_LADER
     //....ADC-Routinen, passend für den Controller/ADC z.B. im Lader
#elif defined ADC_BELICHTUNGSMESSER
     //....ADC-Routinen, passend für Belichtungsmesser
#elif defined ADC_GanzNeuesProjekt
     //....ADC-Routinen, passend für GanzNeuesProjekt
#else #error ADC_ROUTINEN NICHT VORHANDEN IN ADC.C

Dadurch habe ich
- Prima Übersicht über verwendete Codevarianten im Source
- Gezielte Auswahl: Jedes Projekt hat seinen eigenen Code
- Immer die neuesten Varianten übersichtlich im Source angeordnet
- superleicht zu erweitern
- keine Nebeneffekte auf bestehende Projekte durch Codeänderungen wegen 
neuer Dinge


Grüßle

A.Paulin

von Oliver (Gast)


Lesenswert?

"..keine Nebeneffekte auf bestehende Projekte durch Codeänderungen wegen
neuer Dinge.."

Das schon, aber dafür erzeugst du so Code, den spätestens in zwei Jahren 
niemand mehr versteht, dich selber eingeschlossen, der tonnenweise toten 
Code enthält, und den niemals jemand warten kann. Problematisch ist es 
auch, in Original-Sourcen bereits abgeschlossener Projekte rumzuändern. 
Fehlerfreie Software gibt es nunmal nicht, und dann mit Sourcen 
dazustehen, die entweder gar nicht mehr compilieren, oder keine 
lauffähigen Code mehr ergeben, ist doch ziemlich blöd. Denn ob deine 
Änderungen wirklich keine Nebeneffekte auf bestehende Projekte haben, 
glaubst du nur, du weisst es aber nicht. Und schließlich, wie willst du 
ein Projekt archivieren?

Saubere Modulschnittstellen definieren und schreiben ist nicht einfach. 
Und wenn es keine Verallgemeinerung für eine bestimmte Aufgabenstellung 
gibt, dann gibt es die eben nicht. Besser wäre es dann, eigene adc.c 
Dateien für jedes Projekt zu erstellen, mit ein paar Zeilen Kommentar, 
was genau darin passiert. Copy&paste aus anderen Dateien ist ja trotzdem 
nicht verboten.

Oliver

von Peter D. (peda)


Lesenswert?

Ich hatte früher auch universellen Code an zentraler Stelle gespeichert.

Aber der Code mag noch so gut sein, es ergeben sich immer mal kleine 
Änderungen und man kann nicht überblicken, ob er noch abwärtskompatibel 
ist, wenn man mal ein altes Projekt hervorkramt.

Deshalb speichere ich alles mit im aktuellen Projekt ohne extra 
Nebenverzeichnisse. Damit bleibt es uneingeschränkt kompilierbar.


Peter

von Jürgen S. (jsachs)


Lesenswert?

Wenn ich jetzt mal die Unterschiede durch die CPU und Taktfrequenz außen 
vor lasse, ergeben sich bei mir keine Unterschiede. Sonst hätte ich 
einen Fehler im Gemeinsam genutzten Code :-)

Der Code kümmert sich um eine Anbindung an ein Bussystem. Nach außen 
habe ich eine API definiert. Kommt jetzt vom Bus ein Kommando, wird eine 
Funktion der API aufgerufen, die Technisch im Gerätespezifischen Code 
implementiert ist. Die Busanbindung ruft je nach Funktion einfach die 
API Funktionen auf. Da es sich um einen gepollten Bus für die 
Rückmeldungen handelt perfekt.

Bei einem Projekt hat das nun Problemlos funktioniert. Da die Funktionen 
die vom Bus kommen können genau festgelegt sind, ist die API auch 
unveränderlich.

Es wäre jetzt eben schön, wenn ich in einem Makefile, quasi in einer 
Schleife für alle von mir genutzten Prozessoren meine Linkerlib 
erstellen könnte.

1) Im Prinzip einen "make clean"
2) CPU ändern
3) Compile starten
4) Linkerlib erzeugen (mit CPUtyp im namen)
5) zurück zu eins für nächste CPU

Vermutlich würde etwas in der Art gehen:
makelibs:
  CPU=mega8515
  clean compile makelib
  CPU=mega16
  clean compile makelib
  CPU=mega32
  clean compile makelib

Eine Schleife wäre natürlich schöner, die einfach eine Liste 
abarbeitet....

Zum Testen und Bugfixen wird für eine spezifische CPU compiliert und 
getestet. Danach folgt ein "make makelibs", das darf auch ein wenig 
dauern :-) Nur ob sowas geht in einem Makefile, ist die Frage.... Es ist 
ja wieder Wochenende und es regnet ;-)

Gruss
Juergen

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.