How to compile with third party libs properly?

7,920

The correct invocation according to the directory listings you gave would be:

-L/usr/local/lib/boost1.55/lib/ -lboost_system

-L is used to specify the path where libraries are found. -I is for headers, that will not help for linker errors (you'll get compiler errors if you're missing include paths).

As for boost_system versus boost_system-mgw46-mt-sd-1_54 - you don't have anything called "boost_system-mgw46-mt-sd-1_54.so[.version]" in your library directory, so you can't use that second name.

(You also have Windows-type paths in your Makefile - try and avoid mixing the two, use conditionals in your Makefiles to separate Windows and Unix paths.)

Share:
7,920

Related videos on Youtube

Bevor
Author by

Bevor

Updated on September 18, 2022

Comments

  • Bevor
    Bevor almost 2 years

    This is a follow up question to Confusion about linking boost library while compilation:

    What is to do, when I generate a Makefile by qmake and I have only a third party boost lib installed (I uninstalled all boost libs from dependency management, because it always links to the boost lib from dependency management what I don't want) and I want it to compile only against this manually installed library as well as run against it.

    These are the important parts of a Makefile generated by qmake:

    CC            = gcc
    CXX           = g++
    DEFINES       = -DQT_GUI -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -DBOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN -D__NO_SYSTEM_INCLUDES -DUSE_UPNP=1 -DSTATICLIB -DUSE_QRCODE -DUSE_DBUS -DHAVE_BUILD_INFO -DLINUX -DQT_NO_DEBUG -DQT_DBUS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
    CFLAGS        = -m64 -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)
    CXXFLAGS      = -m64 -pipe -fstack-protector -O2 -fdiagnostics-show-option -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter -D_REENTRANT $(DEFINES)
    INCPATH       = -I/usr/share/qt4/mkspecs/linux-g++-64 -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtDBus -I/usr/include/qt4 -Isrc -Isrc/json -Isrc/qt -IC:/deps/ -IC:/deps/boost -Ic:/deps/db/build_unix -Ic:/deps/ssl/include -IC:/deps/libqrencode/ -Ibuild -Ibuild
    LINK          = g++
    LFLAGS        = -m64 -fstack-protector -Wl,-O1
    LIBS          = $(SUBLIBS)  -L/usr/lib/x86_64-linux-gnu -LC:/deps/miniupnpc -lminiupnpc -lqrencode -lrt -LC:/deps/boost/stage/lib -Lc:/deps/db/build_unix -Lc:/deps/ssl -LC:/deps/libqrencode/.libs -lssl -lcrypto -ldb_cxx -lboost_system-mgw46-mt-sd-1_54 -lboost_filesystem-mgw46-mt-sd-1_54 -lboost_program_options-mgw46-mt-sd-1_54 -lboost_thread-mgw46-mt-sd-1_54 -lQtDBus -lQtGui -lQtCore -lpthread 
    

    This is the path to boost:

    /usr/local/lib/boost1.55/lib# ls -1
    libboost_atomic.a
    libboost_atomic.so
    libboost_atomic.so.1.55.0
    libboost_chrono.a
    libboost_chrono.so
    libboost_chrono.so.1.55.0
    libboost_context.a
    libboost_context.so
    libboost_context.so.1.55.0
    libboost_coroutine.a
    libboost_coroutine.so
    libboost_coroutine.so.1.55.0
    libboost_date_time.a
    libboost_date_time.so
    libboost_date_time.so.1.55.0
    libboost_exception.a
    libboost_filesystem.a
    libboost_filesystem.so
    libboost_filesystem.so.1.55.0
    libboost_graph.a
    libboost_graph.so
    libboost_graph.so.1.55.0
    libboost_locale.a
    libboost_locale.so
    libboost_locale.so.1.55.0
    libboost_log.a
    libboost_log_setup.a
    libboost_log_setup.so
    libboost_log_setup.so.1.55.0
    libboost_log.so
    libboost_log.so.1.55.0
    libboost_math_c99.a
    libboost_math_c99f.a
    libboost_math_c99f.so
    libboost_math_c99f.so.1.55.0
    libboost_math_c99l.a
    libboost_math_c99l.so
    libboost_math_c99l.so.1.55.0
    libboost_math_c99.so
    libboost_math_c99.so.1.55.0
    libboost_math_tr1.a
    libboost_math_tr1f.a
    libboost_math_tr1f.so
    libboost_math_tr1f.so.1.55.0
    libboost_math_tr1l.a
    libboost_math_tr1l.so
    libboost_math_tr1l.so.1.55.0
    libboost_math_tr1.so
    libboost_math_tr1.so.1.55.0
    libboost_prg_exec_monitor.a
    libboost_prg_exec_monitor.so
    libboost_prg_exec_monitor.so.1.55.0
    libboost_program_options.a
    libboost_program_options.so
    libboost_program_options.so.1.55.0
    libboost_random.a
    libboost_random.so
    libboost_random.so.1.55.0
    libboost_regex.a
    libboost_regex.so
    libboost_regex.so.1.55.0
    libboost_serialization.a
    libboost_serialization.so
    libboost_serialization.so.1.55.0
    libboost_signals.a
    libboost_signals.so
    libboost_signals.so.1.55.0
    libboost_system.a
    libboost_system.so
    libboost_system.so.1.55.0
    libboost_test_exec_monitor.a
    libboost_thread.a
    libboost_thread.so
    libboost_thread.so.1.55.0
    libboost_timer.a
    libboost_timer.so
    libboost_timer.so.1.55.0
    libboost_unit_test_framework.a
    libboost_unit_test_framework.so
    libboost_unit_test_framework.so.1.55.0
    libboost_wave.a
    libboost_wave.so
    libboost_wave.so.1.55.0
    libboost_wserialization.a
    libboost_wserialization.so
    libboost_wserialization.so.1.55.0
    

    This is the output of ldconfig -v concerning boost:

    # ldconfig -v
    /sbin/ldconfig.real: Path `/lib/x86_64-linux-gnu' given more than once
    /sbin/ldconfig.real: Path `/usr/lib/x86_64-linux-gnu' given more than once
    /usr/local/lib/boost1.55/lib:
        libboost_wave.so.1.55.0 -> libboost_wave.so.1.55.0
        libboost_thread.so.1.55.0 -> libboost_thread.so.1.55.0
        libboost_system.so.1.55.0 -> libboost_system.so.1.55.0
        libboost_prg_exec_monitor.so.1.55.0 -> libboost_prg_exec_monitor.so.1.55.0
        libboost_context.so.1.55.0 -> libboost_context.so.1.55.0
        libboost_atomic.so.1.55.0 -> libboost_atomic.so.1.55.0
        libboost_filesystem.so.1.55.0 -> libboost_filesystem.so.1.55.0
        libboost_math_c99l.so.1.55.0 -> libboost_math_c99l.so.1.55.0
        libboost_math_c99.so.1.55.0 -> libboost_math_c99.so.1.55.0
        libboost_timer.so.1.55.0 -> libboost_timer.so.1.55.0
        libboost_wserialization.so.1.55.0 -> libboost_wserialization.so.1.55.0
        libboost_math_c99f.so.1.55.0 -> libboost_math_c99f.so.1.55.0
        libboost_coroutine.so.1.55.0 -> libboost_coroutine.so.1.55.0
        libboost_signals.so.1.55.0 -> libboost_signals.so.1.55.0
        libboost_random.so.1.55.0 -> libboost_random.so.1.55.0
        libboost_chrono.so.1.55.0 -> libboost_chrono.so.1.55.0
        libboost_program_options.so.1.55.0 -> libboost_program_options.so.1.55.0
        libboost_date_time.so.1.55.0 -> libboost_date_time.so.1.55.0
        libboost_locale.so.1.55.0 -> libboost_locale.so.1.55.0
        libboost_log.so.1.55.0 -> libboost_log.so.1.55.0
        libboost_log_setup.so.1.55.0 -> libboost_log_setup.so.1.55.0
        libboost_serialization.so.1.55.0 -> libboost_serialization.so.1.55.0
        libboost_math_tr1f.so.1.55.0 -> libboost_math_tr1f.so.1.55.0
        libboost_unit_test_framework.so.1.55.0 -> libboost_unit_test_framework.so.1.55.0
        libboost_math_tr1l.so.1.55.0 -> libboost_math_tr1l.so.1.55.0
        libboost_graph.so.1.55.0 -> libboost_graph.so.1.55.0
        libboost_math_tr1.so.1.55.0 -> libboost_math_tr1.so.1.55.0
        libboost_regex.so.1.55.0 -> libboost_regex.so.1.55.0
    

    What do I have exactly to do to compile and run the code properly? I tried combinations of:

    -L/usr/local/lib/boost1.55/lib/boost_thread-mgw46-mt-sd-1_54
    -L/usr/local/lib/boost1.55/lib/boost_thread
    -I/usr/local/lib/boost1.55/
    -I/usr/local/lib/boost1.55/lib/
    -lboost_system-mgw46-mt-sd-1_54
    -lboost_system-mgw46-mt-sd-1_55
    -lboost_system
    

    All this NEVER works when there is no boost installed by package manager, but I don't want it to use it from package manager. That means it doesn't compile. Sometimes I get something like:

    /usr/bin/ld: cannot find -lboost_system-mgw46-mt-sd-1_54
    

    or

    /usr/bin/ld: cannot find -lboost_system
    

    or

    addrman.cpp:(.text.startup+0x23): undefined reference to `boost::system::generic_category()'
    

    ...and so on.

    I don't get it. What's wrong here?

    [UPDATE]
    It turns out that there seems to be something wrong with boost lib itself. After modifying the important parts of the makefile to:

    LIBS          = $(SUBLIBS)  -L/usr/lib/x86_64-linux-gnu -lminiupnpc -lqrencode -lrt -lssl -lcrypto -ldb_cxx -L/usr/local/lib/boost1.55/ -L/usr/local/lib/boost1.55/include/ -L/usr/local/lib/boost1.55/lib/ -lboost_system -lboost_filesystem -lboost_program_options -lpthread -lboost_thread -lQtDBus -lQtGui -lQtCore
    

    make produced another error:

    build/json_spirit_reader.o: In function `void boost::call_once<void (*)()>(boost::once_flag&, void (*)())':
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0x14): undefined reference to `boost::detail::get_once_per_thread_epoch()'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0x2c): undefined reference to `boost::detail::once_epoch_mutex'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0x35): undefined reference to `boost::detail::once_epoch_mutex'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0x72): undefined reference to `boost::detail::once_epoch_mutex'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0x77): undefined reference to `boost::detail::once_epoch_cv'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0xa8): undefined reference to `boost::detail::once_epoch_mutex'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0xb0): undefined reference to `boost::detail::once_epoch_mutex'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0xd9): undefined reference to `boost::detail::once_global_epoch'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0xde): undefined reference to `boost::detail::once_epoch_cv'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0xe9): undefined reference to `boost::detail::once_global_epoch'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0x128): undefined reference to `boost::detail::once_global_epoch'
    json_spirit_reader.cpp:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[_ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_]+0x19b): undefined reference to `boost::detail::once_epoch_cv'
    collect2: error: ld returned 1 exit status
    

    It seems that there is no such function (in this boost version?):

    $ objdump -T /usr/local/lib/boost1.55/lib/libboost_thread.so|c++filt|grep once_epoch
    

    prints nothing as well as

    $ for i in /usr/local/lib/boost1.55/lib/libboost_*.so ; do if grep once_epoch_mutex <(objdump -T $i|c++filt) ; then echo $i ; fi ; done
    

    does not.

    [UPDATE 2]
    After adding

    -I/usr/local/lib/boost1.55/include/ -I/usr/local/lib/boost1.55/include/boost/
    

    to INCPATH and recompile the whole application within a fresh workspace, the error is different but now, I don't see any error message:

    /usr/local/lib/boost1.55/include/boost/bind/arg.hpp: In constructor ‘boost::arg<I>::arg(const T&)’:
    /usr/local/lib/boost1.55/include/boost/bind/arg.hpp:37:22: warning: typedef ‘T_must_be_placeholder’ locally defined but not used [-Wunused-local-typedefs]
             typedef char T_must_be_placeholder[ I == is_placeholder<T>::value? 1: -1 ];
                          ^
    In file included from /usr/local/lib/boost1.55/include/boost/tuple/tuple.hpp:33:0,
                     from /usr/local/lib/boost1.55/include/boost/thread/detail/async_func.hpp:37,
                     from /usr/local/lib/boost1.55/include/boost/thread/future.hpp:22,
                     from /usr/local/lib/boost1.55/include/boost/thread.hpp:24,
                     from src/util.h:22,
                     from src/bignum.h:13,
                     from src/main.h:9,
                     from src/wallet.h:9,
                     from src/wallet.cpp:7:
    /usr/local/lib/boost1.55/include/boost/tuple/detail/tuple_basic.hpp: In function ‘typename boost::tuples::access_traits<typename boost::tuples::element<N, boost::tuples::cons<HT, TT> >::type>::const_type boost::tuples::get(const boost::tuples::cons<HT, TT>&)’:
    /usr/local/lib/boost1.55/include/boost/tuple/detail/tuple_basic.hpp:228:45: warning: typedef ‘cons_element’ locally defined but not used [-Wunused-local-typedefs]
       typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
                                                 ^
    src/wallet.cpp: In member function ‘bool CWallet::AddToWallet(const CWalletTx&)’:
    src/wallet.cpp:402:13: error: ‘replace_all’ is not a member of ‘boost’
                 boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
                 ^
    In file included from /usr/local/lib/boost1.55/include/boost/system/system_error.hpp:14:0,
                     from /usr/local/lib/boost1.55/include/boost/thread/exceptions.hpp:22,
                     from /usr/local/lib/boost1.55/include/boost/thread/pthread/thread_data.hpp:10,
                     from /usr/local/lib/boost1.55/include/boost/thread/thread_only.hpp:17,
                     from /usr/local/lib/boost1.55/include/boost/thread/thread.hpp:12,
                     from /usr/local/lib/boost1.55/include/boost/thread.hpp:13,
                     from src/util.h:22,
                     from src/bignum.h:13,
                     from src/main.h:9,
                     from src/wallet.h:9,
                     from src/wallet.cpp:7:
    /usr/local/lib/boost1.55/include/boost/system/error_code.hpp: At global scope:
    /usr/local/lib/boost1.55/include/boost/system/error_code.hpp:222:36: warning: ‘boost::system::posix_category’ defined but not used [-Wunused-variable]
         static const error_category &  posix_category = generic_category();
                                        ^
    /usr/local/lib/boost1.55/include/boost/system/error_code.hpp:223:36: warning: ‘boost::system::errno_ecat’ defined but not used [-Wunused-variable]
         static const error_category &  errno_ecat     = generic_category();
                                        ^
    /usr/local/lib/boost1.55/include/boost/system/error_code.hpp:224:36: warning: ‘boost::system::native_ecat’ defined but not used [-Wunused-variable]
         static const error_category &  native_ecat    = system_category();
                                        ^
    make: *** [build/wallet.o] Error 1
    
    • Bevor
      Bevor over 10 years
      I rebuilt the whole project, but now I have another error (see my updated question).
    • Mat
      Mat over 10 years
      error: ‘replace_all’ is not a member of ‘boost’
    • Mat
      Mat over 10 years
      You've got boost version problems, what you have and what that code expects doesn't appear to match. You'll need to sort that out.
    • Bevor
      Bevor over 10 years
      I didn't look careful enough to see the error. Nevertheless I was able to manage it by adding #include <boost/algorithm/string.hpp> into a specific header file. It works now, I'm finally able to compile it. Thanks.
  • Bevor
    Bevor over 10 years
    If I do this, I get: undefined reference to boost::detail::once_epoch_mutex' while "make". I wonder why there isn't such library in boost directory. Moreover, if I omit the boost flags -mgw46-mt-sd-1_54 how can I set it as described here: boost.org/doc/libs/1_47_0/more/getting_started/…
  • Mat
    Mat over 10 years
    That thing is probably in the boost_thread library, add that too.
  • Bevor
    Bevor over 10 years
    There is also a directory /usr/local/lib/boost1.55/include/boost/ with a lot of header files. I tried to add -I/usr/local/lib/boost1.55/include/boost/ to INCPATH in the makefile but error is still the same. Is there something else to do?
  • Mat
    Mat over 10 years
    Don't confuse compile errors with linker errors. If you get "undefined references", that's linker errors. The compiler is done already, adding include paths will not help. You need to look at each undefined reference, find what library it belongs to, and add that library. (And the missing reference in your first comment is indeed in boost_thread)
  • Bevor
    Bevor over 10 years
    Thanks, but I don't understand how. I already linked the directory which contains thread by -L/usr/local/lib/boost1.55/lib/. I also tried -L/usr/local/lib/boost1.55/lib/libboost_thread or -L/usr/local/lib/boost1.55/lib/boost_thread but nothing changes. The directory contains libboost_thread.a, libboost_thread.so and libboost_thread.so.1.55.0
  • Mat
    Mat over 10 years
    Please re-read what I said above. -L is for paths, -l for library names. -L alone doesn't do anything, the linker will never attempt to link all the libraries in a path. Just add -lboost_thread after what I put above.
  • Bevor
    Bevor over 10 years
    Yes, but it is already linked. Or is there any special order I have to follow? It looks like this now: -L/usr/local/lib/boost1.55/lib/ -lboost_system -lboost_filesystem -lboost_program_options -lboost_thread
  • Mat
    Mat over 10 years
    Yes order is important, but what you have above looks good. Is it still that same symbol that's unresolved?
  • Bevor
    Bevor over 10 years
    Yes it is, I've never changed something except we discussed. I just read that it could depend on missing -lpthread but it's also there. I also read something about -lboost_thread-mt, but this doesn't exist. Adding it would end up in "cannot find -lboost_thread-mt".
  • Mat
    Mat over 10 years
    run objdump -T /usr/lib/.../libboost_thread.so|c++filt|grep once_epoch and tell us what it outputs
  • Bevor
    Bevor over 10 years
    When I execute it on $ objdump -T /usr/local/lib/boost1.55/lib/libboost_thread.so|c++filt|grep once_epoch it prints just nothing.
  • Mat
    Mat over 10 years
    Well that's a problem. Try to run for i in /usr/lib/.../libboost_*.so ; do if grep once_epoch_mutex <(objdump -T $i|c++filt) ; then echo $i ; fi ; done. (Edit your question to post the output.)
  • Bevor
    Bevor over 10 years
    Ok, I updated the question. Seems that there is no such function, although it is the latest boost version.