2017-11-10 100 views
0

我試圖鏈接使用Boost的第三方庫。我已經鏈接到正確的提升庫(libboost_program_options.a),但仍未找到它。未定義的升壓參考

誤差MSG(格式化的位爲清楚起見):

undefined reference to `boost::program_options::validate(boost::any&, 
           std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, 
           std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, 
           int)' 

納米--demangle libboost_program_options.a | grep validate

boost::program_options::validate(boost::any&,         std::vector<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > const&, 
            bool*, 
            int) 
boost::program_options::validate(boost::any&, 
            std::vector<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > const&, 
            std::string*, 
            int) 
boost::program_options::validate(boost::any&, 
            std::vector<std::string, std::allocator<std::string> > const&, 
            bool*, 
            int) 
boost::program_options::validate(boost::any&, 
            std::vector<std::string, std::allocator<std::string> > const&, 
            std::string*, 
            int) 

第二條記錄看起來很相似,但顯然不夠接近。任何想法如何編譯Boost來獲得與庫中的內容相匹配的簽名?我向圖書館的所有者請求瞭解他們正在使用的Boost版本等,但還沒有收到回覆。

這是一個CentOS 7盒子,它使用g ++版本4.8.5。但我嘗試鏈接的庫大量使用C++ 11,並使用g ++ v 6.1編譯,所以我安裝了devtoolset-6,它給了我一個g ++ 6環境(g ++版本6.3.1)

我下載了並從頭開始構建Boost(v1.65.1),以便使用相同的編譯器構建而不是系統版本。

編輯... 我認爲約翰Zwinck是在正確的軌道上,但我無法得到增強庫編譯到新的ABI。

的驗證()函數在value_semantic.cpp

剝離構建下的基本知識發現,並添加標誌討論:

g++ -std=c++11 -D_GLIBCXX_USE_CXX11_ABI -c -o test.o libs/program_options/src/value_semantic.cpp 

nm --demangle test.o | grep validate 
00000000000008b6 T boost::program_options::validate(boost::any&, std::vector<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > const&, bool*, int) 
0000000000000c02 T boost::program_options::validate(boost::any&, std::vector<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > const&, std::string*, int) 
00000000000005f2 T boost::program_options::validate(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, bool*, int) 
0000000000000b9a T boost::program_options::validate(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, std::string*, int) 

是否_GLIBCXX_USE_CXX11_ABI宏只適用於GCC 5.1的工作?

+1

您是否嘗試過使用'g ++ -std = C++ 11'來構建boost? – burlyearly

+0

不 - 據我所知,C++ 11是g ++ v6的默認設置。不過,我正在考慮這個問題 - 必須看看如何將它融入Boost構建系統。 – CoAstroGeek

+1

剛剛看過C++ 14是gcc v6的默認版本 https://gcc.gnu.org/projects/cxx-status.html#cxx11 – CoAstroGeek

回答

0

您似乎在C++ 11觸犯GCC雙ABI的運行std::stringhttps://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html

你的程序正試圖使用​​

std::__cxx11::basic_string<char>* 

對一個API來的鏈接,但您的Boost庫有

std::basic_string<char>* 

這意味着您的Boost庫是使用GCC超過5.1版本構建的,或者關閉了新的ABI。在這兩種情況下,你可以自己編譯的代碼與新的ABI關閉加入這個編譯標誌:

-D_GLIBCXX_USE_CXX11_ABI=0 

通過與編譯程序時,將有可能使用系統提供的(舊ABI)提升圖書館。但問題是你的供應商將哪些C++ ABI編譯成代碼(詢問他們,或者在他們的庫中查找__cxx11)。

+0

我認爲這是正確的軌道,但我仍然無法讓我的構建與第三方庫ABI匹配 - 請參閱上面的編輯。謝謝! – CoAstroGeek

0

好的,我想我已經知道爲什麼我不能讓g ++生成cxx11簽名(新的ABI)。

如果我運行克++帶-v選項:

g++ -v 
Using built-in specs. 
COLLECT_GCC=g++ 
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-6/root/usr/libexec/gcc/x86_64-redhat-linux/6.3.1/lto-wrapper 
Target: x86_64-redhat-linux 
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-6/root/usr --mandir=/opt/rh/devtoolset-6/root/usr/share/man --infodir=/opt/rh/devtoolset-6/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --disable-libgcj --with-default-libstdcxx-abi=gcc4-compatible --with-isl=/builddir/build/BUILD/gcc-6.3.1-20170216/obj-x86_64-redhat-linux/isl-install --enable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux 
Thread model: posix 
gcc version 6.3.1 20170216 (Red Hat 6.3.1-3) (GCC) 

注下 「被配置爲」 字段的下面

--with - 缺省 - libstdcxx-ABI = GCC4兼容

我相信這意味着g ++的devtoolset-6版本是使用舊式ABI「烘烤」構建的,因此它不會響應_GLIBCXX_USE_CXX11_ABI宏。

根據此鏈接:https://gcc.gnu.org/onlinedocs/libstdc++/manual/configure.html

--with-默認libstdcxx-ABI = OPTION 設置爲_GLIBCXX_USE_CXX11_ABI宏(見宏)的默認值。默認值爲OPTION = new,將宏設置爲1,使用OPTION = gcc4-compatible將其設置爲0.此選項不會更改庫ABI。

它似乎只改變_GLIBCXX_USE_CXX11_ABI的默認值,但在我的嘗試設置_GLIBCXX_USE_CXX11_ABI沒有任何影響。

這不是正面的,但它是我現在的工作理論。任何額外的洞察力是讚賞。