Чи насунуті статичні бібліотеки? [зачинено]


11

Є два аргументи для спільного використання бібліотек:

  1. Це сприяє зменшенню місця на диску.
  2. Коли оновлена ​​бібліотека оновлюється, всі бінарні файли залежно від неї отримують оновлення.

В основному є один недолік спільних бібліотек:

  • Вони (можуть) ввести залежність пекла.

На настільних комп’ютерах перша перевага насправді вже не є. Втрата часу на диску не є великою проблемою в ці дні.

Наявність статичних двійкових файлів дозволило б нам покращити менеджерів пакетів - я маю на увазі, пекло залежностей було б минулим. Додавання програми було б просто додаванням двійкового файлу; врешті-решт папка, щоб вона обробляла свої файли. Видалити програму було б просто видалити цей файл. Залежності? Пропав.

Друга перевага все ще залишається, але я думаю, що перевага статичних двійкових файлів на настільних комп’ютерах переважає її. Я маю на увазі, що навіть нові мови, як-от Go, збирають усі свої двійкові файли, незважаючи на переваги спільних бібліотек, через зручність.


Оскільки одна з головних переваг бібліотек, що поділяються, вже не є великою справою, чи статичні бібліотеки С все ще нахмурені? Якщо так, то чому?


4
Основна причина того, що C більше використовується, полягає в тому, що ви не працюєте на сучасних настільних комп’ютерах.
Теластин,

18
@Telastyn Вибачте? Більшість програмного забезпечення, встановлених на моїх настільних комп’ютерах, написані на C.
Флоріан Маргайн

6
Бічний біт - сайт, який читається на тему - Динамічне посилання вважається шкідливим

6
Однією з переваг динамічних бібліотек є те, що люди все ще можуть оновити бібліотеки, щоб вирішити помилки, безпечні отвори чи проблеми з обладнанням у вашій 15-річній грі із закритим джерелом, яка давно перестала отримувати оновлення. Вигляд нішевого випадку, але оскільки хороші ігри не є товарами, "просто використовувати іншу програму" насправді не допомагає. Це також має значення для дотримання LGPL без відкритого пошуку власного коду.
Doval

4
Ви забули дві інші переваги бібліотек, що поділяються: 1) їм також належить поділитися в пам'яті; 2) всі лінкери погано смокчуть, а зв’язувати величезний бінарний вкрай неприємно. Розбиття двійкового файлу на кілька менших об'єктів робить весь процес набагато більш терпимим.
SK-логіка

Відповіді:


9

Передумова вашого запитання хибна. Те, що нахмуриться, дотримується доктринальних і абсолютних без розуміння основи, що стоїть за ними (Cargo Cult Programming?).

Пов'язана відповідь ТА є цікавим дослідженням у цій самій темі. Питання стосувалося того, чому компіляція із -статичним варіантом не працює, відповідь, на яку ви посилаєтесь, була не що інше, як скандал про використання статичного посилання. Якщо не обговорюється, чому це погано, і вимагає, щоб ОП використовує динамічні зв'язки. Прикро, що вона позначена як правильна відповідь (наступна відповідь має вдвічі більше голосів і є правильною відповіддю на питання ОП), оскільки, хоча правильна відповідь є, її глибоко приховано серед догматичної думки.

Справжнє питання полягає у тому, які плюси та мінуси статичного та динамічного зв’язування та коли можна віддати перевагу іншим.


2
Відповідь Basile в дійсно сказати вам точно , чому він рекомендує використовувати колективні бібліотеки: ? «Чому ви хочете , щоб посилання статично ваше додаток . Як правило , це помилка (бо ви не прибули від оновлень для системи динамічних бібліотек) Зокрема , перемикач служби імен засоби від libc хочуть динамічних бібліотек. " Це не" рент "тільки тому, що ви не згодні з цим.
Коді Грей

@Cody Відповідь, пов’язану з цим, була відредагована, оскільки я назвав її тиражем. Єдина думка, що я притримуюсь статичних та динамічних зв'язків, - це використовувати ту, яка відповідає вашим потребам, і розуміти сильні та слабкі сторони вибору, а не потрапляти в доктрину програмного культового культу, оскільки "хтось так сказав".
mattnz

Так, додано частину "Зокрема ..." Не впевнений, як це впливає на його статус ренту. Звичайно, я не прихильник програмування культового культу. Просто прихильники статичних зв'язків (на мій досвід) часто пропускають або недооцінюють проблеми безпеки. Статичне зв’язування може бути дуже підходящим для разових утиліт, що робить додаток самостійним і, отже, набагато простіше розповсюдження. Але будь-яка програма, яка буде широко розгорнута або використана для виробництва, дійсно повинна посилатися на спільну бібліотеку. Реальних недоліків немає: на цьому рівні програми вам уже потрібен процес розгортання.
Коді Грей

1
Хороший приклад того, де статичне зв’язування доречне, - це те, де я працюю - великі складні системи, що мають критичне значення для життя. Після того, як критичний модуль буде протестований і затверджений для роботи, його поведінка не повинна змінюватися, не проходячи «процес». Однак жодна операційна та нежиттєва важлива частина системи (виставлення рахунків та звітування) не потребує менш надійного контролю та використовує динамічні зв'язки.
mattnz

7

З точки зору розробника, динамічне посилання часто може значно прискорити компіляцію / посилання / тестовий цикл.

Наприклад, з точки зору управління пакетами, візьміть, наприклад, libGL. У мене в диспетчері пакунків доступно близько десятка різних його реалізацій, деякі загальні та деякі націлені на певні графічні карти. Якби це не було динамічно пов'язане, у кожної програми, що посилається на libGL, повинно бути десяток версій, інакше вам доведеться розробити додатковий рівень абстракції, який не такий ефективний, як виклик функції.

Подумайте про питання безпеки в такій популярній бібліотеці, як Qt. За допомогою динамічного посилання я можу просто оновити цей один пакет, замість того, щоб ідентифікувати, перекомпілювати та розгортати кожен пакет, який посилається у Qt.

Статичне зв’язування може мати переваги в незалежно розгорнутих програмах із закритим кодом, але в управлінні пакетами з відкритим кодом це шкодить більше, ніж допомагає.


2
Це правда (прискорення розвитку), але насправді неприємно, що це робить її виробництвом. Канонічний приклад - Firefox. Кількість інженерних зусиль (у вигляді жахливих злому), які ввійшли в прискорення динамічної роздільної здатності символів, завдяки чому завантаження Firefox у розумний час є абсолютно божевільним. Набагато кращі показники можна було б досягти за набагато менших затрат на інженерію, якби вони просто готові статично зв’язати весь свій проектний код (хоча при бажанні все ще динамічно пов'язують системні бібліотеки та плагіни).
R .. GitHub СТОПУВАТИ ДОПОМОГА

5

Менеджери дистрибуції Linux в основному надають перевагу спільним бібліотекам з точки зору вашої причини №2. Для них дуже важливо, що, наприклад, коли хтось виявить помилку безпеки в zlib , їм не доведеться перекомпілювати кожну програму, яка використовує zlib --- не тільки це коштуватиме їм більше циклів процесора, щоб зробити Після перекомпіляції кожен, хто використовує дистрибутив, повинен буде знову завантажити всі ці програми. Тим часом, у наборі пакетів, наданих дистрибутивом, пекло залежності не є проблемою, оскільки все тестується для роботи з цим набором бібліотек.

Якщо ви створюєте стороннє програмне забезпечення, яке потребує бібліотек, які не є у вашому розповсюдженні, то статично пов’язувати ці бібліотеки може бути менше клопоту, ніж альтернатива, і це добре.

Інша важлива річ, яку потрібно знати, це те libc, що libstdc++обидва GNU та GCC мають компоненти, які не працюють надійно, якщо бібліотека є стаціонарно пов'язаною. Найпоширеніша проблема полягає в dlopenтому, що будь-який модуль, який ви завантажуєте dlopen, сам по собі динамічно пов'язаний libc.so.6. Отже, це означає, що у вас є дві копії бібліотеки С у своєму адресному просторі, і веселість виникає тоді, коли вони не погоджуються, яка копія внутрішньої mallocструктури даних (наприклад) є авторитетною. Це стає гірше: ціла купа функцій, які, здається, не мають нічого спільного dlopen, як gethostbynameі з iconvвикористаннямdlopenвнутрішньо (щоб їх поведінку було налаштовано під час виконання). На щастя, ABI для libc та libstdc ++ дуже стабільний, тому навряд чи ви зіткнетеся з проблемами, що їх динамічно пов'язують.


2

Я погоджуюся з останнім моментом mattnz: це питання є завантаженим питанням. Це передбачає, що статичні зв'язки є поганими. Я можу придумати дві причини, чому це не так:

  • Статичне посилання є безпечним: якщо спільна бібліотека буде оновлена ​​таким чином, що програма використовує нову (можливо, нова перезаписала стару, або стару видалили), вона може ввести ризик, що нова версія зламає додаток. Це зміна коду за межами офіційного оновлення програми. Можливо, його не перевіряли. Статичне посилання пов’язує це, не обмінюючись бібліотеками зовні. Я вважаю, що це недолік для спільних бібліотек через цей ризик. Що робити, якщо нова версія спільної бібліотеки вводить нову помилку, яка порушує деякі старі програми?

  • Статичне посилання забезпечує додатки більш автономними. Хоча спільні бібліотеки можуть бути розміщені з основним виконуваним файлом, вони часто зберігаються у спільних місцях. Статично пов’язані програми легше забезпечити "портативний" у значенні "не вимагає змін у файлах, каталогах чи налаштуваннях, що належать ОС" (думаю, що каталог, реєстр Windows тощо).


Дякую, що покращили переваги, які я хотів зазначити. Однак якщо ви бачите більшість пакетів, що надаються, наприклад, дистрибутивами Linux, вони статично не складені. Це дійсно здається , що статична компіляція несхвалення, по крайней мере , з зовнішньої точки зору.
Флоріан Маргаїн

1
Динамічні бібліотеки на майже кожній ОС, що є сьогодні, перебувають під запитом. У пам'яті є лише сторінки, які фактично використовуються. Якщо декілька додатків використовують один і той же функціонал, вони поділять пам’ять і використовуватимуть менше, ніж об'єм статичної бібліотеки. Якщо кілька додатків використовують різні функції в одній бібліотеці, обидва набори функціональності будуть підключені до сторінки, що мають приблизно такий же вплив, як і статичний підхід.
Алан Шутко

@AlanShutko Я боровся і повторював цю частину кількома способами через те, що ви згадали. Жодних реальних гарантій немає, навіть якщо сучасні операційні системи на практиці пропонують ефективність спільних бібліотек з накладними витратами статики. Я відредагую ще раз.

@Snowman Я думаю, що основним моментом є те, що в будь-якій реалістичній операційній системі, яка забезпечує динамічне зв’язування (я не знаю жодної ОС, яка використовує динамічне посилання, але не вимагає підкачки), ваша друга точка не тримає води: пам'ять насправді не використовується якщо функція не використовується, і пам'ять, яку використовує динамічна бібліотека, можна ділити між різними програмами, що використовують її, що робить використання пам'яті для динамічної версії більш ефективним, ніж меншим. Ваша перша і третя причини справедливі, але я просто видалю другу: з будь-якими реалістичними припущеннями це просто неправильно.
Жуль

@Jules Я погоджуюся, це питання, яке було проблематичним та сумнівним у сучасних операційних системах. Я її зняв.

1

Статичні та динамічні бібліотеки мають власні потреби. Дивлячись на одну програму за обсягом, ми отримуємо інше уявлення про те, що потрібно, а що ні.

Статичне посилання різко спрощує розгортання програми. Не потрібно виявляти та мати справу з різними версіями. Просто запікайте і розгортайте.

Очевидною перевагою динамічних бібліотек є можливість самостійного застосування оновлень.

Це одна з причин, що я ненавиджу Maven та інших подібних розробників динамічних зв'язків для Java. Вони очікують, що єдиний варіант бібліотеки буде доступний за вказаною URL-адресою назавжди і назавжди. Не розуміючи проблеми, яка виникає через 10 років, коли ніхто не може скласти заявку, оскільки все джерело та банки вже немає.


Чи є якась конкретна причина, по якій програми, які використовують, FooLib1.8зможуть включити код для цієї бібліотеки у свій виконуваний пакет стандартним чином, щоб дозволити утиліту оновлення, що постачається разом із FooLib1.9її оновленням чи пониженням? Спосіб зберігання коду в класичному Macintosh зробив би це досить просто; Чи є причина, що сьогоднішні системи не зможуть зробити це ще краще?
supercat

@supercat Ви маєте на увазі, що кожна версія бібліотеки буде доступна в системі? Не впевнений, що розумію питання. Питання про ОП було спрямовано більше на загальносистемні бібліотеки, а не на статичні бібліотеки, які будуть упаковані разом.
багато чіпсів

Моя думка полягала в тому, що наявність виконавчого пакету включає всі необхідні йому бібліотеки не повинно виключати можливості оновлення бібліотек, що містяться в ньому. Таким чином, я не знаю, що розглядаю можливість модернізації речей після розгортання як перевагу не зв'язати додаток із його бібліотеками.
supercat

Якщо ліцензія даної бібліотеки дозволяє вам поширювати її разом із вашим пакетом, то це завжди кращий спосіб зробити це. Це зменшує кількість зовнішніх залежностей. Оскільки ви розповсюджуєте все, то механік оновлення або виправлення буде працювати аналогічно статичним або динамічним. Виправлення зазвичай засноване на двійкових дельтах. Не було б різниці.
багато чіпсів
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.