Неопределенная ссылка при связывании с Boost с использованием g++-4.9 в дистрибутиве g++-5-ish
Я написал следующее новаторское приложение:
#include <boost/program_options.hpp>
int main(int argc, char** argv)
{
boost::program_options::options_description generic_options("foo");
return 0;
}
Я пытаюсь построить это на Debian Stretch, на котором по умолчанию используется компилятор GCC 5.3.1-5, а установленная версия Boost - 1.58.0.
Однако по причинам, которые я не буду здесь вдаваться (которые были бы очевидны, если бы не MCVE), мне нужно скомпилировать и связать двоичный файл, используя g++-4.9
не g++-5.3
, Компиляция работает нормально, но когда я пытаюсь связать, вот что происходит:
/usr/bin/g++-4.9 -Wall -std=c++11 CMakeFiles/tester3.dir/src/altmain2.cpp.o -o bin/tester3 -rdynamic -lboost_log -lboost_system -lboost_program_options
CMakeFiles/tester3.dir/src/altmain2.cpp.o: In function `main':
altmain2.cpp:(.text+0x61): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
- Это из-за несовместимости ABI между gcc 4 и 5?
- Если так, есть ли способ обойти это, кроме создания моей собственной версии Boost?
- Если нет, что может вызвать это?
1 ответ
Это из-за несовместимости ABI между gcc 4 и 5?
Похоже, это так. По умолчанию GCC 5 использует новый ABI для нескольких важных стандартных библиотечных классов, включая std::basic_string
шаблон (и, следовательно, также std::string
). К сожалению, невозможно было бы сделать std::string полностью соответствующим C++11 и более поздним версиям, не нарушая ABI.
libstdC++ реализует двойной ABI, так что двоичные файлы, скомпилированные с более старыми версиями GCC, будут связываться (и работать правильно) с новой библиотекой. См. Этот пост Джейсона Меррилла (Jason Merrill) (сопровождающего внешнего интерфейса C++ для GCC) для получения подробной информации.
Если так, есть ли способ обойти это, кроме создания моей собственной версии Boost?
Возможно нет. Повышение зависит от новой реализации std::string
и не обеспечивает обратную совместимость (в отличие от libstdC++). Эта проблема упоминается в багтрекере Debian.