LINUX.ORG.RU

Почему gcc не версионирует свой рантайм?

 , ,


4

5

Приветствую! Друзья, расскажите, почему gcc не соблюдает собственные GNUтые правила libtool.

Например, картина для рантайма gcc 9.2:

/usr/lib/libasan.so.5.0.0
/usr/lib/libatomic.so.1.2.0      <- не меняется годами
/usr/lib/libgcc_s.so.1           <- постоянное значение как минимум с gcc 4.x.x
/usr/lib/libgdruntime.so.76.0.3
/usr/lib/libgfortran.so.5.0.0
/usr/lib/libgo.so.14.0.0
/usr/lib/libgomp.so.1.0.0        <- постоянное значение как минимум с gcc 4.x.x
/usr/lib/libgphobos.so.76.0.3
/usr/lib/libitm.so.1.0.0         <- не меняется годами
/usr/lib/liblsan.so.0.0.0        <- не меняется годами
/usr/lib/libobjc.so.4.0.0        <- не меняется годами
/usr/lib/libquadmath.so.0.0.0    <- постоянное значение как минимум с gcc 4.x.x
/usr/lib/libstdc++.so.6.0.27     <- многие годы вечный 6.0.x
/usr/lib/libtsan.so.0.0.0        <- не меняется годами
/usr/lib/libubsan.so.1.0.0       <- не меняется годами

Почему так?

  • Revision почти всегда 0. Должен увеличиваться с каждым релизом.
  • Minor ( =Age) почти всегда 0. Должен увеличиваться при добавлении новых интерфейсов.
  • Major ( =Current-Age) либо не меняется, либо меняется крайне неспешно. Должен увеличиваться при сломе обратной совместимости.

libstdc++.so версионируются, но странно. В gcc 9.2 она имеет обозначение 6.0.27, и в gcc 4.7.4 — 6.0.17. Если верить такому обозначению, то между этими версиями в библиотеку не было добавлено ни одного интерфейса, что бред.

Видно, что активно версионируются только libgo.so, libgphobos.so, libgdruntime.so.

Deleted

Последнее исправление: Deleted (всего исправлений: 2)

Суть вопроса не ясна.

У каждого подпроекта свои версии. Когда подпроект меняется - версия наращивается, когда не меняется - не наращивается. Как тебе такая гипотеза?

Einstok_Fair ★★☆
()
Ответ на: комментарий от Deleted

багу напиши про то, что был добавлен интерфейс и не сменена версия по правилам. Потом сюда скопируй что там ответят.

Einstok_Fair ★★☆
()
Ответ на: комментарий от Einstok_Fair

Может быть, кто-то из местных даст ответ. На выходных напишу вопрос в рассылку, сейчас времени мало.

Deleted
()
Ответ на: комментарий от Deleted

Я сам хз. У тебя сразу куча либ, я ооочень сомневаюсь что на них идут одно правило версионирования, взять из твоего списка например libstdc++ идём и смотрим что там об версионирование чёрт ногу сломит https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html дальше берём наобум например libatomic и уже как применять тоже самое и к нему? Лично я как непрограммист решительно забил на всё это :D Наверняка логика есть, просо надо раздуплить внимательно от корки до корки прочитав https://gcc.gnu.org или даже может быть написав письмо одному из сопровождающих мол «Что это такое я ничего не понимаю»

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

У тебя сразу куча либ, я ооочень сомневаюсь что на них идут одно правило версионирования

Ну, у них (в смысле, у всех, кто работает над проектами GNU) есть правила в мануале libtool, и им худо-бедно следуют.

Версии всех этих компонентов, конечно, будут разные, но вопрос в том, почему они не меняются годами.

Если читать версию libstdc++.so.6.0.27 по правилам libtool, то получается, что я могу собрать новым gcc код на крестах со всеми современными фичами, а потом скопировать бинарник на систему, где лежит древний libstdc++ от какого-нибудь gcc 4.x.x, и там всё заработает.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

Ой, хз. Сложна. Может они решили игнорировать версию so.x.x.x и ориентируются на #define версионирование из заголовков. Ну типа «Давай so.0.0.0 оставим как тупо часть имени, убрать нельзя ибо где то там чего то кому то надо, а фиксировать версию будем на уровне заголовочных файлов чтобы если линкуем то всегда один путь, а уже внутря будем говорить кто мы и что мы» или типа того. Ну эт я фатазирую, но вдруг. Вот тот же libasan он сам по себе вообще живёт в отрыве от gcc? Если нет то смысла ему может и нет версию ментять ибо он спутник типа.

LINUX-ORG-RU ★★★★★
()

А что, в libgcc_s и libgomp как-то меняется интерфейс? В любом случае, эти бибилотеки не используются в коде программ на прямую, это в прямом смысле рантайм языка.

Что касается libstdc++, то лучше спроси у ее разработчиков, и вряд ли на этом форуме найдется хотя бы один из них.

annulen ★★★★★
()
Ответ на: комментарий от annulen

libgomp используется напрямую, есть API.

anonymous
()

GCC умеет такую штуку https://gcc.gnu.org/wiki/SymbolVersioning

Поэтому в каждой новой версии libstdc++ (и прочих либах) можно не только добавлять новые интерфейсы, но и одновременно совмещать их старые и новые версии, включая разные ABI.

Таким образом, новые выпуски каждой из этих либ позволяют работать старым скомпилированным бинарникам. Поэтому «номер версии» в названии so-библиотек не меняется (см. libtool versioning).

anonymous
()

вариант «они забили на версионирование по правилам, потому что это внутренние либы проекта, не предполагающие их использование в сторонних продуктах» не рассматривается?

olelookoe ★★★
()
Ответ на: комментарий от Deleted

SymbolVersioning ортогонален версионированию ABI библиотек.

Ну снимитесь же с тормоза.

У библиотек, о которых вы говорите (не путать с mustdie и т.п.), версионируется не ABI. Это libtool-номер, RTFM был по ссылке.

Без механизма версионирования символов невозможно поддержать/совместить разные ABI в одной so-библиотеке. Поэтому придется увеличивать номер версии в so-имени либы.

С другой стороны, если поменять libtool-версию, то старый бинарник не найдет новую либу. Соответственно, в такой либе нет смысла поддерживать старые ABI.

Поэтому libtool-версионирование и версионирование символов - это сильно спаренные технологии. И именно благодаря этой связке снаружи не видна разница в библиотеках для старых и новых версий GCC.

Т.е. это цель дизайна такая была )

anonymous
()
Ответ на: комментарий от anonymous

Ну снимитесь же с тормоза.

Кому тут с тормоза надо сняться? Прочитайте уже, как работает версионирование libtool и правила обновления номеров (следующая страница по вашей ссылке).

С другой стороны, если поменять libtool-версию, то старый бинарник не найдет новую либу.

Смысл libtool именно в том, что бинарь найдёт [b]потенциально совместимую[/b] либу (не важно, какая точно версия) и не найдёт [b]несовместимую[/b].

Гуглите, как динамическое связывание работает.

И именно благодаря этой связке снаружи не видна разница в библиотеках для старых и новых версий GCC.

Ну запустите бинарь, собранный новым GCC, в системе, релизнувшейся 10 лет назад.

Deleted
()
Ответ на: комментарий от olelookoe

вариант «они забили на версионирование по правилам, потому что это внутренние либы проекта, не предполагающие их использование в сторонних продуктах» не рассматривается?

  1. В каком месте рантаймы языков стали внутренними либами?

  2. Даже если либы внутренние, как мне без танцев с sed и patch поставить рядом две версии одного продукта, если пакеты по soname конфликтуют?

Deleted
()
Ответ на: комментарий от Einstok_Fair

такого не может быть, опенсорс создаётся по высшим стандартам качества.

Чо-т вспомнилась эпическая история, как в libtool была сломана сборка библиотек под IRIX, и это оставалось незамеченным несколько лет (видимо, за ненужностью самого IRIX-а как такового), а когда обнаружилось – разраба, который за это отвечал, спросили, чем он руководствовался, и он ответил «не знаю, я просто сделал кусок кода по техзаданию из файла вон того чувака, а сам я IRIX никогда в глаза не видел; вы там исправьте как надо, если что».

Deleted
()
Ответ на: комментарий от Deleted

Ну запустите бинарь, собранный новым GCC, в системе, релизнувшейся 10 лет назад.

Хм, обсуждаемое версионирование придумано чтобы явно видеть границы совместимости и иметь возможность запускать старое на новом, а не наоборот.

В остальном просто RTFM, именно всё на что вы ссылаетесь по моим ссылкам.

anonymous
()
Ответ на: комментарий от anonymous

Хм, обсуждаемое версионирование придумано чтобы явно видеть границы совместимости

This. Наконец-то. И где они, эти границы?

и иметь возможность запускать старое на новом

Для этого надо знать, что старое, а что новое. В этом суть самого соглашения о версионировании.

В остальном просто RTFM, именно всё на что вы ссылаетесь по моим ссылкам.

RTFM же уже сами, прекратите тупить.

Согласно the fucking manual, soname-ы крестового рантайма 6.0.27 и 6.0.17 реализуют одинаковое множество интерфейсов и отличаются только реализацией.

Deleted
()
Ответ на: комментарий от Deleted

Ну запустите бинарь, собранный новым GCC, в системе, релизнувшейся 10 лет назад.

это вполне делается, посредством прямого указания нужных символов через symver.

например:

__asm__(".symver clock_gettime,clock_gettime@GLIBC_2.2.5");
waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от waker

есть, конечно, проблемы другого характера.. например, с поддержкой C++ все намного сложнее.

или вот к примеру, если собрать статическую библиотеку (точнее, даже просто скомпилировать в объектники) новым gcc – то старый ld может ее не понять из-за новых опкодов. но собрать и слинковать новым gcc/ld, и запустить с дремучим glibc, вполне реалистично, и даже обыденно.

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от waker

glibc и версионируется нормально, как раз.

Deleted
()
Ответ на: комментарий от Deleted

По-моему не в курсе как раз ты.

В gcc 9.2 она имеет обозначение 6.0.27, и в gcc 4.7.4 — 6.0.17. Если верить такому обозначению, то между этими версиями в библиотеку не было добавлено ни одного интерфейса

Если уметь читать, то было сделано 10 не-деструктивных изменений (добавлений).

TL;DR:

  • if you add something → minor goes up
  • if you break something → major goes up, minor back to 0

Но в GNU мире всё и в самом деле очень условно. ;)

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от Deleted

да я сам хз, просто мысли вслух )

обычная либа, сменившая мажорную версию как бы говорит нам - не юзай меня, я сломала обратную совместимость.

либа с поддержкой SymbolVersioning может поддерживать и старую и новую реализации. внимание вопрос - а должна ли при этом меняться мажорная версия? смена мажорной версии - сигнал о том, что нехрен с новой версией линковаться, а это не так.

minor и release менять? изначальная концепция уже накрылась медным тазом, если и менять, то правила должны быть слегка другими, а какими - хз.

на предмет поставить две версии рядом - всяко придется извращаться, не одним способом так другим.

olelookoe ★★★
()
Ответ на: комментарий от olelookoe

изначальная концепция уже накрылась медным тазом

Почему накрылась. Критерий простой и дубовый: добавил интерфейсы - инкрементируй minor; не добавлял - инкрементируй revision.

SymbolVersioning ничего нового в метод не вносит, т.к. это частный случай специфицирования интерфейсов.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от beastie

Если уметь читать, ты бы не путал minor и revision, однако увы…

Deleted
()

Вот кстати фряха танцует с бубном:

Message from gcc9-9.2.0:

--

To ensure binaries built with this toolchain find appropriate versions of the necessary run-time libraries, you may want to link using

-Wl,-rpath=/usr/local/lib/gcc9

For ports leveraging USE_GCC, USES=compiler, or USES=fortran this happens transparently.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

А в чём танец? Если не указать, оно шланговые либы подцепит(с закономерным результатом)

DllMain
()
Ответ на: комментарий от Deleted

SymbolVersioning ничего нового в метод не вносит

вносит же. считай что у тебя несколько разных либ внутри одного бинаря.

одна 2.1.15, а другая 8.6.13. иии, что мне теперь у so инкрементировать, если у первой либы произошла смена версии до 2.2.8 ?

olelookoe ★★★
()

Revision почти всегда 0. Должен увеличиваться с каждым релизом.

Minor ( =Age) почти всегда 0. Должен увеличиваться при добавлении новых интерфейсов.

Не должны. Для библиотек имеет смысл только major, который увеличивается при несовместимых изменениях ABI. Он же (и только он) попадает в SONAME.

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 1)
Ответ на: комментарий от slovazap

А то, что под линуксом в soname внутри elf попадает только major - это вообще деталь реализации. Вашу мать, ну прочтите чёртов мануал.

Deleted
()
Ответ на: комментарий от anonymous

С другой стороны, если поменять libtool-версию, то старый бинарник не найдет новую либу. Соответственно, в такой либе нет смысла поддерживать старые ABI.

Glibc же работает. Симлинки помогают.

А версионирование ещё одну мину подкладывает: если в нормальной системе с динамическими библиотеками, чтобы исправить ошибку, достаточно поставить новую версию библиотеки, то с версионированием всё равно приходится перекомпилировать бинарники.

monk ★★★★★
()
Ответ на: комментарий от olelookoe

вариант «они забили на версионирование по правилам, потому что это внутренние либы проекта, не предполагающие их использование в сторонних продуктах» не рассматривается?

Порядок должен быть всегда и везде, а не только для либ «внешнего мира».

anonymous
()
Ответ на: комментарий от olelookoe

Да, все верно. Эта ссылка тоже годится.

Deleted
()
Ответ на: комментарий от Deleted

Документация gnu другого мнения на счёт «не должны».

А почему кому-то должно быть дело до документации GNU? Даже самому GNU.

А то, что под линуксом в soname внутри elf попадает только major - это вообще деталь реализации.

А что, осилите назвать систему где не только major?

Вашу мать, ну прочтите чёртов мануал.

Вы опять про писульку GNU?

slovazap ★★★★★
()

libstdc++.so версионируются, но странно

TLDR: есть более лучшие механизмы для обеспечения backward и forward compatibility, чем просто soname.

В какой-то момент (по слухам, после libstdc++.so.5 -> libstdc++.so.6) люди поняли, что обратная совместимость — это серьезно и теперь предпочитают версионирование на уровне символов.

Как я это понимаю (и как это выглядит для окружающих) — символы снабжаются дополнительной метаинформацией (версией), а затем, если на целевой системе символа с нужной версией не окажется, ld-linux.so ругнется, что «symbol not found foo@CXX$VER».

В итоге у тебя под одним и тем же soname может скрываться большое количество символов («старые» и «новые» интефейсы в одном флаконе!).

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

В какой-то момент (по слухам, после libstdc++.so.5 -> libstdc++.so.6) люди поняли, что обратная совместимость — это серьезно и теперь предпочитают версионирование на уровне символов.

Не мутите воду. Это правило действует давным-давно и вся информация явно опубликована https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.