Это сообщение в блоге довольно неточно.
Насколько мне известно, изменения C ++ ABI вводились с каждым основным выпуском GCC (то есть с разными компонентами первого или второго номера версии).
Не правда. Единственные изменения C ++ ABI, внесенные после GCC 3.4, были обратно совместимы, то есть C ++ ABI был стабильным в течение почти девяти лет.
Что еще хуже, большинство основных дистрибутивов Linux используют моментальные снимки GCC и / или исправляют свои версии GCC, что делает практически невозможным точно знать, с какими версиями GCC вы можете иметь дело при распространении двоичных файлов.
Различия между патченными версиями GCC дистрибутивов незначительны, и ABI не меняется, например, Fedora 4.6.3 20120306 (Red Hat 4.6.3-2) является ABI-совместимой с вышестоящими версиями FSF 4.6.x и почти наверняка с любой версией 4.6. x из любого другого дистрибутива.
В GNU / Linux библиотеки времени выполнения GCC используют управление версиями символов ELF, поэтому легко проверять версии символов, необходимые для объектов и библиотек, и если у вас есть программа, libstdc++.so
которая предоставляет эти символы, она будет работать, не имеет значения, если это немного другая версия с исправлениями из другой версии вашего дистрибутива.
но никакой код C ++ (или любой код, использующий поддержку среды выполнения C ++) не может быть связан динамически, если это должно работать.
Это тоже неправда.
Тем не менее, статическая ссылка libstdc++.a
- это один из вариантов для вас.
Причина, по которой это может не работать, если вы динамически загружаете библиотеку (используя dlopen
), заключается в том, что символы libstdc ++, от которых она зависит, могли не понадобиться вашему приложению, когда вы (статически) связали его, поэтому эти символы не будут присутствовать в вашем исполняемом файле. Это можно решить, динамически связав разделяемую библиотеку с libstdc++.so
(что в любом случае будет правильным, если это зависит от него.) Взаимодействие символов ELF означает, что символы, которые присутствуют в вашем исполняемом файле, будут использоваться разделяемой библиотекой, а другие - нет. присутствует в вашем исполняемом файле, будет найден там, где libstdc++.so
он ссылается. Если ваше приложение не использует, dlopen
вам не нужно об этом заботиться.
Другой вариант (и тот, который я предпочитаю) - развернуть новую версию libstdc++.so
вместе с вашим приложением и убедиться, что она будет найдена до системы по умолчанию libstdc++.so
, что можно сделать, заставив динамический компоновщик искать в нужном месте, либо используя $LD_LIBRARY_PATH
переменную среды при запуске - time или установив RPATH
в исполняемом файле во время компоновки. Я предпочитаю использовать, RPATH
поскольку он не зависит от правильной настройки среды для работы приложения. Если вы свяжете свое приложение с '-Wl,-rpath,$ORIGIN'
(обратите внимание на одинарные кавычки, чтобы предотвратить попытку расширения оболочки $ORIGIN
), то исполняемый файл будет находитьсяRPATH
из $ORIGIN
которых сообщает динамическому компоновщику искать разделяемые библиотеки в том же каталоге, что и сам исполняемый файл. Если поставить новееlibstdc++.so
в том же каталоге, что и исполняемый файл, он будет найден во время выполнения, проблема решена. (Другой вариант - поместить исполняемый файл /some/path/bin/
и более новую libstdc ++. So /some/path/lib/
и связать его с '-Wl,-rpath,$ORIGIN/../lib'
любым другим фиксированным местоположением относительно исполняемого файла и установить RPATH относительно $ORIGIN
)
-static-libstdc++
варианте не было бы смысла , вы бы просто использовали-static