Compiling

如何正確編譯第三方庫?

  • December 8, 2013

這是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_systemvs boost_system-mgw46-mt-sd-1_54- 你沒有任何名為“boost_system-mgw46-mt-sd-1_54.so

$$ .version $$" 在您的庫目錄中,因此您不能使用第二個名稱。 (您的 Makefile 中也有 Windows 類型的路徑 - 盡量避免將兩者混合,在 Makefile 中使用條件來分隔 Windows 和 Unix 路徑。)

引用自:https://unix.stackexchange.com/questions/104205