2

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
  • 671
  • 2
  • 11
  • 22
  • Try to do a clean build. Or rebuild whatever it is that contains that `json_spirit_reader.cpp` if that's not in your project. – Mat Dec 08 '13 at 14:53
  • I rebuilt the whole project, but now I have another error (see my updated question). – Bevor Dec 08 '13 at 16:45
  • error: ‘replace_all’ is not a member of ‘boost’ – Mat Dec 08 '13 at 16:46
  • 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. – Mat Dec 08 '13 at 16:47
  • I didn't look careful enough to see the error. Nevertheless I was able to manage it by adding #include into a specific header file. It works now, I'm finally able to compile it. Thanks. – Bevor Dec 08 '13 at 18:02

1 Answers1

4

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

Mat
  • 51,578
  • 10
  • 158
  • 140
  • 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: http://www.boost.org/doc/libs/1_47_0/more/getting_started/unix-variants.html#link-your-program-to-a-boost-library – Bevor Dec 08 '13 at 12:54
  • That thing is probably in the `boost_thread` library, add that too. – Mat Dec 08 '13 at 12:59
  • 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? – Bevor Dec 08 '13 at 13:22
  • 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) – Mat Dec 08 '13 at 13:23
  • 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 – Bevor Dec 08 '13 at 13:52
  • 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. – Mat Dec 08 '13 at 13:54
  • 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 – Bevor Dec 08 '13 at 14:05
  • Yes order is important, but what you have above looks good. Is it still that same symbol that's unresolved? – Mat Dec 08 '13 at 14:11
  • 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". – Bevor Dec 08 '13 at 14:22
  • run `objdump -T /usr/lib/.../libboost_thread.so|c++filt|grep once_epoch` and tell us what it outputs – Mat Dec 08 '13 at 14:27
  • 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. – Bevor Dec 08 '13 at 14:32
  • 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.) – Mat Dec 08 '13 at 14:37
  • Ok, I updated the question. Seems that there is no such function, although it is the latest boost version. – Bevor Dec 08 '13 at 14:50