Linkerfehler - Boost/Linux



  • Hallo allseits,

    ich habe ein ganz merkwürdiges Problem mit Boost unter Linux (Ubuntu 14.04) - ich bekomme eine Reihe von Linkerfehlern obwohl ich die Libraries beim compilen mitangegeben habe und Boost korrekt installiert ist. Hat jemand einen Tip für mich, was ich falsch mache?

    Das Programm kompiliert ohne Fehler oder Warnungen, daher liegt es glaube ich nicht am Source Code. Ich kompiliere mit:

    g++ -lboost_thread -lboost_system dev.cpp main.cpp
    

    Die Ausgabe davon ist länger, siehe ganz unten im Post.
    Das komische ist, dass er sich über Libraries beschwert, die ich explizit beim compilen angegeben habe ("undefined reference to boost::system::[...]" trotz -lboost_system). Ich dachte also, vielleicht ist Boost nicht richtig installiert, aber ein

    sudo apt-get install libboost-all-dev
    

    gibt mir

    libboost-all-dev is already the newest version.
    

    Außerdem beschwert sich der Linker nicht, dass er z.b. libboost_system nicht finden kann.

    Die g++-Version ist 4.8.2. Das Programm ist zu Testzwecken schon recht minimal, ich habe nur einen Thread, in dem ein Zeitstempel erstellt wird, und ein boost::tuple<>; dies gekapselt in einer Klasse (dev.cpp), die einmal instanziert wird (main.cpp). Ich kann den Source Code auch posten.
    Der komplette Output des Linkers:

    ~/dev/boostest$ g++ -lboost_thread -lboost_system dev.cpp main.cpp
    /tmp/ccfodwgK.o: In function `__static_initialization_and_destruction_0(int, int)':
    dev.cpp:(.text+0x275): undefined reference to `boost::system::generic_category()'
    dev.cpp:(.text+0x281): undefined reference to `boost::system::generic_category()'
    dev.cpp:(.text+0x28d): undefined reference to `boost::system::system_category()'
    /tmp/ccfodwgK.o: In function `boost::thread_exception::thread_exception(int, char const*)':
    dev.cpp:(.text._ZN5boost16thread_exceptionC2EiPKc[_ZN5boost16thread_exceptionC5EiPKc]+0x14): undefined reference to `boost::system::system_category()'
    /tmp/ccfodwgK.o: In function `boost::detail::thread_data_base::thread_data_base()':
    dev.cpp:(.text._ZN5boost6detail16thread_data_baseC2Ev[_ZN5boost6detail16thread_data_baseC5Ev]+0x24): undefined reference to `vtable for boost::detail::thread_data_base'
    /tmp/ccfodwgK.o: In function `boost::this_thread::sleep(boost::posix_time::ptime const&)':
    dev.cpp:(.text._ZN5boost11this_thread5sleepERKNS_10posix_time5ptimeE[_ZN5boost11this_thread5sleepERKNS_10posix_time5ptimeE]+0x28): undefined reference to `boost::this_thread::hiden::sleep_until(timespec const&)'
    /tmp/ccfodwgK.o: In function `boost::thread::start_thread()':
    dev.cpp:(.text._ZN5boost6thread12start_threadEv[_ZN5boost6thread12start_threadEv]+0x15): undefined reference to `boost::thread::start_thread_noexcept()'
    /tmp/ccfodwgK.o: In function `boost::thread::~thread()':
    dev.cpp:(.text._ZN5boost6threadD2Ev[_ZN5boost6threadD5Ev]+0x15): undefined reference to `boost::thread::detach()'
    /tmp/ccfodwgK.o: In function `boost::thread::get_id() const':
    dev.cpp:(.text._ZNK5boost6thread6get_idEv[_ZNK5boost6thread6get_idEv]+0x18): undefined reference to `boost::thread::native_handle()'
    /tmp/ccfodwgK.o: In function `boost::thread::join()':
    dev.cpp:(.text._ZN5boost6thread4joinEv[_ZN5boost6thread4joinEv]+0x6d): undefined reference to `boost::thread::join_noexcept()'
    /tmp/ccfodwgK.o: In function `boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, mynamespace::Boostest>, boost::_bi::list1<boost::_bi::value<mynamespace::Boostest*> > > >::~thread_data()':
    dev.cpp:(.text._ZN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0IvN11mynamespace8BoostestEEENS2_5list1INS2_5valueIPS7_EEEEEEED2Ev[_ZN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0IvN11mynamespace8BoostestEEENS2_5list1INS2_5valueIPS7_EEEEEEED5Ev]+0x1f): undefined reference to `boost::detail::thread_data_base::~thread_data_base()'
    /tmp/ccfodwgK.o:(.rodata._ZTIN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0IvN11mynamespace8BoostestEEENS2_5list1INS2_5valueIPS7_EEEEEEEE[_ZTIN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0IvN11mynamespace8BoostestEEENS2_5list1INS2_5valueIPS7_EEEEEEEE]+0x10): undefined reference to `typeinfo for boost::detail::thread_data_base'
    /tmp/ccioMWId.o: In function `__static_initialization_and_destruction_0(int, int)':
    main.cpp:(.text+0xc5): undefined reference to `boost::system::generic_category()'
    main.cpp:(.text+0xd1): undefined reference to `boost::system::generic_category()'
    main.cpp:(.text+0xdd): undefined reference to `boost::system::system_category()'
    collect2: error: ld returned 1 exit status
    

    Danke!

    PS: Der Source Code:

    dev.h

    #ifndef DEV_H_
    #define DEV_H_
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string>
    
    #include <boost/thread.hpp>
    #include <boost/date_time/posix_time/posix_time.hpp>
    #include <boost/tuple/tuple.hpp>
    
    using namespace boost;
    
    namespace mynamespace
    {
        class Boostest
        {
            public:
    			Boostest();
                ~Boostest();            
                void Sending_thread();
                void run();
        };
     }
    
    #endif
    

    dev.cpp

    #include "dev.h"
    
    namespace mynamespace
    {
        Boostest::Boostest() {}
        Boostest::~Boostest() {}
    
    	void Boostest::Sending_thread()
    	{
    		for (int i = 0; i < 255; i++)
    		{
    			boost::this_thread::sleep(boost::posix_time::milliseconds(40));
    		}
    	}
    
        void Boostest::run() 
        {
            thread sending_thread(boost::bind(&Boostest::Sending_thread, this));
            sending_thread.join();
    	}
    }
    

    main.cpp

    #include "dev.h"
    
    using namespace mynamespace;
    
    int main(int argc, char** argv)
    {
    	Boostest bt;
    	bt.run();
    
    	return 0;
    }
    


  • Statische Bibliotheken? Dann müssen sie in der Kommandozeile hinter den cpp stehen.

    32/64 Bit Mischmasch? Korrekte Version installieren.



  • Sind eigentlich alles dynamische Libs, soweit ich weiß. An 32/64 bit habe ich auch schon gedacht, halte ich aber für unwahrscheinlich, da ich einfach libboost-all-dev auf meinem 64-bit-Xubuntu installiert habe - sonst nichts.

    Ich habe jetzt den Buildprozess in Compilen und Linken aufgeteilt, d.h. g++ -c für das Compilen und ld für das Linken. Um die Linker-Commandline zu bekommen, habe ich g++ -v verwendet. Und siehe da - wenn ich den --as-needed - Parameter bei ld weglasse, funktioniert es ohne Probleme!

    Jetzt frage ich mich nur noch, was genau dieser Parameter eigentlich macht bzw. warum ihn g++ verwenden möchte. Aber immerhin funktioniert es erst mal - ich muss allerdings noch testen, ob das gelinkte Programm tatsächlich einwandfrei läuft. Wenn jemand was dazu weiß - bitte gerne melden 🙂 Ansonsten les' ich mal manpages... :p

    Edit: ok, --as-needed verhindert das Linken gegen nicht benutzte Libraries, d.h., auch wenn sie angegeben werden, werden sie nicht gelinkt - was ziemlich genau mein Problem war und auch erklärt, warum g++ die Option verwenden möchte, weil das ja eigentlich eine gute Sache ist, wenn es funktioniert. Nur warum glaubt der Linker (bzw. g++), dass ich die Boost-Libraries eigentlich nicht brauche??



  • Dann probier auch in diesem Fall, die Libs in drr Kommandozeile nach hinten zu schieben. Der Linker bindet auch hier nur Symbole ein, die undefiniert sind. Ohne .cpp oder .o gibt es aber nichts undefiniertes.



  • Tatsächlich, das war's 🙂 Wieder was gelernt. Danke!


Anmelden zum Antworten