Неопределенная ссылка Boost

Я пытаюсь создать ссылку на стороннюю библиотеку, которая использует 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?

1

Решение

Как объяснено в https://stackoverflow.com/a/52611576/981959 ты не можешь использовать новый cxx11 ABI в версии GCC devtoolset (потому что весь смысл GCC devtoolset в том, чтобы оставаться совместимым с ABI системы libstdc ++).

Ваши варианты:

  • получите новую версию сторонней библиотеки, которая использует gcc4-совместимый ABI, чтобы вы могли ссылаться на нее с помощью компилятора devtoolset; или же
  • Соберите и установите новый GCC самостоятельно, используйте его вместо devtoolset GCC и убедитесь, что новый libstdc++.so привыкает во время выполнения.
1

Другие решения

Похоже, вы столкнулись с 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 в их библиотеке).

0

Хорошо, я думаю, я понял, почему я не могу получить 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 не имеет никакого эффекта.

Не уверен, но сейчас это моя рабочая теория. Любое дополнительное понимание приветствуется.

0
По вопросам рекламы [email protected]