Vorhandene C Bibliothek ist vorhanden, aber nicht einbindbar?
Markus Pitha
- sonstiges
Hallo,
ich habe ein ganz seltsames Problem, habe auch schon im Gentoo Forum gepostet, aber seit Stunden keine Antwort erhalten.
In einem Programm binde ich folgende Headerdateien ein.
#include <stdlib.h>
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_endian.h"
.
.
und kompiliere es mit
gcc -std=c99 -o sdl_pixel sdl_pixel.c -lSDL -lSDL_image -lSDL_endian
....erzeugt wird bei der Kompilierung folgenden Fehler:
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/../../../../i686-pc-linux-gnu/bin/ld: cannot find -lSDL_endian
collect2: ld returned 1 exit status
..obwohl der Befehl locate SDL_endian.h
/usr/include/SDL/SDL_endian.h
ausgibt.
SDL.h ist übrigens auch im SELBEN Verzeichnis, und diese Bibliothek funktioniert aber einzubinden. Warum kann also SDL_endian.h nicht gefunden werden, obwohl andere SDL_Bibliotheken, die im selben Verzeichnis sind, gefunden werden? Ich kann mir das überhaupt nicht erklären? Die Rechte und Eigentümer aller sich in dem SDL Verzeichnis befindenden Headerdateien sind übrigens gleich.
Irgendwelche Ideen?
Markus.
Hi,
ich habe ein ganz seltsames Problem, habe auch schon im Gentoo Forum gepostet, aber seit Stunden keine Antwort erhalten.
Ja, das kann ich mir gut vorstellen ;-)
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/../../../../i686-pc-linux-gnu/bin/ld: cannot find -lSDL_endian
collect2: ld returned 1 exit status
Hast Du denn die Bibliothek LibSDL_endian im Pfad?
..obwohl der Befehl locate SDL_endian.h
/usr/include/SDL/SDL_endian.h
ausgibt.
Das ist nicht Ursache der Fehlermeldung, den Header hat er gefunden, nur die Bibliothek nicht.
Irgendwelche Ideen?
gcc -std=c99 -I/usr/include -L/usr/lib -o sdl_pixel sdl_pixel.c -lSDL -lSDL_image -lSDL_endian
Da ich aber nicht weiß, wo Du die Libs hingeschmissen hast, müßtest Du die Pfade halt entsprechend anpassen. Wenn Du die libSDL_endian frisch installiert hast, könnte auch ein ldconfig als root ausgeführt helfen. ('ldconfig -v | grep SDL' zwecks Überprüfung).
Wenn dann immer noch die gleichen Fehlermeldungen kommen ist höchstwahrscheinlich die Installation der Lib danebengegangen.
Äh ... halt ... Moooment. Meintest Du etwa diese Datei?
Die gehört zur Lib, da ist kein main() drin, das kannst Du eh nicht ohne Änderungen Standalone bauen.
so short
Christoph Zurnieden
你好 Christoph,
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/../../../../i686-pc-linux-gnu/bin/ld: cannot find -lSDL_endian
collect2: ld returned 1 exit statusHast Du denn die Bibliothek LibSDL_endian im Pfad?
Nicht im Pfad. Fuer Bibliotheks-Pfade gibt es den -L-Switch. Wenn der nicht
angegeben wird, werden nur die Pfade aus /etc/ld.so.conf auf die Bibliothek
hin durchsucht.
Wenn die Binary dann nicht statisch gebunden wird oder der Bibliothekspfad
nicht mit -rpath angegeben wird, brauchts zur Laufzeit dann noch
LD_LIBRARY_PATH, die dem Runtime-Linker angibt, welche Pfade er zusaetzlich
durchsuchen soll. Standardmaessig leer, womit nur die Verzeichnisse in
/etc/ld.so.conf durchsucht werden, ansonsten ist die Syntax wie immer:
LD_LIBRARY_PATH="PATH1:PATH2:PATH3"
再见,
克里斯蒂安
Hi,
Hast Du denn die Bibliothek LibSDL_endian im Pfad?
Nicht im Pfad.
Wohl im Pfad.
Aber nicht in der Umgebungsvariablen PATH, klar.
Hey, sich mit mir zu beckmessern braucht's schon ein klein wenig mehr! ;-)
so short
Christoph Zurnieden
你好 Christoph,
Hast Du denn die Bibliothek LibSDL_endian im Pfad?
Nicht im Pfad.Wohl im Pfad.
Aber nicht in der Umgebungsvariablen PATH, klar.
"Pfad" wird eigentlich nur der Inhalt der Umgebungsvariablen PATH
genannt ;-)
再见,
克里斯蒂安
Hi,
Hast Du denn die Bibliothek LibSDL_endian im Pfad?
Also in /usr/lib gibt es keine Bibliothek diesen Namens. Was mich hierbei wundert ist, dass doch SDL_endian.h keine extra installierte Bibliothek ist, sondern bei der Standardinstallation von libsdl dabei ist. Ich habe übrigens bereits ein libsdl Update gemacht, wobei das Problem aber weiterhin besteht. Ich glaube somit nicht an einen Installationsfehler.
Es exisitiert offensichtlich nur eine Headerdatei.
gcc -std=c99 -I/usr/include -L/usr/lib -o sdl_pixel sdl_pixel.c -lSDL -lSDL_image -lSDL_endian
Da ich aber nicht weiß, wo Du die Libs hingeschmissen hast, müßtest Du die Pfade halt entsprechend anpassen. Wenn Du die libSDL_endian frisch installiert hast, könnte auch ein ldconfig als root ausgeführt helfen. ('ldconfig -v | grep SDL' zwecks Überprüfung).
Wie gesagt, offensichtlich gibt es hier nur eine Headerdatei namens SDL_endian.h
Äh ... halt ... Moooment. Meintest Du etwa diese Datei?
Die gehört zur Lib, da ist kein main() drin, das kannst Du eh nicht ohne Änderungen Standalone bauen.
Nein. Meine Datei hat nur zufälligerweise einen ähnlichen Namen, aber habe sie jetzt mal nach pixel.c umbenannt, aber damit hat es nichts zu tun.
Markus.
你好 Markus,
Hast Du denn die Bibliothek LibSDL_endian im Pfad?
Also in /usr/lib gibt es keine Bibliothek diesen Namens. Was mich
hierbei wundert ist, dass doch SDL_endian.h keine extra
installierte Bibliothek ist, sondern bei der Standardinstallation von
libsdl dabei ist.
Du musst erstmal unterscheiden lernen: es gibt Header-Dateien und es gibt
Bibliotheken. Header-Dateien sind das, was du ueber #include-Anweisungen
einbindest, Bibliotheken sind das, was du ueber -l-Compiler-Switches an
deine Binary bindest (linkst). Die Header-Dateien definieren das Interface
zur Bibliothek, die Bibliothek selber ist die Implementation. Deshalb ist
SDL_endian.h auch keine Bibliothek, sondern eine Header-Datei aus der
SDL-Paket. Und die Bibliothek, die du an deine Binary binden musst, heisst
libSDL. Das gibt den Compiler-Switch -lSDL, -lSDL_endian und -lSDL_image
muessten voellig unnoetig sein, ich glaube nichtmal, dass die existieren.
SDL_endian.h, SDL_image.h und SDL.h duerften verschiedene Teile des
Interfaces zur libSDL definieren.
Whatever, du solltest dir jetzt erstmal angewoehnen, die bei Bibliotheken
idR mitgelieferten config-Scripts zu benutzen, z. B. so:
gcc -std=c99 -o pixel pixel.c sdl-config --clfags --libs
Wenn du spaeter mit mehreren Source-Dateien arbeitest, solltest du dir
angewoehnen, erst den Object-Code anzulegen und hinterher alles
zusammenzubinden, z.B. in einer Makefile:
.SUFFIXES: .c .o
all: pixel
pixel: pixel1.o pixel2.o pixel3.o
gcc -std=c99 -o pixel pixel1.o pixel2.o pixel3.o `sdl-config --libs`
.c.o:
gcc -std=c99 -c $< `sdl-config --cflags`
Damit ersparst du es dir, dass jedesmal saemtliche Source-Dateien neu
compiliert werden muessen, die muessen dann nur noch gelinkt werden. Ach
ja: am Anfang der Zeile die Einrueckungen, das sind Tabulatoren, bzw.
sollen sein ;-)
再见,
克里斯蒂安
Hallo,
gcc -std=c99 -o pixel pixel.c
sdl-config --clfags --libs
Das funktioniert leider nicht. Es entsteht folgender Fehler beim Kompilieren:
..wobei DrawPixel eine von SDL_endian.h verwendete Funktion ist.
Markus.
你好 Markus,
gcc -std=c99 -o pixel pixel.c
sdl-config --clfags --libsDas funktioniert leider nicht. Es entsteht folgender Fehler beim
Kompilieren:
- /tmp/ccC4HG88.o(.text+0xfc): In function `main':
- undefined reference to `DrawPixel'
collect2: ld returned 1 exit status
Hm, ja, sieht so aus als gaebe es bei SDL noch einen zusaetzlichen Flag,
so dass das dann so aussieht:
gcc -std=c99 -o pixel pixel.c sdl-config --clfags --libs --static-libs
So funktioniert das jetzt bei mir.
..wobei DrawPixel eine von SDL_endian.h verwendete Funktion ist.
Nein, hoechstens eine von SDL_endian.h deklarierte Funktion :)
再见,
克里斯蒂安
Nabend,
gcc -std=c99 -o pixel pixel.c
sdl-config --clfags --libs --static-libs
Auf diese Weise bekomme ich noch 3 Mal mehr Fehler, die in der Fehlerart meines vorigen Postings entsprechen, hmmm.
Das letzte Programm ganz unten auf dieser Seite http://www.pl-berichte.de/work/sdl/sdl-teil1.html will ich eigentlich ausführen, aber dieses Programm ist das einzige hier (aufgrund von SDL_endian.h), das nicht funktioniert.
Markus.
你好 Markus,
Das letzte Programm ganz unten auf dieser Seite http://www.pl-berichte.de/work/sdl/sdl-teil1.html
will ich eigentlich ausführen, aber dieses Programm ist das einzige
hier (aufgrund von SDL_endian.h), das nicht funktioniert.
Ah, hehe, der Fehler liegt woanders. Du hast einfach DrawPixel() nicht
implementiert, die Funktion wird etwas weiter oben erklaert. Wenn du also
die C-Datei jetzt so machst:
#include <stdlib.h>
#include "SDL.h"
#include "SDL_image.h"
// Fuer einen 24-Bit-Modus unabhaengig von der Bytereihenfolge.
// Wird von also DrawPixel() benoetigt
#include "SDL_endian.h"
void DrawPixel(SDL_Surface *screen, int x, int y,Uint8 R, Uint8 G,Uint8 B)
{
Uint32 color = SDL_MapRGB(screen->format, R, G, B);
if ( SDL_MUSTLOCK(screen) )
{
if ( SDL_LockSurface(screen) < 0 ) {
return;
}
}
switch (screen->format->BytesPerPixel) {
case 1: { /* vermutlich 8 Bit */
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
*bufp = color;
}
break;
case 2: { /* vermutlich 15 Bit oder 16 Bit */
Uint16 *bufp;
bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
*bufp = color;
}
break;
case 3: { /* langsamer 24-Bit-Modus, selten verwendet */
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3;
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {
bufp[0] = color;
bufp[1] = color >> 8;
bufp[2] = color >> 16;
} else {
bufp[2] = color;
bufp[1] = color >> 8;
bufp[0] = color >> 16;
}
}
break;
case 4: { /* vermutlich 32 Bit */
Uint32 *bufp;
bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
*bufp = color;
}
break;
}
if ( SDL_MUSTLOCK(screen) )
{
SDL_UnlockSurface(screen);
}
}
int main()
{
SDL_Surface *display;
// init video stuff
if ( SDL_Init( SDL_INIT_VIDEO) < 0 )
{
fprintf(stderr, "SDL konnte nicht initialisiert werden: %s\n",
SDL_GetError());
exit(1);
}
atexit(SDL_Quit);
// init screen
display = SDL_SetVideoMode( 800, 600, 16, SDL_SWSURFACE);
if ( display == NULL )
{
fprintf(stderr, "Konnte kein Fenster 640x480px oeffnen: %s\n",
SDL_GetError());
exit(1);
}
for( int x=0; x < 800; x++ )
{
DrawPixel(display, x, display->h/2, 255, 255, 255);
}
SDL_Flip(display);
SDL_Delay(3000);
return 0;
}
und das dann mit
gcc -std=c99 -o pixel pixel.c sdl-config --clfags --libs
uebersetzt, sollte es dann auch laufen.
再见,
克里斯蒂安
Hallo,
Ah, hehe, der Fehler liegt woanders. Du hast einfach DrawPixel() nicht
implementiert, die Funktion wird etwas weiter oben erklaert. Wenn du also
die C-Datei jetzt so machst:
Mein Gott. Du hast Recht. Ich dachte SDL_endian.h beinhaltet irgendwie die Funktion DrwaPixel, danke.
Noch etwas: Was hat es für einen Sinn mit gcc -std=c99 -o pixel pixel.c sdl-config --clfags --libs zu kompilieren?
gcc -std=c99 -o pixel pixel.c -lSDL -lSDL_image funktioniert auch und ich las es in einem anderen Tutorial so?
Markus.
Hallo Markus,
Noch etwas: Was hat es für einen Sinn mit gcc -std=c99 -o pixel pixel.c
sdl-config --clfags --libszu kompilieren?
gcc -std=c99 -o pixel pixel.c -lSDL -lSDL_image funktioniert auch und ich las es in einem anderen Tutorial so?
Weil sdl-config --cflags --libs alle Compiler- und Linker-Flags ausgibt, die notwendig sind, damit ein Programm mit SDL kompiliert werden kann. Dass es bei Dir mit -lSDL -lSDL_image funktioniert ist toll. Allerdings gibt es keine Garantie, dass das damit funktioniert - auf anderen Systemen müssen eventuell weitere Compiler- und/oder Linkeroptionen angehängt werden. Falls dies mal der Fall sein sollte, brauchst Du Dich - wenn Du sdl-config verwendest - nicht darum zu kümmern, sonst _musst_ Du Dich damit beschäftigen.
Viele Grüße,
Christian
Hallo,
Weil sdl-config --cflags --libs alle Compiler- und Linker-Flags ausgibt, die notwendig sind, damit ein Programm mit SDL kompiliert werden kann.
Wie sieht das eigentlich mit dynamischer Einbindung der Bibliotheken aus? Es wird hier wahrscheinlich nicht berücksichtigt, und die SDL Bibliotheken werden statisch hineinkompiliert, ist das richtig?
Beziehungsweise, wenn ich ...-lSDL -lSDL_image usw... verwende, ist es dann so, dass diese Bibliotheken dynamisch eingebunden werden?
Markus.
Hallo Markus,
Wie sieht das eigentlich mit dynamischer Einbindung der Bibliotheken aus? Es wird hier wahrscheinlich nicht berücksichtigt, und die SDL Bibliotheken werden statisch hineinkompiliert, ist das richtig?
Nein, sie werden idR. dynamisch hineinkompiliert. sdl-config --libs (gib es halt mal ein) dürfte auf Deinem System auch nichts weiteres als -lSDL -lSDL_image oder so ähnlich liefern. Ob sie statisch gelinkt werden, hängt von den weiteren Linkeroptionen ab (-static um genau zu sein). Wenn Du jedoch -static verwendest, musst Du sdl-config auch mit --static-libs aufrufen, da die SDL-Bibliothek auch gegen anderen Bibliotheken gelinkt ist (-lX11 etc.), die bei statischem Linken mit angegeben werden müssen (bei dynamischem nicht).
Beziehungsweise, wenn ich ...-lSDL -lSDL_image usw... verwende, ist es dann so, dass diese Bibliotheken dynamisch eingebunden werden?
Sofern Du kein -static angibst: ja.
Viele Grüße,
Christian
Hallo,
ich glaube jetzt ist mir einiges klarer, danke für die Hilfe.
Markus.