Como compilar com bibliotecas de terceiros corretamente?

2

Esta é uma pergunta de acompanhamento para Confusão sobre a vinculação da biblioteca dinâmica compilação :

O que fazer, quando eu gero um makefile pelo qmake e tenho apenas uma terceira parte boost lib instalada (desinstalei todas as libs do gerenciamento de dependência, porque ele sempre linka para o boost lib de gerenciamento de dependência que eu não quero) e eu quero compilar apenas contra esta biblioteca manualmente instalada, bem como executar contra ele.

Estas são as partes importantes de um Makefile gerado pelo 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 

Este é o caminho para impulsionar:

/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

Esta é a saída de ldconfig -v referente ao 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

O que eu tenho exatamente a fazer para compilar e executar o código corretamente? Eu tentei combinações de:

-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

Tudo isso NUNCA funciona quando não há aumento instalado pelo gerenciador de pacotes, mas não quero usá-lo no gerenciador de pacotes. Isso significa que não compila. Às vezes eu recebo algo como:

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

ou

/usr/bin/ld: cannot find -lboost_system

ou

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

... e assim por diante.

Eu não entendo. O que há de errado aqui?

[UPDATE]
Acontece que parece haver algo errado com o próprio boost lib. Depois de modificar as partes importantes do makefile para:

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 produziu outro erro:

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

Parece que não existe tal função (nesta versão de boost?):

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

imprime nada tão bem quanto

$ 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

não.

[UPDATE 2]
Depois de adicionar

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

para INCPATH e recompilar o aplicativo inteiro dentro de um espaço de trabalho novo, o erro é diferente, mas agora, não vejo nenhuma mensagem de erro:

/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
    
por Bevor 08.12.2013 / 11:36

1 resposta

3

A invocação correta de acordo com as listagens de diretório que você forneceu seria:

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

-L é usado para especificar o caminho onde as bibliotecas são encontradas. -I é para cabeçalhos, o que não ajudará em erros de vinculação (você obterá erros de compilador se não tiver caminhos de inclusão).

Quanto a boost_system versus boost_system-mgw46-mt-sd-1_54 - você não tem nada chamado "boost_system-mgw46-mt-sd-1_54.so [.version]" no seu diretório de bibliotecas, então você não pode usar esse segundo nome.

(Você também tem caminhos do tipo Windows em seu Makefile - tente evitar misturar os dois, use condicionais em seus Makefiles para separar os caminhos Windows e Unix).

    
por 08.12.2013 / 13:08