Полная совместимость. Как работают статические исполняемые файлы в Linux - «Новости» » Самоучитель CSS
Меню
Наши новости
Учебник CSS

Невозможно отучить людей изучать самые ненужные предметы.

Введение в CSS
Преимущества стилей
Добавления стилей
Типы носителей
Базовый синтаксис
Значения стилевых свойств
Селекторы тегов
Классы
CSS3

Надо знать обо всем понемножку, но все о немногом.

Идентификаторы
Контекстные селекторы
Соседние селекторы
Дочерние селекторы
Селекторы атрибутов
Универсальный селектор
Псевдоклассы
Псевдоэлементы

Кто умеет, тот делает. Кто не умеет, тот учит. Кто не умеет учить - становится деканом. (Т. Мартин)

Группирование
Наследование
Каскадирование
Валидация
Идентификаторы и классы
Написание эффективного кода

Самоучитель CSS

Вёрстка
Изображения
Текст
Цвет
Линии и рамки
Углы
Списки
Ссылки
Дизайны сайтов
Формы
Таблицы
CSS3
HTML5

Новости

Блог для вебмастеров
Новости мира Интернет
Сайтостроение
Ремонт и советы
Все новости

Справочник CSS

Справочник от А до Я
HTML, CSS, JavaScript

Афоризмы

Афоризмы о учёбе
Статьи об афоризмах
Все Афоризмы

Видео Уроки


Видео уроки
Наш опрос



Наши новости

       
13-08-2020, 12:39
Полная совместимость. Как работают статические исполняемые файлы в Linux - «Новости»
Рейтинг:
Категория: Новости

Многие пользователи Linux предпочитают устанавливать программы из репозиториев с помощью встроенного менеджера пакетов, а все прочие способы рассматривают как вынужденную меру. Однако разработчики дистрибутивов, очевидно, не могут включить в репозитории все программы в мире, а сами авторы программ тоже не всегда могут или хотят поддерживать пакеты под множество дистрибутивов и их версий.

В последние годы независимые от дистрибутива решения для установки пакетов набирают популярность: к 0install с его давней историей прибавились более новые Flatpak и Snap, да и в Steam игр для Linux становится больше.



Удобнее всего может быть обойтись без установки вообще — просто скачать файл, сделать его исполняемым с помощью chmod +x Рё запустить. Р’ этой статье РјС‹ рассмотрим, почему это возможно Рё как это реализовать.



 

Двоичная совместимость в системах на основе Linux



Часто можно услышать, что в Linux плохо с двоичной совместимостью. При этом люди имеют в виду, что пакет из одной версии дистрибутива Linux порой невозможно поставить на другую, — и в этом они правы. Однако само утверждение о плохой двоичной совместимости версий Linux неверно.



Нужно вспомнить, что Linux — это только ядро, а вся операционная система состоит из ядра, разделяемых библиотек и программ. Библиотеки можно разделить на стандартные библиотеки языков (например, libc, libstd++) и сторонние библиотеки (например, GTK, Qt). Так вот, причиной сломанной двоичной совместимости, как правило, оказываются именно сторонние библиотеки.



Границы ABI, то есть места, где что-то может сломаться, зависят от метода компоновки (linking): статического или динамического.



Границы ABI при статической и динамической компоновке
Границы ABI при статической и динамической компоновке

При динамической компоновке стабильным должен оставаться ABI всех задействованных библиотек. При этом ABI ядра может меняться, если библиотеки это компенсируют. При статической компоновке важна только стабильность ABI ядра. Рассмотрим, как с этим в Linux.



 

Совместимость библиотек



ABI библиотеки — это набор символов, которые она экспортирует. Может ли он быть стабильным? Да, реализация формата ELF в Linux поддерживает версионирование символов. С помощью этого механизма библиотеки могут предоставлять несколько версий одной и той же функции с разными сигнатурами и поведением.



Очевидный недостаток этого подхода — невозможно удалить из библиотеки старый код без риска сломать совместимость. Каждый раз, когда сигнатура или поведение функции меняется, автор должен создать копию старой функции. Кроме того, указывать соответствие имен функций в исходном коде и версий символов этих функций в двоичном — обязанность разработчика.



Не у каждого разработчика есть время и возможность поддерживать совместимость таким образом. Кроме того, радикальные изменения во внутренностях библиотеки могут сделать этот подход совершенно непрактичным — придется, по сути, собирать один двоичный файл из нескольких версий исходного кода.



Р?менно РёР·-Р·Р° идеи сделать как можно больше библиотек общими для всех пакетов РјС‹ Рё РЅРµ можем поставить пакет РёР· Debian 9 РЅР° 10 или РёР· CentOS 6 РЅР° 8 — сторонние библиотеки РЅРµ РІС…РѕРґСЏС‚ РІ пакет, Р° РёС… ABI РЅРµ остается неизменным между версиями.



Однако разработчики GNU libc серьезно относятся к совместимости и версионируют все символы. Благодаря этому, если собрать программу на машине со старой версией glibc, она будет работать с более новыми (но не наоборот).



 

Совместимость версий ядра



ABI СЏРґСЂР° представляет СЃРѕР±РѕР№ соглашение Рѕ системных вызовах, Р° также номера Рё РїРѕСЂСЏРґРѕРє аргументов отдельных вызовов. Рљ примеру, чтобы попросить СЏРґСЂРѕ выполнить write — системный вызов для записи данных в файл, нужно поместить в один регистр процессора номер этого вызова, а в три других регистра — номер файлового дескриптора, указатель на буфер с данными и размер данных в байтах. Любая функция для записи в файл или вывода текста на экран (то есть записи в файлы stdout и stderr с дескрипторами 1 и 2 соответственно) — обертка к этому вызову.



Самый низкий уровень стандартной библиотеки любого языка — набор оберток к системным вызовам. Если изменится ABI ядра, перестанут работать все библиотеки. К счастью, в Linux такого не происходит — интерфейс системных вызовов исключительно стабилен. Линус Торвальдс строго следит за соблюдением совместимости и ругается на всех, кто ее пытается случайно или намеренно сломать.



Благодаря такой политике любая программа из времен ядра 2.6 будет нормально работать и на 5.x, если она не использует никакие разделяемые библиотеки.



Более того, новые программы могут работать на старых ядрах, если используют только старые системные вызовы.


А что в других системах?



Из распространенных свободных Unix-подобных систем Linux — единственная с такими гарантиями совместимости ABI ядра.



Именно поэтому для Linux существует множество альтернативных стандартных библиотек языка C (musl, dietlibc, uclibc, newlib...). По этой же причине FreeBSD реализует двоичную совместимость с Linux, но не наоборот — FreeBSD не дает гарантий стабильности ABI между релизами.



Поддержка версионирования символов в GNU libc тоже нетипична для реализаций стандартной библиотеки.



Таким образом, возможностей для двоичной совместимости в Linux больше, чем во многих других системах, — нужно только ими пользоваться.


Выводы



Из всего сказанного видно, что статическая сборка — залог совместимости с любой системой на основе Linux, причем и с более новыми ядрами, и с более старыми.



Альтернативный подход — AppImage тоже позволяет собрать все в один файл, но этот файл на деле представляет собой сжатый образ SquashFS с исполняемым файлом и динамическими библиотеками внутри. Увы, инструменты автоматического поиска и упаковки всех нужных библиотек капризны, и детальное рассмотрение этого подхода не поместится в рамки нашей статьи. Мы сосредоточимся на статической компоновке.


Практика



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


Многие пользователи Linux предпочитают устанавливать программы из репозиториев с помощью встроенного менеджера пакетов, а все прочие способы рассматривают как вынужденную меру. Однако разработчики дистрибутивов, очевидно, не могут включить в репозитории все программы в мире, а сами авторы программ тоже не всегда могут или хотят поддерживать пакеты под множество дистрибутивов и их версий. В последние годы независимые от дистрибутива решения для установки пакетов набирают популярность: к 0install с его давней историей прибавились более новые Flatpak и Snap, да и в Steam игр для Linux становится больше. Удобнее всего может быть обойтись без установки вообще — просто скачать файл, сделать его исполняемым с помощью chmod x Рё запустить. Р’ этой статье РјС‹ рассмотрим, почему это возможно Рё как это реализовать. Двоичная совместимость РІ системах РЅР° РѕСЃРЅРѕРІРµ Linux Часто можно услышать, что РІ Linux плохо СЃ двоичной совместимостью. РџСЂРё этом люди имеют РІ РІРёРґСѓ, что пакет РёР· РѕРґРЅРѕР№ версии дистрибутива Linux РїРѕСЂРѕР№ невозможно поставить РЅР° РґСЂСѓРіСѓСЋ, — Рё РІ этом РѕРЅРё правы. Однако само утверждение Рѕ плохой двоичной совместимости версий Linux неверно. Нужно вспомнить, что Linux — это только СЏРґСЂРѕ, Р° РІСЃСЏ операционная система состоит РёР· СЏРґСЂР°, разделяемых библиотек Рё программ. Библиотеки можно разделить РЅР° стандартные библиотеки языков (например, libc, libstd ) Рё сторонние библиотеки (например, GTK, Qt). Так РІРѕС‚, причиной сломанной двоичной совместимости, как правило, оказываются именно сторонние библиотеки. Границы ABI, то есть места, РіРґРµ что-то может сломаться, зависят РѕС‚ метода РєРѕРјРїРѕРЅРѕРІРєРё (linking): статического или динамического. Границы ABI РїСЂРё статической Рё динамической РєРѕРјРїРѕРЅРѕРІРєРµ РџСЂРё динамической РєРѕРјРїРѕРЅРѕРІРєРµ стабильным должен оставаться ABI всех задействованных библиотек. РџСЂРё этом ABI СЏРґСЂР° может меняться, если библиотеки это компенсируют. РџСЂРё статической РєРѕРјРїРѕРЅРѕРІРєРµ важна только стабильность ABI СЏРґСЂР°. Рассмотрим, как СЃ этим РІ Linux. Совместимость библиотек ABI библиотеки — это набор символов, которые РѕРЅР° экспортирует. Может ли РѕРЅ быть стабильным? Да, реализация формата ELF РІ Linux поддерживает версионирование символов. РЎ помощью этого механизма библиотеки РјРѕРіСѓС‚ предоставлять несколько версий РѕРґРЅРѕР№ Рё той же функции СЃ разными сигнатурами Рё поведением. Очевидный недостаток этого РїРѕРґС…РѕРґР° — невозможно удалить РёР· библиотеки старый РєРѕРґ без СЂРёСЃРєР° сломать совместимость. Каждый раз, РєРѕРіРґР° сигнатура или поведение функции меняется, автор должен создать РєРѕРїРёСЋ старой функции. РљСЂРѕРјРµ того, указывать соответствие имен функций РІ РёСЃС…РѕРґРЅРѕРј РєРѕРґРµ Рё версий символов этих функций РІ двоичном — обязанность разработчика. РќРµ Сѓ каждого разработчика есть время Рё возможность поддерживать совместимость таким образом. РљСЂРѕРјРµ того, радикальные изменения РІРѕ внутренностях библиотеки РјРѕРіСѓС‚ сделать этот РїРѕРґС…РѕРґ совершенно непрактичным — придется, РїРѕ сути, собирать РѕРґРёРЅ двоичный файл РёР· нескольких версий РёСЃС…РѕРґРЅРѕРіРѕ РєРѕРґР°. Р?менно РёР·-Р·Р° идеи сделать как можно больше библиотек общими для всех пакетов РјС‹ Рё РЅРµ можем поставить пакет РёР· Debian 9 РЅР° 10 или РёР· CentOS 6 РЅР° 8 — сторонние библиотеки РЅРµ РІС…РѕРґСЏС‚ РІ пакет, Р° РёС… ABI РЅРµ остается неизменным между версиями. Однако разработчики GNU libc серьезно относятся Рє совместимости Рё версионируют РІСЃРµ символы. Благодаря этому, если собрать программу РЅР° машине СЃРѕ старой версией glibc, РѕРЅР° будет работать СЃ более новыми (РЅРѕ РЅРµ наоборот). Совместимость версий СЏРґСЂР° ABI СЏРґСЂР° представляет СЃРѕР±РѕР№ соглашение Рѕ системных вызовах, Р° также номера Рё РїРѕСЂСЏРґРѕРє аргументов отдельных вызовов. Рљ примеру, чтобы попросить СЏРґСЂРѕ выполнить write — системный вызов для записи данных в файл, нужно поместить в один регистр процессора номер этого вызова, а в три других регистра — номер файлового дескриптора, указатель на буфер с данными и размер данных в байтах. Любая функция для записи в файл или вывода текста на экран (то есть записи в файлы stdout и stderr с дескрипторами 1 и 2 соответственно) — обертка к этому вызову. Самый низкий уровень стандартной библиотеки любого языка — набор оберток к системным вызовам. Если изменится ABI ядра, перестанут работать все библиотеки. К счастью, в Linux такого не происходит — интерфейс системных вызовов исключительно стабилен. Линус Торвальдс строго следит за соблюдением совместимости и ругается на всех, кто ее пытается случайно или намеренно сломать. Благодаря такой политике любая программа из времен ядра 2.6 будет нормально работать и на 5.x, если она не использует никакие разделяемые библиотеки. Более того, новые программы могут работать на старых ядрах, если используют только старые системные вызовы. А что в других системах? Из распространенных свободных Unix-подобных систем Linux — единственная с такими гарантиями совместимости ABI ядра. Именно поэтому для Linux существует множество альтернативных стандартных библиотек языка C (musl, dietlibc, uclibc, newlib.). По этой же причине FreeBSD реализует двоичную совместимость с Linux, но не наоборот — FreeBSD не дает гарантий стабильности ABI между релизами. Поддержка версионирования символов в GNU libc тоже нетипична для реализаций стандартной библиотеки. Таким образом, возможностей для двоичной совместимости в Linux больше, чем во многих других системах, — нужно только ими пользоваться. Выводы Из всего сказанного видно, что статическая сборка — залог совместимости с любой системой на основе Linux, причем и с более новыми ядрами, и с более старыми. Альтернативный подход — AppImage тоже позволяет собрать все в один файл, но этот файл на деле представляет собой сжатый образ SquashFS с исполняемым файлом и динамическими библиотеками внутри. Увы, инструменты автоматического поиска и упаковки всех нужных библиотек капризны, и детальное рассмотрение этого подхода не поместится в рамки нашей статьи. Мы сосредоточимся на статической компоновке. Практика Для примера мы используем несложную программу, которая проверяет соответствие строки регулярному выражению. Мы соберем ее несколькими разными способами и посмотрим, как убедиться, что файл вышел действительно статический.

Теги: CSS

Просмотров: 492
Комментариев: 0:   13-08-2020, 12:39
Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

 
Еще новости по теме:



Другие новости по теме:
Комментарии для сайта Cackle