Цей допис у блозі досить неточний.
Наскільки мені відомо, зміни в AB ++ на C ++ вносились з кожним основним випуском GCC (тобто з різними компонентами першої або другої версії номера).
Неправда. Єдині зміни CI 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
змінну середовища під час запуску. час, або встановивши RPATH
у виконуваному файлі час посилання. Я вважаю за краще використовувати, RPATH
оскільки воно не покладається на правильне встановлення середовища для роботи програми. Якщо цієї програми було '-Wl,-rpath,$ORIGIN'
(зверніть увагу на одинарні лапки , щоб запобігти оболонку , намагаючись розширити $ORIGIN
) , то виконуваний файл буде мати RPATH
з $ORIGIN
яких говорить динамічний компонувальник шукає спільно використовувані бібліотеки в тому ж каталозі, що і сам виконуваний файл. Якщо поставити новішеlibstdc++.so
в тому ж каталозі, що і виконуваний файл, він буде знайдений під час виконання, проблема вирішена. (Іншим варіантом є розміщення виконуваного файлу /some/path/bin/
та нового libstdc ++. Таким чином, /some/path/lib/
і зв’язування з '-Wl,-rpath,$ORIGIN/../lib'
будь-яким іншим фіксованим розташуванням щодо виконуваного файлу та встановлення RPATH щодо $ORIGIN
)
-static-libstdc++
опції, ви б просто використали-static