Linken in einer Lib schlägt fehl

Gast #2716947
Lesenswert?

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
Lesenswert?

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 :(.
Moderator Persönliche Seite #2717123
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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 #2717875
Lesenswert?

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
Lesenswert?

> 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
Lesenswert?

> 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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren