如何正確編譯第三方庫?
這是Confusion 關於在編譯時連結 boost 庫的後續問題:
當我通過 qmake 生成 Makefile 並且我只安裝了第三方 boost lib 時該怎麼辦(我從依賴管理中解除安裝了所有 boost lib,因為它總是從依賴管理連結到我不想要的 boost lib)我希望它只針對這個手動安裝的庫進行編譯並針對它執行。
這些是 qmake 生成的 Makefile 的重要部分:
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
這是提昇路徑:
/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
這是關於 boost的ldconfig -v的輸出:
# 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
我到底需要做什麼才能正確編譯和執行程式碼?我嘗試了以下組合:
-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
當包管理器沒有安裝boost時,所有這些都不會起作用,但我不希望它從包管理器中使用它。這意味著它不會編譯。有時我會得到類似的東西:
/usr/bin/ld: cannot find -lboost_system-mgw46-mt-sd-1_54
或者
/usr/bin/ld: cannot find -lboost_system
或者
addrman.cpp:(.text.startup+0x23): undefined reference to `boost::system::generic_category()'
…等等。
我不明白。這裡有什麼問題?
$$ UPDATE $$
事實證明,boost lib 本身似乎有問題。將makefile的重要部分修改為:
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產生了另一個錯誤:
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
似乎沒有這樣的功能(在這個提升版本中?):
$ objdump -T /usr/local/lib/boost1.55/lib/libboost_thread.so|c++filt|grep once_epoch
什麼都不列印
$ 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
才不是。
$$ UPDATE 2 $$
添加後
-I/usr/local/lib/boost1.55/include/ -I/usr/local/lib/boost1.55/include/boost/
到 INCPATH 並在一個新的工作區中重新編譯整個應用程序,錯誤是不同的,但現在,我沒有看到任何錯誤消息:
/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
根據您提供的目錄列表,正確的呼叫將是:
-L/usr/local/lib/boost1.55/lib/ -lboost_system
-L
用於指定找到庫的路徑。-I
用於標頭,這對連結器錯誤沒有幫助(如果缺少包含路徑,則會出現編譯器錯誤)。至於
boost_system
vsboost_system-mgw46-mt-sd-1_54
- 你沒有任何名為“boost_system-mgw46-mt-sd-1_54.so$$ .version $$" 在您的庫目錄中,因此您不能使用第二個名稱。 (您的 Makefile 中也有 Windows 類型的路徑 - 盡量避免將兩者混合,在 Makefile 中使用條件來分隔 Windows 和 Unix 路徑。)