Fehler beim Linken (ld: warning: cannot find entry symbol _start)



  • Hallo,

    ich freunde mich gerade mit make und ld an (bisher habe ich nur Kleinkram mit "g++ -o foo bar.cc" kompiliert. Jetzt steht etwas größeres an und versuche mich mit make und ld. Hier ein einfaches Beispiel:

    foo.h:

    #ifndef __FOO_H
    #define __FOO_H
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    class Foo
    {
        public:
            Foo();
    };
    
    #ifdef  __cplusplus
    }
    #endif
    
    #endif /* __FOO_H */
    

    foo.cc:

    #include <iostream>
    #include "foo.h"
    
    using namespace std;
    
    Foo::Foo()
    {
        cout << "constructor" << endl;
    }
    

    main.cc:

    #include "foo.h"
    
    int main(int argc, char *argv[])
    {
        Foo *f = new Foo();
    
        return(0);
    }
    

    Ein 'g++ -o foo main.cc foo.cc' funktioniert einwandfrei.
    Bei 'g++ -c main.cc foo.cc; ld -o foo main.o foo.o' bekomme ich folgende Meldung:

    ld: warning: cannot find entry symbol _start; defaulting to 0000000008048094

    Nach einigem googlen interpretiere ich das so, daß ld vergeblich nach main() sucht. Wirklich verstehen tue ich es aber nicht.

    Kann mir da jemand einen Tip geben? Sorry für die Anfängerfrage und danke im voraus.

    Gruß, psd



  • Kurz und knapp:
    Wenn du g++ oder gcc als Linker-Frontend benutzt, werden zusätzliche Objekte und Bibliotheken (z.B. Startup-Code, C-Bibliothek, C++-Bibliothek) mitgelinkt. Wenn Du ld direkt aufrufst, wird nur dein reiner Objektcode zusammengelinkt. Da der Startup-Code fehlt, fehlt auch _start (welches widerum main() aufruft).



  • LordJaxom schrieb:

    Kurz und knapp:
    Wenn du g++ oder gcc als Linker-Frontend benutzt, werden zusätzliche Objekte und Bibliotheken (z.B. Startup-Code, C-Bibliothek, C++-Bibliothek) mitgelinkt. Wenn Du ld direkt aufrufst, wird nur dein reiner Objektcode zusammengelinkt. Da der Startup-Code fehlt, fehlt auch _start (welches widerum main() aufruft).

    OK, das leuchtet schonmal ein. Aber wie sieht der korrekte ld-Aufruf aus bzw. was muß ich bei -L und -l alles angeben? Ich habe keine Ahnung, wo _start drinsteckt.

    Danke für die Hilfe.



  • Ersetze einfach "ld" durch "g++". Der weiß dann schon, was dazugelinkt werden muß:

    g++ -o foo main.o foo.o
    


  • tntnet schrieb:

    Ersetze einfach "ld" durch "g++". Der weiß dann schon, was dazugelinkt werden muß:

    g++ -o foo main.o foo.o
    

    Hm, das habe ich ja bereits getan (s.o.). Aber das ist eigentlich nicht, was ich will. Das anstehende Programm besteht aus etlichen Modulen (DB, GUI, ...), die ich gerne einzeln kompilieren und linken möchte. Wenn ich den g++ direkt aufrufe, wird immer alles kompiliert, richtig?

    Ich habe mir mal den Output von g++ -v angeschaut, und mein Makefile um folgende LDFLAGS erweitert, damit klappt es dann:

    LDFLAGS = -L/usr/lib -L/usr/lib/gcc/i586-suse-linux/4.1.2 -dynamic-linker  \
              /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o               \
              /usr/lib/gcc/i586-suse-linux/4.1.2/crtbegin.o -lstdc++ -lm       \
              -lgcc_s -lgcc -lc /usr/lib/gcc/i586-suse-linux/4.1.2/crtend.o    \
              /usr/lib/crtn.o
    

    Danke an euch beide für die Tips.



  • neee, schau dir mal an wie er g++ aufgerufen hat. Der linkt dann schon vernünftig wenn du nur Objekt-Dateien übergibst.



  • psd schrieb:

    tntnet schrieb:

    Ersetze einfach "ld" durch "g++". Der weiß dann schon, was dazugelinkt werden muß:

    g++ -o foo main.o foo.o
    

    Hm, das habe ich ja bereits getan (s.o.). Aber das ist eigentlich nicht, was ich will. Das anstehende Programm besteht aus etlichen Modulen (DB, GUI, ...), die ich gerne einzeln kompilieren und linken möchte. Wenn ich den g++ direkt aufrufe, wird immer alles kompiliert, richtig?

    Falsch. Nochmal ausführlich:

    g++ -c main.cpp
    g++ -c foo.cpp
    g++ -o foo main.o foo.o
    

    Das sind 3 Kommandos, die unabhängig voneinander ausgeführt werden können. Wenn Du foo.cpp änderst, brauchst Du das erste Kommando nicht auszuführen. Bei mehr als 2 Dateien wird das natürlich schwierig, was wann übersetzt werden muß. Daher hat man make erfunden.



  • OK, jetzt ist der Groschen gefallen. Dann kann ich mich jetzt über meine Makefiles hermachen. Danke an alle. 🙂


Anmelden zum Antworten