Есть 2 аргумента для наличия общих библиотек:
- Это помогает уменьшить дисковое пространство.
- Когда общая библиотека обновляется, все бинарные файлы, в зависимости от нее, получают обновление.
У разделяемых библиотек есть в основном один недостаток:
- Они (могут) ввести ад зависимости.
На настольных компьютерах 1-е преимущество больше не имеет места. В настоящее время потеря дискового пространства не является большой проблемой.
Наличие статических двоичных файлов позволило бы нам улучшить работу менеджеров пакетов - я имею в виду, что ад зависимости зависел бы в прошлом. Добавление программы будет просто добавлением двоичного файла; в конце концов, папка, позволяющая обрабатывать файлы. Удаление программы - это просто удаление этого файла. Зависимости? Прошло.
Второе преимущество остается в силе, но я думаю, что преимущество статических двоичных файлов на настольных компьютерах перевешивает его. Я имею в виду, что даже новые языки, такие как Go, компилируют все свои двоичные файлы, несмотря на преимущества общих библиотек, из-за удобства.
Поскольку одно из главных преимуществ разделяемых библиотек больше не имеет большого значения, все еще не одобряются статические библиотеки C? Если так, то почему?
Ответы:
Предпосылка вашего вопроса ошибочна. То, что осуждается, - это придерживаться доктринеров и абсолютов, не понимая их основ (программирование грузового культа?).
Связанный ответ SO является интересным исследованием в этой самой теме - Вопрос был о том, почему не работает опция компиляции с -static, а ответ, на который вы ссылались, был не более чем разглагольствованием о том, что не используется статическое связывание. Если не обсуждает, почему это плохо, а требует, то ОП использует динамическое связывание. К сожалению, он помечен как правильный ответ (следующий ответ имеет в два раза больше голосов и является правильным ответом на вопрос ОП), потому что, хотя правильный ответ есть, он глубоко скрыт в догматическом мнении.
Реальный вопрос заключается в том, каковы плюсы и минусы статического и динамического связывания, и когда один из них предпочтительнее другого.
источник
С точки зрения разработчика, динамическое связывание часто может значительно ускорить ваш цикл компиляции / ссылки / тестирования.
С точки зрения управления пакетами, например, возьмем libGL. У меня есть примерно дюжина различных его реализаций, доступных в моем менеджере пакетов, некоторые общие и некоторые ориентированные на конкретные видеокарты. Если бы он не был динамически связан, то было бы дюжина версий каждой программы, которая связана с libGL, иначе вам пришлось бы придумать дополнительный уровень абстракции, который не был бы столь же эффективен, как вызов функции.
Подумайте о проблеме безопасности в популярной библиотеке, такой как Qt. С помощью динамического связывания я могу просто обновить этот пакет, вместо того, чтобы идентифицировать, перекомпилировать и развертывать каждый отдельный пакет, который связывает в Qt.
Статическое связывание может иметь преимущества в независимо развернутых приложениях с закрытым исходным кодом, но при управлении пакетами с открытым исходным кодом это приносит больше вреда, чем помогает.
источник
Общие библиотеки сильно предпочитает Linux распределение сопровождающих для вашей основном причины # 2. Для них действительно важно, что, например, когда кто-то находит ошибку безопасности в zlib , ему не нужно перекомпилировать каждую из программ, использующих zlib - не только это будет стоить им больше циклов ЦП для выполнения после перекомпиляции каждый, кто использует дистрибутив, должен будет заново загрузить все эти программы. Между тем, в наборе пакетов, предоставляемых дистрибутивом, ад зависимости не является проблемой, потому что все проверено на работу с этим набором библиотек.
Если вы создаете стороннее программное обеспечение, для которого нужны библиотеки, которых нет в вашем дистрибутиве, то статическое связывание этих библиотек может быть менее сложным, чем альтернатива, и это нормально.
Другая важная вещь, которую нужно знать, это то, что GNU
libc
и GCClibstdc++
имеют компоненты, которые не работают надежно, если библиотека статически связана. Наиболее распространенная проблема связана сdlopen
тем, что любой загружаемый модульdlopen
сам по себе динамически связан сlibc.so.6
. Таким образом, это означает, что теперь у вас есть две копии библиотеки C в вашем адресном пространстве, и веселье наступает, когда они не соглашаются с тем, какая копия внутреннейmalloc
структуры данных (например) является авторитетной. Становится все хуже: целая куча функций , которые , кажется , не имеет ничего общего сdlopen
, какgethostbyname
иiconv
, использоватьdlopen
внутренне (так что их поведение настраивается во время выполнения). К счастью, ABI для libc и libstdc ++ очень стабилен, поэтому вы вряд ли столкнетесь с проблемами их динамического связывания.источник
Я согласен с последним замечанием Мэтнза: этот вопрос - загруженный вопрос. Предполагается, что статическое связывание плохое. Я могу думать о двух причинах, почему это не так:
Статическое связывание является безопасным: если общая библиотека обновляется таким образом, что приложение использует новую (возможно, новая перезаписывает старую или удаляется старая), это может создать риск того, что новая версия сломает приложение. Это изменение кода выходит за рамки официального обновления для приложения. Это, возможно, не было проверено. Статическое связывание обходит стороной, не разделяя библиотеки извне. Я считаю, что это является недостатком для разделяемых библиотек из-за этого риска. Что, если новая версия общей библиотеки представляет новую ошибку, которая ломает некоторые старые приложения?
Статическое связывание гарантирует, что приложение более автономно. Хотя совместно используемые библиотеки можно размещать вместе с основным исполняемым файлом, часто они хранятся в общих местах. Статически связанные приложения легче обеспечить «переносимыми» в смысле «не требующих изменений в файлах, каталогах или настройках, принадлежащих ОС» (например, каталог Windows, реестр и т. Д.).
источник
Статические и динамические библиотеки имеют свое использование. Глядя на одно приложение по объему, мы получаем другое представление о том, что необходимо, а что нет.
Статическое связывание существенно упрощает развертывание приложения. Не нужно обнаруживать и иметь дело с разными версиями. Просто испечь и развернуть.
Очевидным преимуществом динамических библиотек является возможность применять обновления независимо.
Это одна из причин, по которой я ненавижу maven и других подобных динамических компоновщиков компоновок проектов для java. Они ожидают, что одна версия библиотеки будет доступна по заданному URL навсегда. Непонимание проблемы, которая возникает через 10 лет, когда никто не может скомпилировать приложение, потому что все исходники и файлы jar пропали.
источник
FooLib1.8
такую возможность, невозможно включить код этой библиотеки в свой исполняемый пакет стандартным способом, чтобы позволить поставляемой вместе с ней утилитеFooLib1.9
обновления обновить или понизить ее версию? Способ хранения кода в Classic Macintosh сделал бы это довольно легко; есть ли причина, по которой сегодняшние системы не могут сделать это еще лучше?