Я пытаюсь создать ссылку на стороннюю библиотеку, которая использует 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)'
nm —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), чтобы он собирался с тем же компилятором, а не с системной версией.
Редактировать…
Я думаю, что Джон Звинк на правильном пути, но я не могу заставить библиотеку наддува компилироваться в новый ABI.
Функции validate () находятся в 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?
Как объяснено в https://stackoverflow.com/a/52611576/981959 ты не можешь использовать новый cxx11
ABI в версии GCC devtoolset (потому что весь смысл GCC devtoolset в том, чтобы оставаться совместимым с ABI системы libstdc ++).
Ваши варианты:
libstdc++.so
привыкает во время выполнения.Похоже, вы столкнулись с GCC Dual ABI для std::string
в C ++ 11: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
Ваша программа пытается связать API с помощью
std::__cxx11::basic_string<char>*
Но ваша библиотека Boost имеет
std::basic_string<char>*
Это означает, что ваша библиотека Boost была собрана с GCC старше 5.1 или с новым ABI выключенным. В любом случае вы можете скомпилировать свой собственный код с отключенным новым ABI, добавив этот флаг компилятора:
-D_GLIBCXX_USE_CXX11_ABI=0
Скомпилировав вашу программу с этим, вы сможете использовать предоставляемые системой (старые ABI) библиотеки Boost. Но тогда вопрос будет в том, с каким C ++ ABI ваш поставщик компилировал их код (спросите их или поищите __cxx11
в их библиотеке).
Хорошо, я думаю, я понял, почему я не могу получить g ++ для генерации подписи cxx11 (новый ABI).
Если я запускаю g ++ с параметром -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)
Обратите внимание на следующее в поле «сконфигурировано с»
—с по умолчанию-libstdcxx-аби = gcc4-совместимый
Я считаю, что это означает, что версия g ++ devtoolset-6 построена со старым ABI «запеченным», и поэтому не отвечает на макрос _GLIBCXX_USE_CXX11_ABI.
По этой ссылке: https://gcc.gnu.org/onlinedocs/libstdc++/manual/configure.html
—с по умолчанию-libstdcxx-аби = ВАРИАНТ
Установите значение по умолчанию для макроса _GLIBCXX_USE_CXX11_ABI (см. Макросы). По умолчанию используется OPTION = new, который устанавливает макрос в 1, используйте OPTION = gcc4-совместимый, чтобы установить его в 0. Эта опция не меняет ABI библиотеки.
Казалось бы, только изменить значение по умолчанию _GLIBCXX_USE_CXX11_ABI, но в моих попытках установка _GLIBCXX_USE_CXX11_ABI не имеет никакого эффекта.
Не уверен, но сейчас это моя рабочая теория. Любое дополнительное понимание приветствуется.