Linken in einer Lib schlägt fehl

Gast #2716947
Hi,

ich portiere derzeit mein CFramework und eine andere Bibliothek von dem 
MS Compiler zu GCC (die MS Unterstützung für C ist nicht die Beste), 
also die Dateien zu einem Eclipse Projekt kopiert und kompiliert. So 
weit so gut. Nachdem ich jedoch ein Testprogramm geschrieben habe, 
jammert der Linker an vielen Stellen, dass dort eine Funktion ist, zu 
dem er keine Referenz findet. Nur warum? Die Pfade und Bibliotheken sind 
drin und der Compiler und der Linker haben sonst nichts zu meckern.
Mir ist aufgefallen, dass der Linker kein Problem mit der CFramework Lib 
hat, sondern mit der anderen Lib, welche dass das CFramework benutzt. 
Und genau dort liegt das Problem. Der Linker findet die Referenz von den 
CFramework Funktionen nicht, die (und nur die) in der anderen Bibliothek 
verwendet werden, das eigentliche Programm hat keine Problem das 
CFramework zu benutzen.

Ich hoffe, dass ich das Problem ausreichend schildern konnte, denn am 
Code kanns nicht liegen.

Vielen Dank für eure Hilfe!
Gast #2716987
OK hier mal ein Beispiel:

CFramework.c:
1
void stopwatch_start()
2
{
3
...
4
}
5

6
...

Hier wird dann das Framework benutzt:
CEngine.c
1
void DoSomething()
2
{
3
    stopwatch_start();
4
...
5
}

main.c:
1
...
2
int main(void)
3
{
4
    ...
5
    DoSomething(); // <-- undefined reference to `stopwatch_start' CEngine.c
6
    ...
7
}

Hier die Ausgabe von Eclipse:
1
gcc -IC:\Users\Christopher\C_Projekte\CFramework\src -IC:\Users\Christopher\C_Projekte\CEngine\src -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -o src\Main.o ..\src\Main.c
2
gcc -LC:\Users\Christopher\C_Projekte\CFramework\Debug -LC:\Users\Christopher\C_Projekte\CEngine\Debug -o CEngine_Test.exe src\Main.o -lCFramework -lCEngine -lgdi32 -luser32 -lkernel32 -lopengl32 -lglu32
Und dann gehts los mit Fehlern :(.
Gast #2717045
Also diese drei Codedateien gehören je zu einem Projekt.
CFramework.c -> CFramework
CEngine.c -> CEngine (braucht CFramework)
main.c -> Programm (linkt CFramework und CEngine)
Moderator Persönliche Seite #2717123
Christopher C. schrieb:
> Also diese drei Codedateien gehören je zu einem Projekt.

Das allein hat doch aber noch nichts mit Bibliotheken zu tun.

Mir dünkt, du schmeißt hier gerade sämtliche Begriffe durcheinander.

Compiliere diese drei Dateien jeweils separat, und dann linkst du
die erhaltenen Objekte zusammen.  Nix "Bibliothek", keine -l
Optionen (außer denen für Systembibliotheken, soweit erforderlich).

gcc -o executable main.o CFramework.o CEngine.o

Fertig ist die Laube.
#2717137
Früher war's mal so, dass der Linker statische Bibliotheken nur von 
links nach rechts einmal sequenziell abgearbeitet hat. Man musste also 
die Bibliotheken in der richtigen Reihenfolge beim Linken angeben und 
ggf. auch mal eine Bibliothek mehrfach angeben, z.B. wenn A und B sich 
gegenseitig benötigen "-lA -lB -lA".
Gast #2717809
Nein, du verstehtst mich falsch, das war nur ein Beispiel, die Projekte 
haben weit mehr als nur eine Codedatei. Bibliotheken daraus zu machen, 
macht schon Sinn.
Am Anfang hab ich die drei Projekte schon mal für den GCC gemacht, das 
funktionierte auch. Danach wechselte ich dann zu Visual Studio 2010, da 
ich hörte, dass es die beste IDE für C++ ist (somit eigentlich auch für 
C). Allerdings stellte sich dann heraus, dass die IDE wirklich gut, der 
Compiler aber für C Müll ist. Ich schrieb aber trotzdem noch ein wenig 
weiter an meinem Bibliotheken und nun will ich wieder zurück zu GCC.

Hier noch mal die ganze Ausgabe:
1
gcc -IC:\Users\Christopher\C_Projekte\CFramework\src -IC:\Users\Christopher\C_Projekte\CEngine\src -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -o src\Main.o ..\src\Main.c
2
gcc -LC:\Users\Christopher\C_Projekte\CFramework\Debug -LC:\Users\Christopher\C_Projekte\CEngine\Debug -o CEngine_Test.exe src\Main.o -lCFramework -lCEngine -lgdi32 -luser32 -lkernel32 -lopengl32 -lglu32
3
C:\Users\Christopher\C_Projekte\CEngine\Debug/libCEngine.a(Framelimiter.o): In function `framelimiter':
4
C:\Users\Christopher\C_Projekte\CEngine\Debug/../src/Framelimiter.c:9: undefined reference to `stopwatch_new'
5
C:\Users\Christopher\C_Projekte\CEngine\Debug/libCEngine.a(Framelimiter.o): In function `framelimiter_update':
6
C:\Users\Christopher\C_Projekte\CEngine\Debug/../src/Framelimiter.c:16: undefined reference to `stopwatch_stop'
7
C:\Users\Christopher\C_Projekte\CEngine\Debug/../src/Framelimiter.c:17: undefined reference to `stopwatch_getElapsedMilliseconds'
8
C:\Users\Christopher\C_Projekte\CEngine\Debug/../src/Framelimiter.c:20: undefined reference to `stopwatch_restart'

Ich hab zwar die alten Projekte noch, kann aber leider keinen 
Unterschied in den Einstellungen feststellen. Kann das überhaupt nicht 
nachvollziehen.
Gast #2717858
Endlich funktionierts!
Dachte es wäre egal wie man die Bibliotheken anordnet. Und selbst wenn, 
dachte ich, die wären richtig angeordnet.

Vielen Dank!
Gast #2717875
aha,

Christopher C. schrieb:

> Am Anfang hab ich die drei Projekte schon mal für den GCC gemacht, das
> funktionierte auch. Danach wechselte ich dann zu Visual Studio 2010, da
> ich hörte, dass es die beste IDE für C++ ist (somit eigentlich auch für
> C). Allerdings stellte sich dann heraus, dass die IDE wirklich gut, der
> Compiler aber für C Müll ist. Ich schrieb aber trotzdem noch ein wenig
> weiter an meinem Bibliotheken und nun will ich wieder zurück zu GCC.

deshalb steigt man von einem funktionierenden System um,

Jörg Wunsch schrieb:
>>... -lCFramework -lCEngine ...Falsche Reihenfolge.
>
> Bzw. siehe Beitrag "Re: Linken in einer Lib schlägt fehl"
>
> Konkret also:
> -lCFramework -lCEngine -lCFramework......

muss ich mir mal merken, wenn ich wieder zuviel zu tun haben
#2719783
> Allerdings stellte sich dann heraus, dass die IDE wirklich gut, der
> Compiler aber für C Müll ist

Woran machst Du das fest?



> -lCFramework -lCEngine -lCFramework

Kann man machen. Hat aber den Nachteil daß es kompliziert/aufwändig 
werden kann wenn man noch mehr Komponenten mit diesen Abhängigkeiten 
verwenden will.

Aber diese zirkulären Abhängigkeiten sind häufig ein Anzeichen für ein 
schlechtes Design. Überleg mal, ob Du es nicht anders aufteilen  kannst.

Wenn das nicht geht (oder zu kompliziert/aufwändig ist) kannst Du auch 
die Linker-Gruppen vom GCC/LD verwenden.

 -Wl,--start-group -lCFramework -lCEngine  -Wl,--end-group

dann versucht der LD diese Abhängikeiten selbst aufzulösen.
Gast #2720133
> Aber diese zirkulären Abhängigkeiten sind häufig ein Anzeichen für ein
> schlechtes Design. Überleg mal, ob Du es nicht anders aufteilen  kannst.

Danke für die Rückmeldung. Aber so schlimm is es nicht, ich kann einfach 
mit:
-lCEngine -lCFramework
linken. Die Reihenfolge war einfach falsch.

Vielen Dank für eure Bemühungen ;).

mfg

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.