Линукс статическая линковка мертва? - PullRequest
57 голосов
/ 07 августа 2010

Фактически, флаг -static gcc в Linux сейчас не работает.Позвольте мне процитировать из GNU libc FAQ:

2.22.Даже статически связанные программы нуждаются в некоторых общих библиотеках, что для меня неприемлемо.Что я могу сделать?

{AJ} NSS (для подробностей просто наберите "info libc" Name Service Switch ") не будет работать должным образом без разделяемых библиотек.NSS позволяет использовать разные сервисы (например, NIS, файлы, базы данных, hesiod), просто изменив один файл конфигурации (/etc/nsswitch.conf) без перепривязки каких-либо программ.Единственным недостатком является то, что теперь статическим библиотекам необходим доступ к общим библиотекам.Это прозрачно обрабатывается библиотекой GNU C.

Решением является настройка glibc с параметром --enable-static-nss.В этом случае вы можете создать статический бинарный файл, который будет использовать только сервисы dns и файлы (для этого измените /etc/nsswitch.conf).Вы должны явно ссылаться на все эти сервисы.Например:

 gcc -static test-netdb.c -o test-netdb \
   -Wl,--start-group -lc -lnss_files -lnss_dns -lresolv -Wl,--end-group

Проблема этого подхода заключается в том, что вам необходимо связать каждую статическую программу, использующую процедуры NSS, со всеми этими библиотеками.
{UD} Фактически, однабольше не могу сказать, что libc, скомпилированный с этой опцией, использует NSS.Больше нет переключателя.Поэтому настоятельно рекомендуется не использовать --enable-static-nss, так как это делает поведение программ в системе несовместимым.

Что касается этого факта, есть ли сейчас какой-нибудь разумный способ создать полнофункциональную статическую сборку в Linux, или статическое связывание полностью не работает в Linux?Я имею в виду статическую сборку, которая:

  • ведет себя точно так же, как динамическая сборка (static-nss с непоследовательным поведением - зло!);
  • Работает на разумных вариациях среды glibc иВерсии для Linux;

Ответы [ 6 ]

39 голосов
/ 14 декабря 2010

Я думаю, что это очень раздражает, и я считаю высокомерным называть функцию «бесполезной», потому что у нее есть проблемы, связанные с определенными вариантами использования. Самая большая проблема с подходом glibc заключается в том, что он жестко кодирует пути к системным библиотекам (gconv, а также nss), и поэтому он ломается, когда люди пытаются запустить статический двоичный файл в дистрибутиве Linux, отличном от того, для которого он был создан.

В любом случае, вы можете обойти проблему gconv, установив GCONV_PATH, чтобы он указывал на соответствующее местоположение, это позволило мне взять двоичные файлы, созданные на Ubuntu, и запустить их на Red Hat.

25 голосов
/ 09 августа 2010

Что касается этого факта, есть ли сейчас какой-нибудь разумный способ создать полнофункциональную статическую сборку в Linux, или статическая компоновка полностью отсутствует в Linux?

Я не знаю, где найти исторические ссылки, но да, статическое связывание не работает в системах GNU. (Я считаю, что он умер при переходе с libc4 / libc5 на libc6 / glibc 2.x.)

Функция была признана бесполезной в свете:

  • Уязвимости безопасности. Приложение, которое было статически связано, даже не поддерживает обновление libc. Если приложение было связано в системе, содержащей уязвимость lib, оно будет сохранено в статически связанном исполняемом файле.

  • Раздувание кода. Если многие статически связанные приложения запускаются в одной и той же системе, стандартные библиотеки не будут использоваться повторно, поскольку каждое приложение содержит внутри свою собственную копию всего. (Попробуйте du -sh /usr/lib, чтобы понять масштабы проблемы.)

Попробуйте копать архивы списков рассылки LKML и glibc 10-15 лет назад. Я уверен, что давно я видел что-то связанное с LKML.

18 голосов
/ 07 июля 2016

Статическое связывание, похоже, не очень нравится в мире Linux. Вот мой дубль.

Люди, которые не видят привлекательности статического связывания, обычно работают в области ядра и операционной системы более низкого уровня. Многие разработчики * nix библиотек потратили целую жизнь на решение неизбежных проблем, связанных с попыткой связать сотню постоянно меняющихся библиотек - задача, которую они выполняют каждый день. Взгляните на автоинструменты, если вы хотите узнать, какие сальто они могут выполнять.

Но никто не должен тратить на это большую часть своего времени. Статическое связывание продвинет вас далеко от буферизации библиотеки. Разработчик может обновить зависимости своего программного обеспечения в соответствии с расписанием программного обеспечения, вместо того, чтобы быть вынужденным делать это в момент появления новых версий библиотеки. Это важно для ориентированных на пользователя приложений со сложными пользовательскими интерфейсами, которым необходимо управлять потоком многих библиотек более низкого уровня, от которых они неизбежно зависят. И именно поэтому я всегда буду фанатом статических ссылок. Если вы можете статически связывать кросс-скомпилированный переносимый код C и C ++, вы в значительной степени сделали мир устрицей, поскольку сможете быстрее доставлять сложное программное обеспечение для широкого спектра постоянно растущих устройств в мире.

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

12 голосов
/ 07 августа 2010

То, что вам необходимо динамически связываться со службой NSS, не означает, что вы не можете статически связываться с любой другой библиотекой.Все, что часто задаваемые вопросы говорят о том, что даже «статически» связанные программы имеют некоторые динамически связанные библиотеки.Это не значит, что статическое связывание «невозможно» или «не работает».

9 голосов
/ 01 января 2015

Добавление на другие ответы:

По причинам, указанным в других ответах, это не рекомендуется для большинства дистрибутивов Linux, но на самом деле существуют дистрибутивы, созданные специально для запуска статически связанных двоичных файлов:

Из стали описания:

static linux основан на отобранной вручную коллекции лучших инструментов для каждой задачи и каждого инструмента статически связаны (включая некоторые X такие клиенты, как st, surf, dwm, dmenu),

Он также нацелен на уменьшение размера двоичного файла за счет исключения glibc. и другие раздутые библиотеки GNU, где это возможно (ранние эксперименты показывают, что статически связанные двоичные файлы обычно меньше, чем их динамически связанные аналоги glibc !!!). Обратите внимание, это в значительной степени вопреки тому, что Ульрих Дреппер считает о статическом связывании.

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

Статическое связывание также помогает уменьшить зависимость.

Вы можете узнать больше об этом в этот вопрос о статических и динамических связях .

8 голосов
/ 26 июня 2019

Статическое связывание снова на подъеме!

  • Многие (большинство?) Go исполняемые файлы языка программирования статически связаны.
    • Повышенная мобильность и обратная совместимость - одна из причин их популярности.
  • Другие языки программирования прилагают аналогичные усилия для упрощения статического связывания, например Haskell (я работаю над этим усилия ).
  • Настраиваемые Linux-дистрибутивы / наборы пакетов, такие как NixOS / nixpkgs позволяют статически связывать большую часть их пакетов (например, pkgsStatic пакетный набор может обеспечить все виды статически связанных исполняемых файлов).
  • Статическое связывание может привести к лучшему исключению неиспользуемого кода во время соединения, уменьшая размер исполняемых файлов.
  • libcs ​​вроде musl делают статическое связывание простым и правильным.
  • Некоторые крупные разработчики программного обеспечения руководители с этим согласны. Например, Google пишет новую библиотеку libc, нацеленную на статическое связывание ( "поддержка статического связывания без PIE и статического пирога" , ", в который мы не намерены вкладывать средства point [in] поддержка динамической загрузки и компоновки ").
...