Forum: Compiler & IDEs Selbsterstelle Libray einbinden


von Daniel (Gast)


Lesenswert?

Guten Morgen!

Ich versuche, mit GCC für den MSP430-Controller eine Bibliothek 
zusammenzustellen, damit ich meine Funktionen nicht dauernd kopieren 
muss. Dazu habe ich mir das Tutorial auf dieser Seite durchgelesen 
(http://www.mikrocontroller.net/articles/Libraries).

Zum testen habe ich mir folgende Dateien erstellt:
Die Funktion typechange.c:

#include "libtest.h"
int typechange(char c)
{
  return (int) c;
}

Und eine Header-Datei libtest.h mit folgendem Inhalt:

int typechange(char c);


Ich arbeite unter Windows und habe "mspgcc" installiert. Auf der Zeile 
compiliere ich mit dem Befehl "msp430-gcc.exe -c typechange.c". Dann 
bekomme ich folgerichtig das Object-File "typechange.o".

Im Anschluss packe ich das Object-File zur eigentlichen Library mit 
"msp430-ar.exe -rcs libtest.a typechange.o". Funktioniert optimal, ich 
bekomme die Library "libtest.a".

Dann schreibe ich mir meine Main (Datei main.c):
#include "libtest.h"

int main(void)
{
  return typechange('A');
}

Auf der Zeile tippe ich zum linken:
"msp430-gcc.exe -o test.com main.c -L. -ltest". Keine Fehlermeldung, die 
Datei "test.com" wird erzeugt und lässt sich ausführen. Nun kann ich 
aber den Rückgabewert, der "65" sein sollte, nicht kontrollieren, da er 
auf der Konsole nicht angezeigt wird.

Nun möchte ich die erstelle Library in IAR verwenden. Beim Ausführen 
bekomme ich allerdings die Fehlermeldung "Error[e46]: Undefined external 
"typechange" referred in main ( C:\Documents and 
Settings\daniel\Desktop\iartest\Debug\Obj\main.r43 )"

Nun frage ich mich, warum der Linker "typechange" nicht auflösen kann 
und was ich dagegen machen kann.

Vielleicht könnt ihr mir dabei ja helfen.

Vielen Dank schonmal!
Daniel

von Karl H. (kbuchegg)


Lesenswert?

Daniel wrote:

> Nun möchte ich die erstelle Library in IAR verwenden.

Es gibt keine echte Normierung wie Libaries aufgebaut sein
müssen. Jeder Hersteller kocht da sein eigenes Süppchen.
Eine Library, die du mit Produkt xxx erstellt hast, wird mit
Produkt yyy nicht funktionieren.

von bereits fort (Gast)


Lesenswert?

Deine Headerdatei braucht noch (einen) Verweis(e) auf die Libery(s) in 
welche(r/n) die die declarierte(n) Funktionen definiert ist(sind).

von winne (Gast)


Lesenswert?

stichwort compilerdirektiven:

versuchs mal so.
da keine Pfade dabei sind erstmal alle Dateien in den Arbeitsordner

oder wenn es getrennte Ordner für include- und libery_dateien gibt diese 
dort hin
______________________________
libtest.c  //hauptprogramm
//****************************
#include "libtest.h"

int main(void)
{
  return typechange('A');
}

______________________________

"libtest.h"  //headerdatei
//*****************************
#ifndef libtest_INCLUDED
#define libtest_INCLUDED


#pragma used+
int typechange(char c);
#pragma used-


#pragma library libtest.lib // verweis auf libery

#endif

____________________________________

"libtest.lib" //liberydatei(kann beliebig viele Funktionen enthalten
//**********************************
int typechange(char c)
{
  return (int) c;
}

___________________________________



gruß winne = bereits weg

von Daniel (Gast)


Lesenswert?

Danke für eure Antworten.

Die Pragmas kennt IAR leider nicht. Welchen Zweck hätten diese?
Die mit
1
#ifndef libtest_INCLUDED
2
#define libtest_INCLUDED
3
4
int typechange(char c);
5
6
#endif
abgeänderte libtest.h hat auch nicht funktioniert.

Was bewirken diese Direktiven eigentlich genau? Meine Library hat zudem 
die Endung .a und nicht .lib. Wo wird .lib verwendet und könnte das 
einen Einfluss haben?

Ich dachte, ich habe mit der oben beschriebenen Vorgehensweise eine 
"Standard C-Bibliothek" erstellt, die jeder Compiler für diesen 
Controllertyp versteht.

Wenn ich aber das Posting von  Karl Heinz Buchegger durchlese, könnte 
mein ganzes Vorhaben völlig um sonst sein. Dann müsste ich die 
Bibliotheken mit den Tools von IAR erstellen und kann diese dann aber 
auch nur mit der Entwicklungsumgebung von IAR verwenden. Doof irgendwie, 
wenn ich später ne andere Umgebung verwenden will...

Grüße,
Daniel

von Oliver (Gast)


Lesenswert?

>Doof irgendwie, wenn ich später ne andere Umgebung verwenden will...

Klingt doof, ist aber so. Willkommen im Leben...

Und selbst auf Sourcelevel ghibt es keine Kompatibilität. gcc nach IAR, 
und umgekehrt, erfordert auch im Sourcecode Änderungen.

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Oliver wrote:

> Und selbst auf Sourcelevel ghibt es keine Kompatibilität. gcc nach IAR,
> und umgekehrt, erfordert auch im Sourcecode Änderungen.

Und dann gibts dann noch das weite Feld der "calling conventions".
Welcher Compiler übergibt wie Funktionsargumente an Funktionen?
Wenn überhaupt, wieviele von den Argumenten landen in welchen
Registern? In welchem Register kommt der Returnwert zurück
oder liegt der vielleicht doch am Stack? ....

Apropos: Wie gross ist eigentlich ein int? Und kann es sein,
dass ein int dieselbe Größe wie ein long hat?

(Ist ne rethorische Frage, die dich zum Nachdenken über mögliche
Unterschiede bei verschiedenen Compilern anregen soll und was daraus
für Bibliotheken folgt.)

> Dann müsste ich die Bibliotheken mit den Tools von IAR erstellen
> und kann diese dann aber auch nur mit der Entwicklungsumgebung
> von IAR verwenden.

Das ist im Regelfall noch das kleinere Übel. In Bibliotheken
schreibt man den Code entweder
 * so, dass er universell einsetzbar ist: Sprich Standard-C und nur
   Standard-C.
   In dem Fall genügt es meist, den Quellcode für die Bibliothek
   einmal neu zu übersetzen und die Library neu zu bilden.
   Ist meist kein großes Thema

 * so, dass man die Hardwareabhängigen Teile in der Library kapselt.
   Die ist aber meist so compilerspezifisch, dass man sowieso
   ran muss.

von winne (Gast)


Lesenswert?

Hallo daniel

meine directivenbeispiele entstammen dem CVAVR wenn dein compiler diese 
nicht akzeptiert, so bleibt dir nichts anderes als die vür deinen 
Compiler gültigen zu studieren.



#include "libtest.h"  // bindet eine headerdatei ein (in ihr sollten 
externe funktions,variablen und konstantendefinitonen vorgenommen 
werden, so können programme zum beispiel durch ändern der 
Chipspezifischen headerdateien auf ander chips der gleiche familie 
portiert werden.)

#ifndef libtest_INCLUDED // begin der if schleife es wird getestet ob 
"libtest_INCLUDED" noch nicht definert ist
#define libtest_INCLUDED in diesem fall wird "libtest_INCLUDED" 
definiert


#pragma used+    // die folgenden funktionen (etc.) werden nur dann 
dclariert wenn der compiler sie tatsächlich benötigt
int typechange(char c); // funtionsdeclaration (prototyp)
#pragma used-    // used pragma wird wieder ausgeschaltet


#pragma library libtest.lib // verweis auf libery

#endif // hier endet die if schleife

von winne (Gast)


Lesenswert?

Vielleicht aber kennt dein Compiler aber auch diese Direktiven oder 
ähnliche, und nur die Syntax ist eine andere. Das hat es leider oft wenn 
man Beispielprogramme von einer Plattform auf eine andere portieren 
will.

:-((

von Daniel (Gast)


Lesenswert?

Alles klar!

Danke für eure kompetente Hilfe!

Daniel

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.