Le biblioteche statiche C sono disapprovate? [chiuso]


11

Esistono 2 argomenti per avere librerie condivise:

  1. Aiuta a ridurre lo spazio su disco.
  2. Quando una libreria condivisa viene aggiornata, tutti i file binari che dipendono da essa ottengono l'aggiornamento.

C'è principalmente uno svantaggio per le librerie condivise:

  • Possono (possono) introdurre l'inferno della dipendenza.

Sui computer desktop, il primo vantaggio non è più valido. Lo spreco di spazio su disco non è un grosso problema in questi giorni.

Avere binari statici ci permetterebbe di ottenere gestori di pacchetti migliori - voglio dire, l'inferno delle dipendenze sarebbe un ricordo del passato. Aggiungere un programma significherebbe semplicemente aggiungere un binario; alla fine una cartella per permettergli di gestire i suoi file. L'eliminazione di un programma significherebbe semplicemente eliminare questo file. Dipendenze? Andato.

Il secondo vantaggio è ancora valido, ma penso che il vantaggio dei binari statici sui computer desktop sia superiore. Voglio dire, anche i nuovi linguaggi come Go compilano tutti i loro binari nonostante i vantaggi delle librerie condivise, per la comodità.


Dato che uno dei principali vantaggi delle librerie condivise non è più un grosso problema, le librerie statiche C sono ancora disapprovate? Se è così, perché?


4
La ragione principale per cui C è più utilizzato è proprio perché si sta non lavorando su un moderno computer desktop.
Telastyn,

18
@Telastyn mi dispiace? La maggior parte del software installato sui miei computer desktop è scritto in C.
Florian Margaine il

6
Side bit - un sito off letto sull'argomento - Collegamento dinamico considerato

6
Un vantaggio delle librerie dinamiche è che le persone possono ancora aggiornare le librerie per aggirare bug, falle di sicurezza o problemi hardware nel gioco quindicinale di 15 anni che ha smesso da tempo di ricevere aggiornamenti. Una specie di caso di nicchia, ma dato che i buoni giochi non sono prodotti di base, "usa un altro programma" non è di grande aiuto. È inoltre importante rispettare la LGPL senza approvvigionamento aperto del proprio codice.
Doval,

4
Hai dimenticato altri due vantaggi delle librerie condivise: 1) sono condivise anche nella memoria, 2) tutti i linker fanno schifo male e collegare un enorme binario è molto spiacevole. Dividere un binario in diverse entità più piccole rende l'intero processo molto più tollerabile.
SK-logic,

Risposte:


9

La premessa della tua domanda è errata. Ciò che è disapprovato è attenersi ai dottrinari e agli assoluti senza alcuna comprensione delle basi che stanno dietro (Programmazione del Culto del Carico?).

La risposta SO collegata è uno studio interessante proprio in questo stesso argomento: la domanda riguardava il motivo per cui una compilazione con opzione statica non funzionava, la risposta a cui si era collegati non era altro che una curiosità sul non utilizzare il collegamento statico. Se non discute il motivo per cui è negativo e richiede che l'OP utilizzi il collegamento dinamico. È un peccato che sia contrassegnato come la risposta corretta (la risposta che segue ha il doppio dei voti ed è la risposta corretta alla domanda del PO) perché sebbene la risposta corretta sia lì, è profondamente nascosta in un'opinione dogmatica.

La vera domanda è quali sono i pro e i contro del collegamento statico vs dinamico e quando uno sarebbe preferito rispetto all'altro.


2
La risposta di Basile fa dirti esattamente perché egli consiglia di utilizzare le librerie condivise: ? "Perché si desidera collegare staticamente l'applicazione . In genere è un errore (perché non lo fai profitto da aggiornamenti delle librerie di sistema dinamici) In particolare interruttore di servizio nome strutture di libc vogliono librerie dinamiche. " Non è un" rant "solo perché non sei d'accordo con esso.
Cody Grey,

@Cody La risposta collegata è stata modificata da quando l'ho definita un rant. L'unica opinione che tengo sul collegamento statico vs dinamico è quella di utilizzare quella appropriata per le tue esigenze e comprendere i punti di forza e di debolezza della scelta piuttosto che cadere nella dottrina della programmazione del culto del carico perché "qualcuno l'ha detto".
Mattnz,

Sì, è stata aggiunta la parte "In particolare ...". Non sono sicuro di come ciò influisca sul suo stato rant. Ovviamente non sto sostenendo la programmazione di culto del carico. È solo che i sostenitori del collegamento statico (nella mia esperienza) spesso mancano o sottovalutano i problemi di sicurezza. Il collegamento statico può essere molto appropriato per le utility una tantum, rendendo l'app indipendente e quindi la distribuzione molto più semplice. Ma qualsiasi app che sarà ampiamente distribuita o utilizzata per la produzione dovrebbe davvero collegarsi a una libreria condivisa. Non ci sono svantaggi reali: a questo livello di app, hai già bisogno di un processo di distribuzione.
Cody Grey,

1
Un buon esempio di dove è appropriato il collegamento statico è dove lavoro - sistemi complessi, grandi e complessi. Una volta che un modulo critico è stato testato e approvato per il funzionamento, il suo comportamento non deve cambiare senza passare attraverso "il processo". Tuttavia, nessuna parte operativa e non vitale del sistema (fatturazione e reportistica) necessita di un controllo meno efficace e utilizza un collegamento dinamico.
Mattnz,

7

Dal punto di vista dello sviluppatore, il collegamento dinamico può spesso velocizzare notevolmente il ciclo di compilazione / collegamento / test.

Dal punto di vista della gestione dei pacchetti, ad esempio libGL. Ho circa una dozzina di diverse implementazioni disponibili nel mio gestore di pacchetti, alcune generiche e alcune specifiche per schede grafiche specifiche. Se non fosse collegato dinamicamente, ci dovrebbero essere una dozzina di versioni di ciascun programma che si collega a libGL, altrimenti dovresti escogitare un ulteriore livello di astrazione che non è efficiente come una chiamata di funzione.

Pensa a un problema di sicurezza in una libreria popolare come Qt. Con il collegamento dinamico, posso semplicemente aggiornare quel pacchetto, invece di dover identificare, ricompilare e distribuire ogni singolo pacchetto che collega in Qt.

Il collegamento statico può presentare vantaggi in applicazioni chiuse distribuite in modo indipendente, ma nella gestione dei pacchetti open source fa più male di quanto aiuti.


2
Questo è vero (accelerare lo sviluppo), ma è davvero frustrante che lo faccia entrare in produzione. L'esempio canonico è Firefox. La quantità di sforzi ingegneristici (sotto forma di orribili hack) che hanno accelerato la risoluzione dei simboli di collegamento dinamico in modo che Firefox si carichi in tempi ragionevoli è assolutamente folle. Prestazioni molto migliori avrebbero potuto essere ottenute con costi di progettazione molto inferiori se fossero solo disposti a collegare staticamente tutto il loro codice in-project (mentre, se lo si desidera, ancora collegando dinamicamente librerie e plugin di sistema).
R .. GitHub FERMA AIUTANDO ICE il

5

Le librerie condivise sono fortemente preferite dai manutentori della distribuzione Linux per il tuo motivo n. 2. È davvero importante per loro che, ad esempio, quando qualcuno trova un bug di sicurezza in zlib , non devono ricompilare tutti i programmi che usano zlib, non solo costerebbe loro più cicli della CPU per fare il ricompilando, tutti coloro che usano la distro dovrebbero quindi scaricare nuovamente tutti quei programmi. Nel frattempo, all'interno del set di pacchetti fornito da una distribuzione, l'inferno delle dipendenze non è un problema, perché tutto è testato per funzionare con quel set di librerie.

Se stai sviluppando software di terze parti che necessita di librerie che non sono presenti nella tua distribuzione, il collegamento statico di tali librerie potrebbe essere meno problematico dell'alternativa, e va bene.

L'altra cosa importante da sapere è che GNU libce GCC libstdc++hanno entrambi componenti che non funzionano in modo affidabile se la libreria è staticamente collegata. Il problema più comune è con dlopen, perché qualsiasi modulo che carichi dlopenè esso stesso collegato dinamicamentelibc.so.6 . Ciò significa che ora hai due copie della libreria C nel tuo spazio degli indirizzi e ne deriva il divertimento quando non sono d'accordo su quale copia della mallocstruttura di dati interna (ad esempio) è autorevole. Peggio ancora: un sacco di funzioni che non sembrano avere nulla a che fare con dlopen, come gethostbynamee iconv, usaredlopeninternamente (in modo che il loro comportamento sia configurabile in runtime). Fortunatamente, l'ABI per libc e libstdc ++ è molto stabile, quindi è improbabile che tu abbia problemi a collegarli dinamicamente.


2

Sono d'accordo con l'ultimo punto di Mattnz: questa domanda è una domanda carica. Presuppone che il collegamento statico sia errato. Posso pensare a due motivi per cui questo non è il caso:

  • Il collegamento statico è sicuro: se una libreria condivisa viene aggiornata in modo tale che un'applicazione utilizzi quella nuova (forse la nuova sovrascrive la vecchia o la vecchia viene rimossa), può presentare il rischio che la nuova versione rompa l'applicazione. Si tratta di una modifica del codice al di fuori dell'ambito di un aggiornamento ufficiale per l'applicazione. Potrebbe non essere stato testato. Il collegamento statico lo elude non condividendo le librerie esternamente. Ritengo che questo sia uno svantaggio delle librerie condivise a causa di questo rischio. Cosa succede se una nuova versione di una libreria condivisa introduce un nuovo bug che rompe alcune applicazioni meno recenti?

  • Il collegamento statico assicura che un'applicazione sia più autonoma. Mentre le librerie condivise possono essere associate al file eseguibile principale, spesso vengono depositate in posizioni condivise. Le applicazioni collegate staticamente sono più facili da garantire "portatili" nel senso di "non richiedere modifiche a file, directory o impostazioni di proprietà del sistema operativo" (si pensi alla directory di Windows, al registro, ecc.).


Grazie per aver migliorato i vantaggi che intendevo menzionare. Tuttavia, se vedi la maggior parte dei pacchetti forniti dalle distribuzioni Linux, ad esempio, non sono compilati staticamente. Si fa sembrare che compilazione statica è malvista, almeno dal punto di vista esterno.
Florian Margaine,

1
Le librerie dinamiche su quasi tutti i sistemi operativi in ​​circolazione in questi giorni sono pagate dalla domanda. Solo le pagine effettivamente utilizzate sono in memoria. Se più applicazioni utilizzano la stessa funzionalità, condivideranno la memoria e utilizzeranno meno del caso della libreria statica. Se più app utilizzano funzionalità diverse nella stessa libreria, entrambi i set di funzionalità verranno sottoposti a paging, con approssimativamente lo stesso impatto dell'approccio statico.
Alan Shutko,

@AlanShutko Ho faticato e digitato di nuovo quella parte in diversi modi a causa di ciò che hai menzionato. Non ci sono garanzie reali in entrambi i casi, anche se in pratica i moderni sistemi operativi offrono l'efficienza delle librerie condivise con il sovraccarico di elettricità statica. Modificherò di nuovo.

@Snowman Penso che il punto di base sia che su qualsiasi sistema operativo realistico che fornisce collegamenti dinamici (non conosco alcun sistema operativo che utilizza collegamenti dinamici ma non richiede il paging) il tuo secondo punto non trattiene l'acqua: la memoria non viene effettivamente utilizzata a meno che non venga utilizzata la funzione e che la memoria utilizzata da una libreria dinamica possa essere condivisa tra diversi programmi che la utilizzano, rendendo l'utilizzo della memoria per la versione dinamica più efficiente anziché inferiore. Il tuo primo e terzo motivo sono validi, ma eliminerei semplicemente il secondo: con qualsiasi ipotesi realistica, è semplicemente sbagliato.
Jules,

@Jules Sono d'accordo, è un punto problematico e di dubbia validità nei moderni sistemi operativi. L'ho rimosso.

1

Le librerie statiche e dinamiche hanno ciascuna i propri usi. Guardando una singola applicazione nell'ambito abbiamo un'idea diversa di ciò che è necessario e cosa non lo è.

Il collegamento statico semplifica drasticamente la distribuzione delle applicazioni. Non dover rilevare e gestire versioni diverse. Basta cuocere e distribuire.

L'ovvio vantaggio con le librerie dinamiche è la possibilità di applicare gli aggiornamenti in modo indipendente.

Questo è uno dei motivi per cui detesto Maven e altri simili costruttori di progetti di collegamento dinamico simili per Java. Si aspettano che una singola versione della libreria sia disponibile in un determinato url per sempre. Non capire il problema che si verifica in 10 anni in cui nessuno può compilare l'applicazione perché tutte le fonti e i vasetti sono spariti.


C'è qualche motivo particolare per cui non dovrebbe essere possibile per i programmi che usano FooLib1.8essere in grado di includere il codice per quella libreria nel loro pacchetto eseguibile in modo standard, in modo da consentire a un'utilità di aggiornamento fornita con FooLib1.9l'aggiornamento o il downgrade? Il modo in cui il codice è stato archiviato nel Macintosh classico lo avrebbe reso abbastanza semplice; c'è qualche ragione per cui i sistemi di oggi non dovrebbero essere in grado di farlo ancora meglio?
supercat

@supercat intendi che ogni versione di una determinata libreria sarebbe disponibile sul sistema? Non sono sicuro di aver capito la domanda. La domanda di OP era più rivolta alle librerie condivise a livello di sistema rispetto alle librerie statiche che sarebbero state raggruppate insieme.
molte patatine il

Il mio punto era che avere un pacchetto eseguibile include tutte le librerie di cui ha bisogno non dovrebbe precludere la possibilità di aggiornare le librerie in esso contenute. Pertanto, non so che considererei la possibilità di aggiornare le cose dopo la distribuzione come un vantaggio di non raggruppare un'applicazione con le sue librerie.
supercat

Se la licenza di una determinata libreria ti consente di distribuirla con il tuo pacchetto, questo è sempre il modo preferito per farlo. Riduce il numero di dipendenze esterne. Dal momento che distribuiresti tutto, un meccanico di aggiornamento o patch funzionerebbe allo stesso modo con statico o dinamico. Patch di solito basato su delta binari. Non ci sarebbe differenza.
molte patatine il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.