Markus Pitha: Vorhandene C Bibliothek ist vorhanden, aber nicht einbindbar?

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.

--
sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|
  1. 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

    1. 你好 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 status

      Hast 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"

      再见,
      克里斯蒂安

      --
      Nichts zu begehren, das ist der Weg.
      1. 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

        1. 你好 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 ;-)

          再见,
          克里斯蒂安

          --
          Die Wirklichkeit hat weder ein Inneres, noch ein Äußeres, noch ein Zentrum.
    2. 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.

      --
      sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|
      1. 你好 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 ;-)

        再见,
        克里斯蒂安

        --
        Willst du die Freuden dieser Welt geniessen, so musst du auch ihr Leid erdulden.
        1. Hallo,

          gcc -std=c99 -o pixel pixel.c sdl-config --clfags --libs

          Das 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

          ..wobei DrawPixel eine von SDL_endian.h verwendete Funktion ist.

          Markus.

          --
          sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|
          1. 你好 Markus,

            gcc -std=c99 -o pixel pixel.c sdl-config --clfags --libs

            Das 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 :)

            再见,
            克里斯蒂安

            --
            Kommt ein Vektor zur Drogenberatung: "Hilfe, ich bin linear abhaengig!"
            1. 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.

              --
              sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|
              1. 你好 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.

                再见,
                克里斯蒂安

                --
                Ich bewundere wirklich den Sinn der Bienen für kollektive Verantwortung. Obwohl sich einzelne Bienen hin und wieder bekämpfen, herrscht zwischen Ihnen grundsätzlich ein starkes Gefühl für Eintracht und Zusammenarbeit. Wir Menschen gelten als sehr viel weiter entwickelt, doch mitunter rangieren wir sogar hinter kleinen Insekten.
                1. 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.

                  --
                  sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|
                  1. Hallo Markus,

                    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?

                    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

                    1. 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.

                      1. 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

                        1. Hallo,
                          ich glaube jetzt ist mir einiges klarer, danke für die Hilfe.

                          Markus.

                          --
                          sh:( fo:| ch:? rl:( br:> n4:( ie:{ mo:) va:) de:] zu:) fl:( ss:| ls:] js:|