Qual è la fonte della mentalità "compilalo tu stesso" in Linux [chiuso]


11

Ho usato un po 'Linux al college e ho familiarità con i termini. Sviluppo regolarmente in linguaggi .NET, quindi non sono analfabeta per computer.

Detto questo, non posso davvero dire di aver capito la mentalità "compilalo da te" [CIY] che esiste nei circoli * nix. So che se ne andrà, ma di tanto in tanto lo sento ancora. Come sviluppatore, so che impostare compilatori e dipendenze necessarie è una seccatura, quindi sento che i flussi di lavoro di CIY hanno contribuito a rendere * nix molto meno accessibile.

Quali fattori sociali o tecnici hanno portato all'ascesa della mentalità CIY?


12
Lo senti in ambienti Linux o UNIX ? C'è un'enorme differenza.
terdon

2
Linux ha così tante distro diverse non è davvero una sorpresa. Ora che alcune distro stanno arrivando come front-runner ci sono versioni compilate, ma era una rete tale da non essere pratica.
Centimane,

8
E per la cronaca, "impostare compilatori e dipendenze necessarie" su un sistema Linux non è poi così difficile. Qualcuno potrebbe anche dire facile.
Deathgrip,

6
@Darren - È il contrario, al giorno d'oggi la maggior parte dei tarball OpenSource seguono uno standard che non esisteva anni fa. Scarica tarball, estrai tarball, cd nella directory, esegui ./configure <options>, quindi crea ed esegui l' installazione. Mi sono tagliato i denti 30 anni fa sui server AT&T 3B2 con AT&T SysV Unix e Gould iron con UTX. Le cose erano molto più difficili allora. Alcuni hanno avuto l'inizio del configureprocesso, la maggior parte è stata modificata manualmente makefile(s)per il proprio sistema.
Deathgrip,

1
@Deathgrip In effetti, hai mai provato a configurare un ambiente di sviluppo Windows per la programmazione di sistemi senza Visual Studio? Quasi impossibile te lo dico.
gatto

Risposte:


27

Molto semplicemente, per gran parte della storia di * nix, non c'era altra scelta. I programmi sono stati distribuiti come tarball di origine e l'unico modo che hai avuto di usarli è stato compilare dal sorgente. Quindi non è tanto una mentalità quanto un male necessario.

Detto questo, ci sono ottime ragioni per compilare le cose da soli poiché verranno quindi compilate appositamente per il tuo hardware, puoi scegliere quali opzioni abilitare o meno e puoi quindi finire con un eseguibile ottimizzato, proprio come piace a te . Questo, tuttavia, è ovviamente solo qualcosa che ha senso per gli utenti esperti e non per le persone che vogliono semplicemente una macchina funzionante su cui leggere le loro e-mail.

Ora, nel mondo Linux, le principali distribuzioni si sono allontanate da questo molti anni fa. Molto, molto raramente è necessario compilare qualcosa da soli in questi giorni a meno che non si stia utilizzando una distribuzione appositamente progettata per le persone a cui piace fare questo come Gentoo. Per la stragrande maggioranza delle distribuzioni, tuttavia, l'utente medio non dovrà mai compilare nulla poiché praticamente tutto ciò di cui avrà mai bisogno è presente e compilato nei repository della sua distribuzione.

Quindi questa mentalità CIY come la chiami è sostanzialmente scomparsa. Potrebbe essere ancora vivo e vegeto nel mondo UNIX, non ho esperienza lì, ma in Linux, se stai usando una distribuzione popolare con un repository decente, non avrai quasi mai bisogno di compilare nulla da solo.


5
Nel mondo Unix, differirà di nuovo a seconda del sistema operativo. La mia ultima posizione riguardava un gran numero di server Solaris (piattaforma Sun Sparc) e ho eseguito Solaris 10 x86 a casa come desktop per alcuni anni. Non posso parlare per HPUX o AIX, ma hai dovuto fare un po 'di CIY su Solaris. Sun ha distribuito una serie di utility OpenSource preconfezionate per Solaris. C'erano anche siti come opencsw.org e unixpackages.com. Ma ho ancora fatto un po 'di compilazione dai tarball di origine.
Deathgrip,

"per gran parte della storia di * nix, non c'era altra scelta. I programmi erano distribuiti come tarball sorgente." - ma è a causa della mentalità CIY, giusto?
Woodrow Barlow,

2
@woodrow non proprio. Non c'era altra scelta disponibile. Non dimenticare che * nix è vecchio . Inoltre, la maggior parte dei programmi sono stati scambiati tra colleghi che erano già esperti e perché dovresti preoccuparti di inventare qualcosa di così complesso come un installatore o un gestore di pacchetti per le altre 8 persone che userebbero il tuo codice? Quando sono stati inventati tali strumenti, la gente * nix ha iniziato a usarli come tutti gli altri.
terdon

@WoodrowBarlow No, stai scambiando causa ed effetto. I programmi sono stati distribuiti come sorgente perché c'erano molte piattaforme diverse (diverse architetture hardware, diversi sistemi operativi, diversi set di librerie), quindi un autore del programma avrebbe dovuto distribuire centinaia o migliaia di binari per coprirli tutti. CIY è ancora in circolazione per le persone che gestiscono piattaforme "esotiche", ma una grande maggioranza gestisce piattaforme "mainstream" in cui i binari sono prontamente disponibili dalle distribuzioni.
Gilles 'SO- smetti di essere malvagio' il

@terdon okay, capisco. Vorrei solo sottolineare, tuttavia, che il paragrafo è un po 'tautologico. a un certo livello, l'OP ha chiesto "perché gli sviluppatori * nix distribuiscono il codice sorgente anziché i binari compilati?" e il tuo primo paragrafo dice "perché gli sviluppatori * nix distribuiscono il codice sorgente invece dei binari compilati". sì, mi rendo conto che sto semplificando, ma penso che la tua risposta sarebbe più chiara se aggiungi gli argomenti del tuo commento nel testo della risposta.
Woodrow Barlow,

13

Ci sono alcune cause per quella mentalità, da parte di utenti finali, manutentori della distribuzione e fornitori di codice / sviluppatori / gruppi di progetti, e ognuno di essi è perfettamente valido.

L'aspetto Open Source

Ci sono alcuni a cui piace sapere che stanno usando il software libero e lo convalidano scegliendo di compilare dal sorgente. È qui che entrano in gioco cose come il progetto Linux From Scratch / howto / guide / book.

L'ottimizzazione e l'aspetto delle opzioni

Vuoi compilare elementi con ottimizzazioni specifiche per la tua particolare architettura della CPU? Forse esiste un'opzione di compilazione (o patch per crearne una) per abilitare o disabilitare una particolare funzione di cui hai bisogno. Esempi di questo potrebbero essere l'applicazione di patch postfix per la possibilità di gestire le quote o l'utilizzo di una distribuzione come Gentoo in cui è possibile scegliere di non utilizzare systemd, oppure si sceglie di supportare specificamente ogg / theora / vorbis / qualunque cosa e NON mp3 a causa di problemi di licenza o qualunque altra cosa.

L'aspetto architettura della CPU

Il tuo posto di lavoro utilizza macchine non x86 / amd64 di fascia alta? Il pacchetto di cui hai bisogno / desideri potrebbe non essere disponibile pre-compilato per l'architettura della tua CPU, tanto meno qualunque distribuzione tu stia eseguendo. Certo, la maggior parte dei luoghi che eseguono questo tipo di hardware sono anche supportati da IBM, ecc. E non vanno a installare / compilare cose volenti o nolenti. Ma cosa succede se ne prendi uno da una vendita in eccedenza, scavi un vecchio processore iMac con PPC, ecc.?

L'aspetto distribuzione

Le "famiglie" di distribuzione - ovvero Debian con Ubuntu, Mint, et al e RedHat con CentOS, Whitebox, Fedora, et al - usano tutti diversi formati di pacchetto. E ogni versione viene fornita con diverse versioni di libreria, ecc. Anche per un semplice script di shell a file singolo la configurazione di un corretto file .deb Debian richiede tempo e fatica. Se hai scritto del software per grattarti un po 'di prurito e volevi renderlo gratuito e pubblicarlo su gitlab, il tuo server web, qualunque cosa, preferiresti semplicemente pubblicare un file .tar.gz generico di origine con le istruzioni per la costruzione o preferiresti impacchettare versioni per 2 versioni di Debian (stable e testing, forse oldstable), versioni multiple di Redhat e Fedora come RPM, un TGZ per Slackware, un profilo ebuild per Gentoo, ecc. ecc. ecc. ecc.


1
Un altro motivo è che a volte l'origine upstream corregge un bug non critico per una funzionalità che ha funzionato in una versione precedente ma che da allora è stata interrotta. Tuttavia, il pacchetto per una distribuzione più stabile potrebbe non aggiornare il pacchetto per settimane o addirittura mesi. Questo è uno dei motivi per cui un utente normale potrebbe voler imparare a compilare alcune cose dal sorgente. Inoltre, anche le distro con una reputazione di software all'avanguardia nei loro repository come Arch, a un certo punto rimarranno indietro. Compilare dalla fonte significa che posso avere tutto ciò che hai menzionato, oltre a qualsiasi nuova funzionalità che potrebbe essere stata introdotta.

@ChronoKitsune Molto vero; confronta le versioni del pacchetto in Gentoo (una distro CIY) con qualsiasi altra distro. Molto più nuovo Fare istruzioni per la compilazione è mille volte più semplice che creare un pacchetto binario che funzionerà su ogni architettura. Ciò significa che puoi utilizzare nuove fantastiche funzionalità software che gli altri non vedranno per un po '.
dogoncouch,

9

Come dice @terdon, al giorno d'oggi la necessità di compilare le cose è piuttosto sottile, specialmente per gli utenti domestici.

In passato, nel mondo Unix, dipendevo fortemente dalle fonti di compilazione, ad esempio, poiché gestivo i sistemi Solaris, AIX, Ultrix, Digital Ultrix e HP / UX che a volte non erano più gestiti dal fornitore o quali implementazioni dei servizi comuni erano molto indietro rispetto a ciò che veniva comunemente usato da altri Unix, incluso Linux.

Esistono ancora vere esigenze per la compilazione di cose nel presente, sia per ottenere un pezzo di software più oscuro o obsoleto che non si trova nei repository, o utilizzare una versione più recente di un pacchetto per il quale non si hanno binari compatibili, o quando vuoi aggiungere funzionalità extra o raramente, se sei in grado di scrivere una patch o un modulo per esso.

Ho anche dovuto compilare manualmente il software quando riprogettavo i sistemi per il porting su Debian e / o nuove versioni di Debian che avevano un framework che non era più supportato dal sistema operativo.

Ad esempio, in passato ho dovuto compilare manualmente i demoni DHCP per avere il supporto (per allora recente) delle modifiche al protocollo di Windows o per supportare patch specifiche per il provisioning nel mondo Telecom.

Continuo a conservare nel mio repository locale i debs per le versioni di FreeRadius compilati da me dal repository dev git, dato che c'erano una serie di versioni stabili che presentavano bug (gravi) in Debian, e di solito i corrispondenti .debs per Debian / Ubuntu non sono stati adeguato alle nostre esigenze.

E va da sé che spesso di tanto in tanto dobbiamo anche eseguire / o compilare cose scritte da noi stessi.

L'installazione delle dipendenze al giorno d'oggi non è così difficile come in passato e alcuni software hanno persino file di regole personalizzati per alcune comuni distribuzioni Linux che nominano le dipendenze da compilare e svolgono il pesante lavoro di creazione del file del pacchetto con l'elenco delle dipendenze integrate. L'installazione di un tale pacchetto da un repository locale non è molto diversa dall'installazione dello stesso pacchetto dai repository ufficiali.


4

Quali fattori sociali o tecnici hanno portato all'ascesa della mentalità CIY?

La causa principale è ovviamente la ragione tecnica: la portabilità binaria è più difficile della portabilità della fonte . Al di fuori dei pacchetti di distribuzione, la maggior parte dei software gratuiti è ancora disponibile solo in formato sorgente perché è molto più conveniente per gli autori / manutentori.

Fino a quando le distribuzioni Linux non hanno iniziato a impacchettare la maggior parte delle cose che la gente media vorrebbe usare, l'unica opzione era quella di ottenere il sorgente e compilarlo per il proprio sistema. I venditori di Unix commerciali in genere non includevano roba che quasi tutti volevano (ad esempio una bella shell come GNU basho simile), solo la propria implementazione di she / o csh, quindi era necessario creare roba da soli se tu (come amministratore di sistema) volevi per fornire un piacevole ambiente Unix ai tuoi utenti per un uso interattivo.

La situazione ora, con la maggior parte delle persone che è l'unico amministratore e unico utente della macchina seduta sul desktop, è molto diversa dal tradizionale modello Unix. Un amministratore di sistema ha mantenuto il software sul sistema centrale e sul desktop di tutti. (Spesso avendo le workstation delle persone semplicemente montate su NFS /opte /usr/local/dal server centrale e installando roba lì.)


Prima di cose come .NET e Java, la vera portabilità binaria su diverse architetture CPU era impossibile. La cultura di Unix si è evoluta con la portabilità dei sorgenti come impostazione predefinita per questo motivo, con pochi sforzi anche per provare ad abilitare la portabilità binaria fino ai recenti sforzi di Linux come LSB. Ad esempio, POSIX ( il principale standard Unix) tenta solo di standardizzare la portabilità del codice sorgente, anche nelle versioni recenti.

Fattore culturale correlato: I primi AT&T commerciali Unix venivano forniti con il codice sorgente (sui nastri). Non hai hai per costruire il sistema dai sorgenti, è stato solo lì nel caso in cui si voleva vedere come qualcosa di veramente funzionato quando i documenti non erano sufficienti.

Wikipedia dice :

"La politica Unix di ampia documentazione online e (per molti anni) pronto accesso a tutto il codice sorgente del sistema ha sollevato le aspettative del programmatore e ha contribuito al lancio del 1983 del movimento di software libero".

Non sono sicuro di cosa abbia motivato questa decisione, dal momento che dare ai clienti l'accesso al codice sorgente del software commerciale è inaudito in questi giorni. Esistono chiaramente alcuni preconcetti culturali in questa direzione, ma forse ciò è nato dalle radici di Unix come sistema operativo portatile scritto principalmente in C (non linguaggio assembly) che poteva essere compilato per hardware diverso. Penso che molti sistemi operativi precedenti avessero scritto più codice per una CPU specifica, quindi la portabilità a livello di sorgente era uno dei punti di forza di Unix. (Potrei sbagliarmi su questo; non sono un esperto dei primi Unix, ma Unix e C sono correlati.)


La distribuzione di software in formato sorgente è di gran lunga il modo più semplice per consentire alle persone di adattarlo al sistema su cui vogliono che funzioni. (Utenti finali o persone che lo confezionano per una distribuzione Linux). Se il software è già stato impacchettato da / per una distribuzione, gli utenti finali possono semplicemente utilizzarlo.

Ma è troppo aspettarsi che gli autori della maggior parte dei pacchetti facciano binari per ogni possibile sistema. Alcuni importanti progetti forniscono file binari per alcuni casi comuni (in particolare x86 / windows in cui il sistema operativo non viene fornito con un ambiente di compilazione e il fornitore del sistema operativo ha posto l'accento sulla distribuzione di programmi di installazione solo binari).

Far funzionare un software su un sistema diverso da quello utilizzato dall'autore potrebbe anche richiedere alcune piccole modifiche, che sono facili con l'origine . Un piccolo programma unico che qualcuno ha scritto per grattarsi il prurito probabilmente non è mai stato testato sulla maggior parte dei sistemi oscuri. Avere la fonte rende possibile apportare tali modifiche. L'autore originale potrebbe aver trascurato qualcosa o intenzionalmente scritto meno codice portatile perché ha risparmiato molto tempo. Anche i principali pacchetti come Info-ZIP non avevano subito tester su ogni piattaforma e avevano bisogno che le persone inviassero le loro patch di portabilità quando i problemi venivano scoperti.

(Ci sono altri tipi di problemi di portabilità a livello di sorgente che solo accadere a causa di differenze nella costruzione env, e non sono davvero rilevanti per il problema qui. Con stile Java portabilità binario, auto-strumenti ( autoconf/ auto-make) e cose simili come cmakewouldn sarebbe necessario. E non avremmo cose come alcuni sistemi richiedono l'inclusione <netinet/in.h>invece di<arpa/inet.h> perntohl(3) . (E forse non avremmo ntohl()o qualsiasi altra roba di ordine byte in primo luogo!)


Sviluppo regolarmente in linguaggi .NET, quindi non sono analfabeta per computer.

Compilare una volta, correre ovunque è uno degli obiettivi principali di .NET e anche di Java, quindi è giusto dire che interi linguaggi sono stati inventati nel tentativo di risolvere questo problema e la tua esperienza di sviluppo è con uno di essi. Con .NET, il tuo binario viene eseguito su un ambiente di runtime portatile (CLR) . Java chiama il suo ambiente di runtime Java Virtual Machine . Devi solo distribuire un binario che funzionerà su qualsiasi sistema (almeno, qualsiasi sistema in cui qualcuno ha già implementato una JVM o CLR). Puoi ancora avere problemi di portabilità come, /vs \separatori di percorso, o come stampare, o dettagli del layout della GUI, ovviamente.

Un sacco di software è scritto in lingue che sono completamente compilate in codice nativo . Non esiste un .netbytecode o java, solo un codice macchina nativo per la CPU su cui verrà eseguito, memorizzato in un formato di file eseguibile non portatile. C e C ++ ne sono il principale esempio, specialmente nel mondo Unix. Ovviamente questo significa che un binario deve essere compilato per una specifica architettura della CPU.

Le versioni della libreria sono un altro problema . Le librerie possono e spesso mantengono stabile l'API a livello di sorgente durante la modifica dell'ABI a livello binario. (Vedi Differenza tra API e ABI .) Ad esempio, l'aggiunta di un altro membro a un opaco structmodifica comunque le sue dimensioni e richiede una ricompilazione con le intestazioni per la nuova versione della libreria per qualsiasi codice che alloca spazio per tale struttura, sia esso dinamico (malloc ), statico (globale) o automatico (locale nello stack).

Anche i sistemi operativi sono importanti . Un sapore diverso di Unix per la stessa architettura CPU può avere diversi formati di file binari, un ABI differente per le chiamate di sistema e differenti valori numerici per le costanti come fopen(3)'s O_RDONLY, O_APPEND,O_TRUNC .

Si noti che anche un binario collegato dinamicamente ha ancora un codice di avvio specifico del sistema operativo che viene eseguito in precedenza main(). Su Windows, questo è crt0. Unix e Linux hanno la stessa cosa, in cui un po 'di codice C-Runtime Startup è staticamente collegato in ogni binario. Immagino che in teoria potresti progettare un sistema in cui anche quel codice era collegato dinamicamente e parte di libc o del linker stesso, ma non è così che funzionano in pratica su qualsiasi sistema operativo di cui sono a conoscenza. Ciò risolverebbe solo il problema ABI delle chiamate di sistema, non il problema dei valori numerici per le costanti per le funzioni di libreria standard. (Normalmente le chiamate di sistema vengono fatte tramite le funzioni wrapper libc: un normale binario Linux x86-64 per il sorgente che usa mmap()non includerà l' syscallistruzione, solo uncall istruzioni per la funzione wrapper libc con lo stesso nome.

Questo è uno dei motivi per cui non puoi semplicemente eseguire i binari i386-FreeBSD su i386-Linux. (Per un po ', il kernel Linux ha avuto un livello di compatibilità delle chiamate di sistema. Penso che almeno uno dei BSD possa eseguire binari Linux, con un livello di compatibilità simile, ma ovviamente sono necessarie librerie Linux.)


Se si desidera distribuire i binari, è necessario crearne uno separato per ogni combinazione di CPU / sistema operativo + versione / versione installata-libreria-versioni .

Negli anni '80 / '90, c'erano molti diversi tipi di CPU di uso comune per i sistemi Unix (MIPS, SPARC, POWER, PA-RISC, m68k, ecc.) E molti tipi diversi di Unix (IRIX, SunOS, Solaris, AIX, HP-UX, BSD, ecc.).
E questo è solo un sistema Unix . Molti pacchetti sorgente compilerebbero e funzionerebbero anche su altri sistemi, come VAX / VMS, MacOS (m68k e PPC), Amiga, PC / MS-DOS, Atari ST, ecc.

Esistono ancora molte architetture e sistemi operativi della CPU, sebbene ora gran parte dei desktop sia x86 con uno dei tre sistemi operativi principali.

Quindi ci sono già più combinazioni CPU / OS di quelle a cui puoi agitare, anche prima di iniziare a pensare alle dipendenze da librerie di terze parti che potrebbero trovarsi in versioni diverse su sistemi diversi. (Tutto ciò che non è confezionato dal fornitore del sistema operativo dovrebbe essere installato a mano.)

Anche i percorsi compilati nel file binario sono specifici del sistema. (Ciò consente di risparmiare RAM e tempo rispetto alla lettura da un file di configurazione all'avvio). I sistemi Unix della vecchia scuola avevano in genere un sacco di cose personalizzate a mano, quindi non c'è modo di fare ipotesi valide su cosa sia dove.

La distribuzione di file binari era totalmente impossibile per Unix di vecchia scuola, tranne per i grandi progetti commerciali che possono permettersi di costruire e testare su tutte le principali combinazioni .

Anche fare binari per giusto i386-linux-gnued amd64-linux-gnuè difficile. Molto tempo e sforzi sono stati spesi in cose come Linux Standard Base per rendere possibili i binari portatili . Anche il collegamento statico dei binari non risolve tutto. (es. come dovrebbe stampare un programma di elaborazione testi su un sistema RedHat rispetto a un sistema Debian? In che modo l'installazione dovrebbe aggiungere un utente o un gruppo per un demone e organizzare l'esecuzione dello script di avvio dopo ogni riavvio?) esempi, perché la ricompilazione dalla fonte non li risolve.


Oltre a tutto ciò, ai giorni nostri la memoria era più preziosa di quanto non sia ora. Tralasciando le funzionalità opzionali in fase di compilazione è possibile creare file binari più piccoli (meno dimensioni del codice) che utilizzano anche meno memoria per le loro strutture di dati. Se una funzione richiede un membro aggiuntivo in ogni istanza di un determinato classo structper tracciare qualcosa, la disabilitazione di tale funzione ridurrà l'oggetto di 4 byte (ad esempio), il che è utile se si tratta di un oggetto di cui il programma alloca 100k.

Oggigiorno, le funzioni opzionali di compilazione vengono spesso utilizzate per rendere opzionali librerie extra. ad esempio, è possibile compilare ffmpegcon o senza libx264, libx265, libvorbis, e molte altre librerie per specifiche video / encoder audio, la gestione dei sottotitoli, ecc ecc Più comunemente, un sacco di cose possono essere compilati con o senza libreadline: se è disponibile quando si esegue ./configure, il il binario risultante dipenderà dalla libreria e fornirà un editing di riga di fantasia durante la lettura da un terminale. In caso contrario, il programma utilizzerà un supporto di fallback per leggere le righe dallo stdin con fgets()o qualcosa del genere.)

Alcuni progetti utilizzano ancora funzionalità opzionali per tralasciare il codice non necessario per motivi di prestazioni. ad es. il kernel Linux stesso può essere compilato senza il supporto SMP (ad es. per un sistema incorporato o un desktop antico), nel qual caso gran parte del blocco è più semplice. O con molte altre funzionalità opzionali che influiscono su alcuni dei codici core, non solo tralasciando i driver o altre funzionalità hardware. (Sebbene le opzioni di configurazione specifiche dell'arco e dell'hardware rappresentino gran parte del codice sorgente totale. Vedi Perché il kernel Linux ha oltre 15 milioni di righe di codice? )

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.