• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

problem mit gcc

ramrod

Newbie
ich weiss, dass es sich bei dem ganzen nicht wirklich um ein problem handelt, sondern eher um meine eigene, schon so oft unter beweis gestellte, unfaehigkeit, mans richtig zu lesen. aber ich finde einfach keine loesung und denke mal, dass ich da hier richtig bin.

das problem ist folgendes: ich habe vor einiger zeit ein recht umfangreiches programm in c geschrieben. das war fuer die hochschule und die hatten da so ein eigenes "make" fuer, das echt komisch zu konfigiurieren war. nun, dieses make habe ich nicht mehr und ich will das programm aber trotzdem compilieren, ohne irgendwelche make-files und dergleichen.

ich habe also also ein verzeichnis src/, in dem die eigentliche code-datei liegt, die auch die main funktion beinhaltet, und ich habe noch zwei andere verzeichnisse a/ und b/, in welchen sich verschiedene c und h dateien befinden, die ich zum compilieren der main-datei benoetige. die ganzen "#includes" usw muessten also passen (schliesslich hat es ja damals geklappt), aber ich wenn ich in der main-datei eine Instanz eines objekt erstellen will (auch, wenn es sich im selben verzeichnis befindet), kriege ich z.b. die meldung "undefined reference to `Vector::Vector(float, float, float)'". Vector.c ist also einfach eine Datei in src/. Ich denke mal, dass ich diese anderen Dateien irgendwie als objects "vorkompilieren" muss. ich weiss aber nicht wie. und wie gebe ich dem gcc dann an, dass er diese auch verwenden muss?

weiss vielleicht jemand etwas? mir waere damit wirklich sehr geholfen!! vielen dank schonmal ;)

martin
 
Es kommt darauf an, ob die Objektdeklaration als Header eingebunden ist oder nicht.

Wenn nicht:
Du musst die einzelnen .c als .o kompilieren ohne sie zu linken. Und zwar mit
Code:
gcc -c -o Main.o Main.c -Wall
Du musst natürlich deine Includes mit -I/pfad/zum/ordner übergeben, die nicht im Suchpfad des Compilers sind (die im Projektordner müssen nicht angegeben werden)
Das musst du mit jeder .c Datei machen, die z.B. eine Objektdeklaration enthält, die in der Hauptdatei verwendet wird und nicht als Header eingebunden ist.

Dann musst du die erzeugten .o Dateien Linken mit
Code:
gcc -o Main Main.o andere.o ... -Wall
Hier musst du die Programm spezifischen Bibliothekenpfade mit angeben, mit -L/pfad/zum/ordner

Ich hoffe das hilft dir weiter

Je nachdem wie dein Projekt aufgebaut ist auch Tools, die die Makefiles automatisch generieren. Z.B. qmake für Qt-Programme


MfG

Daniel

P.S.: Ich bin noch nicht so programmiererfahren, also alles ohne Gewähr :twisted: .
Ich habe das aus diesem Tutorial für Qt abgeleitet ( Lektion 3-5 sind interresant): http://www.mrunix.de/forums/showthread.php?t=36851#postmenu_165369
 

TeXpert

Guru
ramrod schrieb:
das problem ist folgendes: ich habe vor einiger zeit ein recht umfangreiches programm in c geschrieben. das war fuer die hochschule und die hatten da so ein eigenes "make" fuer, das echt komisch zu konfigiurieren war. nun, dieses make habe ich nicht mehr und ich will das programm aber trotzdem compilieren, ohne irgendwelche make-files und dergleichen.

warum willst Du ein umfangreiches Projekt von Hand kompilieren? Das verstehe ich nicht, bau Dir einmal ein Makefile und Du hast ruhe.

ich habe also also ein verzeichnis src/, in dem die eigentliche code-datei liegt, die auch die main funktion beinhaltet, und ich habe noch zwei andere verzeichnisse a/ und b/, in welchen sich verschiedene c und h dateien befinden, die ich zum compilieren der main-datei benoetige. die ganzen "#includes" usw muessten also passen (schliesslich hat es ja damals geklappt),

wenn die Direktiven ohne relative Pfade sind, dann verlässt sich der Kompiler auf die cmd-line-Parameter, d.h. Du musst hier die Pfade zu den Bibliotheken und Include-Files angeben

aber ich wenn ich in der main-datei eine Instanz eines objekt erstellen will (auch, wenn es sich im selben verzeichnis befindet), kriege ich z.b. die meldung "undefined reference to `Vector::Vector(float, float, float)'". Vector.c ist also einfach eine Datei in src/. Ich denke mal, dass ich diese anderen Dateien irgendwie als objects "vorkompilieren" muss. ich weiss aber nicht wie. und wie gebe ich dem gcc dann an, dass er diese auch verwenden muss?

das ist kein Kompilefehler sondern Linkerfehler, d.h. Du brauchst da auch noch entsprechende Parameter.
weiss vielleicht jemand etwas? mir waere damit wirklich sehr geholfen!! vielen dank schonmal ;)

mehr Input => mehr output ;) z.zt. muss ich etwas raten.
 
OP
R

ramrod

Newbie
@daniel2000: vielen dank fuer deine muehe, aber leider klappt es noch immer nicht und ich steige da nicht so ganz durch...

@TeXpert: hmm, ok. ich weiss nicht genau, wie ich es beschreiben soll. ich schildere die situation am besten mal ganz konkret:

ich habe also das main-programm in der datei "test.c" und in dieser test-datei brauche ich die datei "Vector.c", weil ich von "Vector" irgendwo in "test.cc" eine instanz erzeuge... da sich die datei "Vector.c" und deren header-datei im selben verzeichnis wie "test.c" befinden, habe ich in letzterer einfach "#include Vector.h" stehen. aber irgendwie muss ich diese Vector.c wohl leider erst voher kompilieren, oder? denn, wenn ich das nicht tue, dann meldet der gcc halt " undefined reference to `Vector::Vector(float, float, float)'", wenn ich in "test" einen Vector erzeugen will. das problem ist quasi analog zu folgendem:

dieses programm benutzt auch opengl. wenn ich einfach nur compiliere und alles richtig include, kommt auch so eine fehlermeldung. sag ich dem gcc, dass er die gl-libs benutzen soll (mit gcc-lGL ...), dann klappt es... nur leider ist die Vector.c erstmal kein lib, sondern einfach ne c-datei...

ok, ich glaub besser erklaeren kann ich es fuers erste nicht... hab halt leider ueberhaupt keine ahnung von sowas. darum will ich mir das makefile erst mal ersparen und gucken, wie es so geht.

danke!

martin
 

oc2pus

Ultimate Guru
c, cpp, cc sind Sourcen
h, hpp, hxx, ... sind Includes
diese wandelt der compiler um in binäre Objekte die Dateien mit *.o
mehre dieser Objekte kann man in einer lib sammeln (libXXX.so)

diese werden dann vom Linker zu einem Programm zusammengefasst

der gcc kann das beides in einem Schritt, er braucht dazu aber die Angabe aller Bibliothekne und Objekte um alle Referenzen auflösen zu können.

gcc -I<include-pfade> -l<bibliothek-pfade> -o<ausgabenamen des Objektes> <source-datei>

Beispiel:
Code:
g++ -DHAVE_CONFIG_H -I. -I. -I.. -DDATADIR=\"/usr/share\" -DRC_DIR=\"/usr/etc\" -DGNOMELOCALEDIR=\""/usr/share/locale"\" -I../intl -DPREFIX=\"/usr\" -DDATA_DIR=\"/usr/share\" -I. -IGTK/ -ISettings/ -IsoundData/ -IIO/ `pkg-config --cflags sigc++-1.2` `pkg-config --cflags gtkmm-2.0` -IShm/ -IMixer/ -Ialsa/ -IOSS/ -IEsound/ -ICThread/ -IEffet/ -IPiste/ -IBloc/ -IDebug/ -IMutex/ -IDiskWriter/ -I/usr/include/taglib -I/usr/include/libxml2 -I/opt/gnome/lib/sigc++-1.2/include -I/opt/gnome/include/sigc++-1.2   -DXTHREADS -D_REENTRANT -DXUSE_MTSAFE_API -I/usr/include/freetype2 -I/usr/include/cairo -I/usr/X11R6/include -I/usr/include/libpng12 -I/opt/gnome/include/gtkmm-2.0 -I/opt/gnome/lib/gtkmm-2.0/include -I/opt/gnome/include/gtk-2.0 -I/opt/gnome/lib/sigc++-1.2/include -I/opt/gnome/include/sigc++-1.2 -I/opt/gnome/include/glib-2.0 -I/opt/gnome/lib/glib-2.0/include -I/opt/gnome/lib/gtk-2.0/include -I/opt/gnome/include/pango-1.0 -I/usr/include/freetype2/config -I/opt/gnome/include/atk-1.0    -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -pthread -I/usr/include/libxml2 -I/opt/gnome/include/gstreamer-0.8 -I/opt/gnome/include/glib-2.0 -I/opt/gnome/lib/glib-2.0/include    -DWAVEMIXERLOCALEDIR=\""/usr/share/locale"\" -D_DEBUG     -g -MT GtkSettingItem.o -MD -MP -MF ".deps/GtkSettingItem.Tpo" -c -o GtkSettingItem.o `test -f 'GTK/GtkSettingItem.cpp'

d.h. du musst zuerst deine beiden C-Dateien in *.o Dateien umwandeln und dann zusammenlinken mit allen anderen benötigten Bibliotheken.

Schau dir dazu am besten mal ein Makefile eines anderen Programmes an. Das sollte dir als Basis reichen um dein eigenes Makefile zu erstellen.
 

TeXpert

Guru
ok, das sind alles Linker-probleme, d.h. Du musst die Datei vector.o mit dem test.o zusammen linken.

also
Code:
gcc -c test.c
gcc -c vector.c

zum Kompilieren
und dann
Code:
gcc -o foobar test.o vector.o
zum Linken. Hier musst Du natürlich noch die anderen Bibliotheken anfügen -> -lGL -lGLU sollten reichen...
 
OP
R

ramrod

Newbie
TeXpert: vielen dank. ich glaube, ich bin ein ganzes stueck weitergekommen... und obwohl ich mich jetzt wohl als noch unwissender oute, erscheint ein neues problem, das ich nicht loesen kann... ich habe also die drei verzeichnisse src/ a/ b/ und habe zunaechst alles zu .o kompiliert, ohne es zu linken. hat auch alles wunderbar geklappt. allerdings kommen dann, wenn ich alles zusammenfuegen will via

Code:
g++ -o main *.o ../a/*.o ../b/*.o  -lGL -lGLU

einige "multiple definition" fehler. vielleicht ne idee, woran das liegt? er sagt halt:

Code:
main.o:(.data+0x6): multiple definition of `SPACE'
SceneLoader.o:(.data+0x6): first defined here

aber dieses "SPACE" kommt halt wirklich nur in der datei "SceneLoader.cc" vor...

ich danke mal wieder ;)

martin
 

TeXpert

Guru
das kommt dann von unsaubere Includes würde ich jetzt mal spontan sagen.. und warum kompilierst Du mit dem g++? ich denke Du redest von c-Sourcen?
 
OP
R

ramrod

Newbie
ok... also mit gcc kommen genau dieselben fehlermeldungen... und mit diesem komischen "make" hat es ja auch geklappt. allerdings hat der auch noch irgendwelche .dep-dateien erstellt, faellt mir gerade ein. koennte es was damit zu tun haben?

martin
 

TeXpert

Guru
gcc kann automatisch Abhängigkeiten aufbereiten um passend zu kompilieren, aber dazu muss man mehr über Dein Projekt wissen.

Du solltest Dich in aller Ruhe mit dem gcc-Handbuch auseinandersetzen und überlegen, was Du wie zusammenkompilieren musst. (hast Du etwa noch eigene Bibliotheks-Funktionen gebaut und willst aus teilen noch eigene Libs basteln... etc.
 
OP
R

ramrod

Newbie
HAH, du hattest natuerlich recht! MEINE SCHULD! es funktioniert, es funktioniert!!! danke, mann!!! du weisst ja, man sieht sich immer zweimal im leben! vielleicht kann ich das ja irgendwie wieder gut machen...

martin
 
OP
R

ramrod

Newbie
der gcc scheint probleme damit zu haben, wenn ich variablen in den header-dateien definiere... keine ahnung wieso, aber ich habs in die c-datei verschoben und es lief!
 

TeXpert

Guru
ramrod schrieb:
der gcc scheint probleme damit zu haben, wenn ich variablen in den header-dateien definiere... keine ahnung wieso, aber ich habs in die c-datei verschoben und es lief!
das ist übel :) Stichworte wäre da spontan extern und dann noch: Globale Variablen sind übel ;)
 
Oben