- Вопрос или проблема
- Резюме
- Как узнать все это
- GCC, используемый для сборки Ubuntu
- Ответ или решение
- Обсуждение версий libgcc-s1 и gcc-base в Ubuntu 20.04 LTS
- Объяснение несоответствия версий
- Зачем использовать более новые версии библиотек?
- Как это повлияет на компиляцию и приложения?
- Как выяснить используемые версии
- Заключение
Вопрос или проблема
Ubuntu 20.04 LTS (по крайней мере, основное изображение docker) распространяется с libgcc-s1 и gcc-10-base версии 10.3.0(-1ubuntu1~20.04), смотрите, например, манифест по адресу https://partner-images.canonical.com/core/focal/20211103/ubuntu-focal-core-cloudimg-amd64.manifest.
Версия GCC по умолчанию в 20.04 LTS – GCC 9, а не GCC 10.
Каково объяснение этой видимой несоответствия? – Почему не распространять версии 9.x этих пакетов? Это связано с версией GCC, используемой для компиляции пакетов на основе C в 20.04 LTS? Большинство (все?) пакетов на основе C в 20.04 LTS скомпилированы с помощью GCC 10?
Отказ от ответственности: я довольно нов в Ubuntu. У меня есть разумный опыт работы с RHEL и SLES, и мне пришлось изучить версии LTS Ubuntu недавно из-за некоторого аппаратного обеспечения ARM64, которое не хочет загружать ничего другого.
Резюме
Выпуски Ubuntu действительно часто поставляются с некоторыми компонентами из более поздних версий GCC, чем версия по умолчанию для релиза. Они, по-видимому, делают это, чтобы предоставить более поздние версии компилятора, если вы хотите их использовать.
- Пакет gcc-10-base просто предоставляет документацию.
- Пакет libgcc-s1 предоставляет важную библиотеку,
libgcc_s.so.1
. Это предоставляет вспомогательные функции для кода, сгенерированного компилятором: я знаю, что это важно для обработки исключений C++, возникающих через стек вызовов C. - Еще одна важная библиотека – это
libstdc++.so.6
. Она предоставляет функции поддержки C++. - Glibc (
libc.so.6
,libm.so.6
и другие библиотеки) также важна, но не привязана к версии GCC.
Все эти библиотеки имеют очень строгие правила совместимости. По сути, более поздняя версия библиотеки всегда будет совместима с более ранними версиями, за исключением некоторых древних версий из ранней истории GCC и Linux.
Сразу не очевидно, почему Ubuntu и Debian предоставляют время выполнения, которое позже, чем компилятор, но это становится яснее, когда вы смотрите на диапазон доступных версий GCC в недавних версиях Ubuntu LTS:
Distribution Released Debian GCC run-times Default GCC Additional GCCs
Ubuntu 16.04 Apr 2016 9.x 5.x 5.4 4.7, 4.8, 4.9
Ubuntu 18.04 Apr 2018 10.x 8.x 7.5 4.8, 5.5, 6.5. 8.4
Ubuntu 20.04 Apr 2020 11.x 9.x & 10.x 9.3 7.4, 8.4, 10.3
Ubuntu 22.04 Apr 2022 12.x 12.x 11.4 9.5, 10.5, 12.3
На этом этапе это становится довольно очевидным. Ubuntu 20.04 имеет время выполнения для кода, скомпилированного с помощью GCC 9.x и 10.x (GCC 10.x не требует дополнительных функций библиотеки, которые не использовались GCC 9.x). Вы можете установить любую комбинацию GCC 7.4, 8.4 и 10.3 в качестве дополнительных компиляторов, и они все будут работать. Библиотеки времени выполнения в Ubuntu 20.04 поддерживают код, скомпилированный с помощью любого из этих компиляторов.
Почему же не поставлять GCC 10.3 с Ubuntu 20.04? Библиотеки времени выполнения, как правило, более стабильны, чем компиляторы. GCC 10 был впервые выпущен (как 10.1) примерно в то время, когда создавался 20.04. Создание версии LTS с совершенно новым компилятором было бы безрассудно; поставка новых библиотек времени выполнения, после их тестирования с кодом, построенным с использованием GCC 9, гораздо безопаснее и позволяет добавить GCC 10, когда он стабилизируется.
Canonical не предоставляет GCC 11 для 20.04, потому что у него нет необходимых библиотек времени выполнения. Для этого вам нужна более поздняя версия Ubuntu.
Как узнать все это
/usr/share/doc/gcc/README.Debian
содержит некоторую информацию.
dpkg-query --listfiles gcc-10-base
показывает, что gcc-10-base только предоставляет документацию.
dpkg-query --listfiles libgcc-s1
показывает, что libgcc-s1 предоставляет /lib/x86_64-linux-gnu/libgcc_s.so.1
, который является одной из основных библиотек времени выполнения для GCC.
Другие основные библиотеки времени выполнения для C/C++ – это glibc, которая не зависит от GCC, и libstdc++. dpkg-query -list | grep libstdc
показывает нам два пакета:
ii libstdc++-9-dev:amd64 9.3.0-17ubuntu1~20.04 amd64 GNU Standard C++ Library v3 ...
ii libstdc++6:amd64 10.3.0-1ubuntu1~20.04 amd64 GNU Standard C++ Library v3
libstdc++6
– это версия GCC 10.3; пакет -dev
– это версия GCC 9.3.
dpkg-query --listfiles libstdc++-9-dev
показывает, что этот пакет предоставляет заголовочные файлы, архивные библиотеки и документацию для разработки на C++ с помощью GCC 9.
dpkg-query --listfiles libstdc++6
показывает, что этот пакет предоставляет документацию, некоторые сценарии Python и два действительно важных файла:
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28
Файл .so.6
– это то, с чем связаны программы. На самом деле это символическая ссылка на файл .so.6.028
. Это название версии libstdc++ для GCC 10, библиотеки поддержки GCC для C++. Вы можете получить сопоставление между этими именами и версиями GCC здесь. Прокрутите вниз, и вы найдете некоторые таблицы.
GCC, используемый для сборки Ubuntu
Самое простое, что можно проверить, это glibc. Строить это с помощью другого компилятора, чем остальные компоненты ОС, было бы безумно, и вы можете узнать, какой компилятор использовался для его сборки, просто спросив:
/usr/lib/x86_64-linux-gnu/libc.so.6
GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.7) стабильная версия 2.31.
Copyright (C) 2020 Free Software Foundation, Inc.
Это бесплатное программное обеспечение; смотрите источник для условий копирования.
Гарантии НЕТ; даже не для ТОРГОВЛИ или ПРИГОДНОСТИ ДЛЯ О
ОПРЕДЕЛЕННОЙ ЦЕЛИ.
Скомпилировано с помощью GNU CC версии 9.3.0.
ABI libc: UNIQUE IFUNC ABSOLUTE
Инструкции по отчетности об ошибках смотрите на:
https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs.
Просто комментарий: я рвал на себе волосы, потому что мне нужно было установить старую инструментальную цепочку gcc 9.5, и по странному стечению обстоятельств я не мог найти библиотеку libcc1.so, которая должна была находиться в пакетах libgcc1, которые, похоже, были удалены с лица земли и из всех архивов Ubuntu. Оказалось, что я могу использовать пакеты libgcc1 версии 10.1, что стало настоящим спасением. Также спасибо за другие insights, предоставленные в вашем вкладе! Спасибо, приятель!
Ответ или решение
Обсуждение версий libgcc-s1 и gcc-base в Ubuntu 20.04 LTS
Ubuntu 20.04 LTS, как и многие версии операционной системы, использует набор библиотек и инструментов разработки, которые могут отличаться по версии от стандартного компилятора GCC, установленного по умолчанию. В случае Ubuntu 20.04 LTS, в частности в базовом образе Docker, мы видим следующие версии: libgcc-s1 и gcc-10-base версии 10.3.0(-1ubuntu1~20.04). Однако стандартная версия GCC для этой версии Ubuntu – это GCC 9. Это вызывает определенное недоумение, и ниже мы рассмотрим причины этой ситуации более подробно.
Объяснение несоответствия версий
-
Разные роли пакетов:
- Пакет gcc-10-base в основном предоставляет документацию и не содержит исполняемых файлов компилятора.
- Пакет libgcc-s1 необходим для обеспечения работы с функциями, сгенерированными компилятором, включая обработку исключений в C++. Эти библиотеки имеют критически важное значение для работы программ, написанных на C и C++.
-
Совместимость библиотек:
- Библиотеки GCC, такие как libgcc и libstdc++, имеют четкие правила совместимости. Это означает, что более свежая версия библиотеки будет работать с кодом, скомпилированным более ранними версиями компилятора. Например, бинарные файлы, скомпилированные с помощью GCC 9, будут совместимы с более новыми библиотеками, предоставляющими GCC 10. Это позволяет избежать проблем с совместимостью при обновлении библиотек.
Зачем использовать более новые версии библиотек?
Использование более новых версий библиотек в дистрибутиве Ubuntu 20.04 LTS связано с обеспечением стабильности и безопасности системы. Хотя GCC 10 был первоначально выпущен в рамках разработки Ubuntu 20.04, принимать решение о внедрении только что выпущенного компилятора в LTS-версию было бы рискованно. Вместо этого разработчики Ubuntu выбрали более поздние версии библиотек, которые уже прошли тестирование и признаны стабильными, что обеспечивает большую предсказуемость и надежность.
Как это повлияет на компиляцию и приложения?
-
Компиляция с помощью GCC 9:
- Большинство программного обеспечения, предоставляемого в Ubuntu 20.04, было скомпилировано с использованием GCC 9. Однако это не означает, что разработчики не могут использовать GCC 10 для своих собственных проектов. При установке дополнительных версий компилятора пользователи могут собирать и запускать свои приложения с использованием GCC 10, зная, что соответствующие библиотеки уже находятся в системе.
-
Обеспечение совместимости:
- Использование библиотек, совместимых с обоими компиляторами (GCC 9 и 10), позволяет избежать проблем с миграцией и интеграцией в будущем. Это также упрощает разработку и тестирование, так как разработчики могут использовать более свежие возможности языков C и C++, не боясь нарушения совместимости.
Как выяснить используемые версии
Для опытных пользователей и разработчиков в Ubuntu существуют удобные команды, которые помогут проверить версии установленных библиотек и их источники. Например, команды:
dpkg-query --listfiles gcc-10-base
dpkg-query --listfiles libgcc-s1
dpkg-query --listfiles libstdc++6
помогут узнать, какие библиотеки присутствуют в системе и какие версии имеют.
Заключение
Таким образом, несоответствие версий между компилятором по умолчанию и используемыми библиотеками в Ubuntu 20.04 LTS объясняется безопасностью, совместимостью и стремлением предоставить пользователям возможность использовать более свежие инструменты без ущерба для стабильности системы. Это подход, который был применен на протяжении многих лет и продолжает оставаться основным принципом в разработке баланса между новизной и надежностью в Ubuntu.
Если у вас есть дополнительные вопросы или колебания относительно этой темы, не стесняйтесь обращаться за помощью.