[gelöst] Verschachtelte Codes linken
-
Hi,
wie angekündigt ein eigener Thread zu meinem Problem des Linkens. Ich hoffe das können wir noch gemeinsam bearbeiten, dann wäre ich auf jeden Fall einen riesigen Schritt weiter, auch was einen guten Programmierstil angeht.
Ich versuche auch gleich die Ratzschläge umzusetzen
i) in Header Dateien nur Deklarationen
ii) include guards
iii) Einrücken zur ÜbersichtlichkeitAlso das Ziel ist es in meiner Hauptdatei mainWater.cpp die Funktion time_of_photon_income() zur Verfügung zu haben, die wiederum Zufallszahlen benötigt.
Also für die Zufallszahlen verwende ich
// rng.h #ifndef rng_h #define rng_h double get_random_number(); #endif
Das ganze mündet dann in die folgende cpp Datei
#include <stdio.h> // GSL #include <gsl/gsl_rng.h> // header files #include "rng.h" double get_random_number() { const gsl_rng_type* T; gsl_rng* r; gsl_rng_env_setup(); T = gsl_rng_default; r = gsl_rng_alloc (T); return gsl_rng_uniform (r); gsl_rng_free (r); }
Frage 1
Dass die rng.cpp Datei rng.h benötigt ist klar. Doch weiterhin wird noch die gsl und stdio.h benötigt.
Wo includiere ich die denn jetzt am Besten? Ich habe es mal in der cpp Datei getan, ist das richtig? Oder gehören die ebenfalls in die rng.h Datei?Frage 2
Ich habe das ganze mittelg++ -Wall -pedantic -ansi -c rng.cpp
kompiliert und es funktioniert. Eigentlich sollte ich froh sein, doch warum funktioniert es? Müsste er nicht nach der gsl fragen?
Ich habe es dann analog versucht mitg++ -Wall -pedantic -ansi -I/usr/local/include -c rng.cpp
Das legt natürlich die Vermutung nahe, dass der Kompiler g++ sowieso im Verzeichnis /usr/local/include schaut, doch da befindet sich nichts außer dem gsl Ordner?
Okay, weiter: rng.cpp ist scheinbar kompiliert.
Als nächstes möchte ich es ja verwenden und zwar in
// time_of_photon_income. #ifndef time_of_photon_income_h #define time_of_photon_income_h #include <math.h> #include "rng.h" double time_of_photon_income(); #endif
Und das ganze mündet wiederum in
#include "time_of_photon_income.h" double time_of_photon_income(){// double mu = 12.5; double sigma = 5/sqrt(2*log(2)); bool condition = 0; double income_time = 0; while(condition == 0) { income_time = mu + sigma * sqrt(-2*get_random_number()) * cos(2*M_PI*get_random_number()); if( 0 < income_time && income_time < 25) { condition = 1; } } return income_time; }
Auch das wird wieder mittels
g++ -Wall -pedantic -ansi -c time_of_photon_income.cpp
kompiliert und funktioniert.
So, und jetzt geht es darum das ganze in meiner Hauptdatei zu verwenden und wie gesagt: Nur header Dateien includen
#include <iostream> #include "time_of_photon_income.h" using namespace std; int main(){// cout << "Time of photon income : " << time_of_photon_income() << " fs" << endl; return 0; }
und kompilieren mittels
g++ -Wall -pedantic -ansi -c mainWater.cpp
So, und jetzt würde ich gerne mainWater.o und time_of_photon_income.o linken. Oder benötige ich noch rng.o ? Ich meine, rng.o ist doch abgehandelt nachdem time_of_photon_income kompiliert wurde.
Da eben meine Verwunderung zur Verschachtelung. Auf jeden Fall kriege ich jetzt:~/GSL/Cpp$ g++ mainWater.o time_of_photon_income.o -o mainWater time_of_photon_income.o: In function `time_of_photon_income()': time_of_photon_income.cpp:(.text+0x37): undefined reference to `get_random_number()' time_of_photon_income.cpp:(.text+0x70): undefined reference to `get_random_number()' collect2: ld returned 1 exit status
Frage 3:
Müsste ich nicht eigentlich noch die gsl linken? Das ganze kommt mir nach wie vor komisch vor. Aber da kriege ich jetzt::~/GSL/Cpp$ g++ -L/usr/local/lib -o mainWater mainWater.o time_of_photon_income.o -lgsl lgslcblas -lm g++: lgslcblas: Datei oder Verzeichnis nicht gefunden
Hat doch hier auch noch funktioniert!
So, das wars.
RIESEN DANK FÜR EURE HILFE!!
Viele Grüße,
Klaus.
-
Hallo Klaus,
zu 1.: nur includieren, was auch wirklich benötigt wird, d.h. möglichst erst in der CPP-Datei
zu 2.: beim reinen Kompilieren mittels "-c" interessiert den Compiler noch keine Library, sondern eben erst beim Linken
zu 3.: hast du das Minuszeichen überlesen?
-lgslcblas
-l bezeichnet die Linkeroption und direkt dahinter steht dann der Libraryname
-
Hi,
Th69 schrieb:
zu 3.: hast du das Minuszeichen überlesen?
-lgslcblas
-l bezeichnet die Linkeroption und direkt dahinter steht dann der Libraryname
Verdamt, das war wirklich dumm von mir. Nachmittags lässt dann einfach die Konzentration nach.
Jetzt hänge ich nach wie vor an dem Problem, dass ich eine undefinierte Referenz bekomme. Vorher lässt sich aber alles problemlos kompilieren
:~/GSL/Cpp$ g++ -Wall -pedantic -ansi -c rng.cpp :~/GSL/Cpp$ g++ -Wall -pedantic -ansi -c time_of_photon_income.cpp :~/GSL/Cpp$ g++ -Wall -pedantic -ansi -c mainWater.cpp :~/GSL/Cpp$ g++ -L/usr/local/lib -o mainWater mainWater.o time_of_photon_income.o -lgsl -lgslcblas -lm time_of_photon_income.o: In function `time_of_photon_income()': time_of_photon_income.cpp:(.text+0x37): undefined reference to `get_random_number()' time_of_photon_income.cpp:(.text+0x70): undefined reference to `get_random_number()' collect2: ld returned 1 exit status
Gruß,
Klaus.
-
Du hast rng.o vergessen.
-
pyhax schrieb:
Du hast rng.o vergessen.
Wow, damit klappt es!
:~/GSL/Cpp$ g++ -L/usr/local/lib -o mainWater mainWater.o time_of_photon_income.o rng.o -lgsl -lgslcblas -lm
Aber genau das ist der Punkt wo mein Verständnis aussetzt. Wenn ich time_of_photon_income.cpp erfolgreich kompiliert habe (also es kann), weil die Datei weiß, dass die Zufallszahl mittels rng.h (und damit rng.cpp) erstellt wird.
Dann müsste time_of_photon_income.cpp doch nach dem kompilieren alle Informationen vorliegen haben, wieso muss ich dann rng.o nachträglich nochmal verlinken?
Gruß,
Klaus.
-
Nein, time_of_photon_income.o enthält nur "Verweise" auf Symbole aus anderen .o (Objekt-) Dateien. Erst der Linker löst dann diese Verweise auf.
-
pyhax schrieb:
Nein, time_of_photon_income.o enthält nur "Verweise" auf Symbole aus anderen .o (Objekt-) Dateien. Erst der Linker löst dann diese Verweise auf.
Okay, dann lese ich dazu mal noch ein wenig nach. Ist ja nicht so, als ob ich keinen Nachholbedarf hätte.
Wobei ich zugeben muss, dass ich die Wortwahl 'auflösen' ein wenig irreführend finde. Es hat etwas von beenden. Aber ich denke damit ist mehr die Auflösung eines Rätsels, Puzzles, Knotens oder Verwirrung gemeint?
Dass der Linker also die ganzen Querverweise sauber ordnet und anschließend klar ist, welches Objekt wohin verweist.
Gruß,
Klaus.
-
Klaus82 schrieb:
Aber ich denke damit ist mehr die Auflösung eines Rätsels, Puzzles, Knotens oder Verwirrung gemeint?
So ist das auch zu verstehen. Kann der Linker einen Verweis auf eine Funktion nicht eindeutig auflösen (weil sie z.B. mehrfach oder überhaupt nicht definiert ist), schlägt die Lösung des "Rätsels" fehl und der Linker beschwert sich. Genau das ist hier bei dir passiert. Der eigentliche generierte Code befindet sich bei dir in rng.o. Das Inkludieren des Headers in eine andere Datei führt lediglich dazu, dass bekannt gemacht wird, wie genau diese Funktion zu benutzen ist.