Ich habe im College ein bisschen Linux benutzt und bin mit den Begriffen vertraut. Ich entwickle mich regelmäßig in .NET-Sprachen, bin also kein Computer-Analphabet.
Trotzdem kann ich nicht wirklich sagen, dass ich die Mentalität "Compile it yourself" [CIY] verstehe, die in * nix-Kreisen existiert. Ich weiß, dass es weggeht, aber ich höre es immer noch von Zeit zu Zeit. Als Entwickler weiß ich, dass das Einrichten von Compilern und erforderlichen Abhängigkeiten ein Problem darstellt. Ich bin daher der Meinung, dass CIY-Workflows dazu beigetragen haben, * nix viel weniger zugänglich zu machen.
Welche sozialen oder technischen Faktoren haben zum Aufstieg der CIY-Mentalität geführt?
./configure <options>
, installieren Sie es und lassen Sie es installieren. Ich habe mir vor 30 Jahren auf AT & T 3B2-Servern mit AT & T SysV Unix und Gould Iron UTX die Zähne geschnitten. Damals war es viel schwieriger. Einige hatten die Anfänge desconfigure
Prozesses, die meisten mussten Sie manuellmakefile(s)
für Ihr bestimmtes System bearbeiten .Antworten:
Ganz einfach, für einen Großteil der Geschichte von * nix gab es keine andere Wahl. Programme wurden als Quell-Tarballs verteilt, und Sie konnten sie nur verwenden, indem Sie sie aus dem Quellcode kompilierten. Es ist also weniger eine Mentalität als ein notwendiges Übel.
Trotzdem gibt es sehr gute Gründe, Dinge selbst zu kompilieren, da sie dann speziell für Ihre Hardware kompiliert werden. Sie können wählen, welche Optionen aktiviert werden sollen oder nicht, und Sie können daher eine genau abgestimmte ausführbare Datei erhalten, genau so, wie Sie es möchten . Dies ist jedoch offensichtlich nur für erfahrene Benutzer sinnvoll und nicht für Personen, die nur möchten, dass eine funktionierende Maschine ihre E-Mails liest.
In der Linux-Welt haben sich die Hauptdistributionen vor vielen Jahren alle davon entfernt. Sie müssen heutzutage sehr, sehr selten selbst etwas kompilieren, es sei denn, Sie verwenden eine Distribution, die speziell für Leute entwickelt wurde, die dies gerne tun, wie Gentoo. Für die überwiegende Mehrheit der Distributionen muss Ihr durchschnittlicher Benutzer jedoch nie etwas kompilieren, da so ziemlich alles, was er jemals benötigt, in den Repositorys seiner Distribution vorhanden und kompiliert ist.
Diese CIY-Mentalität, wie Sie sie nennen, ist also im Wesentlichen verschwunden. Es mag in der UNIX-Welt noch am Leben sein, ich habe dort keine Erfahrung, aber wenn Sie unter Linux eine beliebte Distribution mit einem anständigen Repository verwenden, müssen Sie fast nie selbst etwas kompilieren.
quelle
Es gibt einige Gründe für diese Mentalität, von Endbenutzern, Distributionsbetreuern und Codelieferanten / Entwicklern / Projektgruppen, und jeder einzelne von ihnen ist vollkommen gültig.
Der Open Source-Aspekt
Es gibt einige, die gerne wissen, dass sie freie Software verwenden, und dies überprüfen, indem sie sich dafür entscheiden, aus dem Quellcode zu kompilieren. Hier kommen Dinge wie das Linux From Scratch-Projekt / Howto / Guide / Book ins Spiel.
Der Optimierungs- und Optionsaspekt
Möchten Sie Inhalte mit spezifischen Optimierungen für Ihre spezielle CPU-Architektur kompilieren? Möglicherweise gibt es eine Option zur Kompilierungszeit (oder einen Patch zum Erstellen einer Option), um eine bestimmte Funktion zu aktivieren oder zu deaktivieren, die Sie benötigen. Beispiele hierfür sind das Patchen von Postfix, um Kontingente verwalten zu können, oder die Verwendung einer Distribution wie Gentoo, bei der Sie sich dafür entscheiden können, systemd nicht zu verwenden, oder Sie entscheiden sich aufgrund von Lizenzproblemen speziell für die Unterstützung von ogg / theora / vorbis / Whatever und NICHT mp3 oder Wasauchimmer.
Der Aspekt der CPU-Architektur
Verwendet Ihr Arbeitsplatz High-End-Computer, die nicht von x86 / amd64 stammen? Das Paket, das Sie benötigen / möchten, ist möglicherweise nicht vorkompiliert für Ihre CPU-Architektur verfügbar, geschweige denn für die von Ihnen ausgeführte Distribution. Zugegeben, die meisten Orte, an denen diese Art von Hardware ausgeführt wird, werden auch von IBM usw. unterstützt und werden nicht ohne weiteres installiert / kompiliert. Aber was ist, wenn Sie einen von einem Überschussverkauf abholen, einen alten iMac mit PPC-Prozessor usw. ausgraben?
Der Verteilungsaspekt
Distributions- "Familien" - dh Debian mit Ubuntu, Mint et al. Und RedHat mit CentOS, Whitebox, Fedora ua - verwenden alle unterschiedliche Paketformate. Und jede Version wird mit unterschiedlichen Bibliotheksversionen usw. ausgeliefert. Selbst für ein einfaches Shell-Skript für eine einzelne Datei erfordert das Einrichten einer richtigen Debian-DEB-Datei Zeit und Mühe. Wenn Sie eine Software geschrieben haben, um etwas Juckreiz zu beseitigen, und sie kostenlos machen und auf gitlab, Ihrem eigenen Webserver, veröffentlichen möchten, würden Sie lieber einfach eine generische .tar.gz-Quelldatei mit Anweisungen zum Erstellen veröffentlichen oder möchten Packen Sie Versionen für 2 Versionen von Debian (stabil und testend, möglicherweise oldstable), mehrere Versionen von Redhat und Fedora als RPMs, ein TGZ für Slackware, ein Ebuild-Profil für Gentoo usw. usw. usw. zusammen.
quelle
Wie @terdon sagt, ist die Notwendigkeit, Dinge zu kompilieren, heutzutage ziemlich gering, insbesondere für Heimanwender.
In der Vergangenheit war ich in der Unix-Welt stark vom Kompilieren von Quellen abhängig, beispielsweise als ich Solaris-, AIX-, Ultrix-, Digital Ultrix- und HP / UX-Systeme verwaltete, die manchmal nicht mehr vom Hersteller gewartet wurden oder welche Implementierungen der allgemeinen Dienste lagen weit hinter dem zurück, was von anderen Unixen, einschließlich Linux, häufig verwendet wurde.
In der Gegenwart besteht nach wie vor ein echtes Bedürfnis nach Kompilierung, entweder um eine obskurere oder veraltete Software zu erhalten, die sich nicht in den Repositorys befindet, oder um eine neuere Version eines Pakets zu verwenden, für das Sie keine kompatiblen Binärdateien haben, oder wann Sie möchten zusätzliche Funktionen hinzufügen oder selten, wenn Sie einen Patch oder ein Modul dafür schreiben können.
Ich musste auch Software von Hand kompilieren, wenn ich Systeme für die Portierung auf Debian und / oder neue Versionen von Debian neu entwickelte, die ein Framework hatten, das vom Betriebssystem nicht mehr unterstützt wurde.
In der Vergangenheit musste ich beispielsweise DHCP-Dämonen von Hand kompilieren, um (bis dahin) Windows-Änderungen am Protokoll zu unterstützen oder um bestimmte Patches für die Bereitstellung in der Telekommunikationswelt zu unterstützen.
Ich behalte immer noch in meinem lokalen Repository Debs für FreeRadius-Versionen, die ich aus dem Dev Git Repo zusammengestellt habe, da es eine Reihe stabiler Versionen gab, die (schwerwiegende) Fehler in Debian hatten, und normalerweise waren die entsprechenden .debs für Debian / Ubuntu nicht vorhanden angemessen für unsere Bedürfnisse.
Und es versteht sich von selbst, dass wir oft auch von uns selbst geschriebene Dinge ausführen oder kompilieren müssen.
Die Installation der Abhängigkeiten ist heutzutage nicht mehr so schwierig wie in der Vergangenheit, und einige Softwareprogramme haben sogar angepasste Regeldateien für einige gängige Linux-Distributionen, in denen die zu kompilierenden Abhängigkeiten benannt sind, und erledigen die umfangreiche Arbeit beim Erstellen der Paketdatei mit der Liste der integrierten Abhängigkeiten. Die Installation eines solchen Pakets aus einem lokalen Repository unterscheidet sich nicht wesentlich von der Installation desselben Pakets aus den offiziellen Repositorys.
quelle
Die Hauptursache ist ganz offensichtlich der technische Grund: Die Binärportabilität ist schwieriger als die Quellportabilität . Außerhalb von Distributionspaketen ist die meiste freie Software immer noch nur in Quellform verfügbar, da dies für den Autor / die Betreuer wesentlich bequemer ist.
Bis Linux-Distributionen anfingen, die meisten Dinge zu verpacken, die Durchschnittsbürger verwenden möchten, bestand Ihre einzige Option darin, die Quelle abzurufen und für Ihr eigenes System zu kompilieren. Kommerzielle Unix-Anbieter enthielten normalerweise keine Inhalte, die fast jeder wollte (z. B. eine nette Shell wie GNU
bash
oder ähnliches), sondern nur ihre eigene Implementierung vonsh
und / odercsh
. Sie mussten also selbst Inhalte erstellen, wenn Sie (als Systemadministrator) dies wollten um Ihren Benutzern eine schöne Unix-Umgebung für die interaktive Verwendung bereitzustellen.Die Situation, in der die meisten Benutzer der einzige Administrator und einzige Benutzer des Computers sind, der auf ihrem Desktop sitzt, unterscheidet sich erheblich vom traditionellen Unix-Modell. Ein Systemadministrator hat die Software auf dem zentralen System und auf jedem Desktop verwaltet. (Oft, indem die Workstations der Leute nur über NFS
/opt
und/usr/local/
vom zentralen Server bereitgestellt werden und dort Dinge installiert werden.)Vor Dingen wie .NET und Java war eine echte Binärportabilität über verschiedene CPU-Architekturen hinweg unmöglich. Die Unix-Kultur hat sich aus diesem Grund mit der Quellportabilität als Standard entwickelt, wobei nur wenig Aufwand erforderlich war, um die Binärportabilität bis zu den jüngsten Linux-Bemühungen wie LSB zu aktivieren. Beispielsweise versucht POSIX ( der wichtigste Unix-Standard) nur, die Quellportabilität zu standardisieren, selbst in neueren Versionen.
Verwandter kultureller Faktor: Frühe kommerzielle AT & T Unix kam mit Quellcode (auf Bändern). Sie haben es nicht haben , um das System aus dem Quellcode zu bauen, war es dort nur, wenn Sie sehen wollte , wie etwas wirklich funktioniert , wenn die Dokumente nicht genug waren.
Ich bin mir nicht sicher, was diese Entscheidung motiviert hat, da es heutzutage unerhört ist, Kunden Zugriff auf den Quellcode kommerzieller Software zu gewähren. Es gibt eindeutig einige frühe kulturelle Vorurteile in diese Richtung, aber vielleicht ist dies auf Unix 'Wurzeln als tragbares Betriebssystem zurückzuführen, das hauptsächlich in C (nicht in Assemblersprache) geschrieben ist und für verschiedene Hardware kompiliert werden kann. Ich denke, viele frühere Betriebssysteme hatten mehr Code in asm für eine bestimmte CPU geschrieben, daher war die Portabilität auf Quellenebene eine der Stärken von Unix. (Ich kann mich irren; ich bin kein Experte für frühes Unix, aber Unix und C sind verwandt.)
Die Verteilung von Software in Quellform ist bei weitem die einfachste Möglichkeit, sie an das System anzupassen, auf dem sie ausgeführt werden soll. (Entweder Endbenutzer oder Leute, die es für eine Linux-Distribution verpacken). Wenn Software bereits von / für eine Distribution gepackt wurde, können Endbenutzer diese einfach verwenden.
Es ist jedoch viel zu viel zu erwarten, dass Autoren der meisten Pakete Binärdateien für jedes mögliche System selbst erstellen. Einige große Projekte bieten Binärdateien für einige häufige Fälle (insbesondere x86 / Windows, in denen das Betriebssystem nicht über eine Build-Umgebung verfügt und der Betriebssystemhersteller den Schwerpunkt auf die Verteilung von Nur-Binär-Installationsprogrammen gelegt hat).
Um eine Software auf einem anderen System als dem vom Autor verwendeten auszuführen, sind möglicherweise sogar einige kleine Änderungen erforderlich, die mit der Quelle einfach sind . Ein kleines einmaliges Programm, das jemand geschrieben hat, um seinen eigenen Juckreiz zu kratzen, wurde wahrscheinlich noch nie auf den meisten obskuren Systemen getestet. Mit der Quelle können solche Änderungen vorgenommen werden. Der ursprüngliche Autor hat möglicherweise etwas übersehen oder absichtlich weniger portablen Code geschrieben, weil dies viel Zeit gespart hat. Selbst große Pakete wie Info-ZIP hatten nicht sofort Tester auf jeder Plattform und mussten ihre Portabilitäts-Patches einsenden, sobald Probleme entdeckt wurden.
(Es gibt andere Arten von Portabilitätsproblemen auf Quellenebene, die nur aufgrund von Unterschieden in der Build-Umgebung auftreten und für das Problem hier nicht wirklich relevant sind. Mit binärer Portabilität im Java-Stil, Auto-Tools (
autoconf
/auto-make
) und ähnlichen Dingen wiecmake
würde Es wird nicht benötigt. Und wir hätten keine Dinge wie einige Systeme, die die Einbeziehung von<netinet/in.h>
anstelle von<arpa/inet.h>
für erfordernntohl(3)
. (Und vielleicht hätten wir überhauptntohl()
keine andere Byte-Reihenfolge!)Einmal kompilieren, überall ausführen ist eines der Hauptziele von .NET und auch Java. Man kann also mit Recht sagen, dass ganze Sprachen erfunden wurden, um dieses Problem zu lösen , und Ihre Entwicklererfahrung ist mit einem von ihnen. Mit .NET wird Ihre Binärdatei in einer tragbaren Laufzeitumgebung (CLR) ausgeführt . Java nennt seine Laufzeitumgebung die Java Virtual Machine . Sie müssen nur eine Binärdatei verteilen, die auf jedem System funktioniert (zumindest auf jedem System, auf dem bereits jemand eine JVM oder CLR implementiert hat). Möglicherweise können weiterhin Portabilitätsprobleme auftreten, z. B. im
/
Vergleich zu\
Pfadtrennzeichen oder zum Drucken oder Details zum GUI-Layout.Viele Softwareprogramme sind in Sprachen geschrieben, die vollständig in nativen Code kompiliert sind . Es gibt keinen
.net
oder Java-Bytecode, nur nativen Maschinencode für die CPU, auf der er ausgeführt wird, gespeichert in einem nicht portierbaren ausführbaren Dateiformat. C und C ++ sind die wichtigsten Beispiele dafür, insbesondere in der Unix-Welt. Dies bedeutet natürlich, dass eine Binärdatei für eine bestimmte CPU-Architektur kompiliert werden muss.Bibliotheksversionen sind ein weiteres Problem . Bibliotheken können und werden häufig die API auf Quellenebene stabil halten, während der ABI auf Binärebene geändert wird. (Siehe Unterschied zwischen API und ABI .) Wenn Sie beispielsweise einem undurchsichtigen Element ein weiteres Mitglied hinzufügen,
struct
ändert sich seine Größe weiterhin und es muss für jeden Code, der Speicherplatz für eine solche Struktur reserviert, unabhängig davon, ob sie dynamisch ist (malloc), eine Neukompilierung mit Headern für die neue Bibliotheksversion durchgeführt werden ), statisch (global) oder automatisch (lokal auf dem Stapel).Betriebssysteme sind ebenfalls wichtig . Eine andere Unix - Variante für die gleiche CPU - Architektur könnten verschiedene binäre Dateiformate haben, eine andere ABI für die Herstellung von Systemaufrufen und unterschiedliche numerische Werte für Konstanten wie
fopen(3)
‚sO_RDONLY
,O_APPEND
,O_TRUNC
.Beachten Sie, dass selbst eine dynamisch verknüpfte Binärdatei noch einen betriebssystemspezifischen Startcode enthält, der zuvor ausgeführt wurde
main()
. Unter Windows ist diescrt0
. Unix und Linux haben dasselbe, wobei ein C-Runtime-Startcode statisch mit jeder Binärdatei verknüpft ist. Ich denke, theoretisch könnten Sie ein System entwerfen, in dem dieser Code auch dynamisch verknüpft war und Teil von libc oder des dynamischen Linkers selbst ist, aber so funktionieren die Dinge in der Praxis auf keinem mir bekannten Betriebssystem. Dies würde nur das ABI-Problem des Systemaufrufs lösen, nicht das Problem der numerischen Werte für Konstanten für Standardbibliotheksfunktionen. (Normalerweise werden Systemaufrufe über libc-Wrapper-Funktionen ausgeführt: Eine normale x86-64-Linux-Binärdatei für die verwendete Quelle enthältmmap()
nicht diesyscall
Anweisung, sondern nur acall
Anweisung an die gleichnamige libc-Wrapper-Funktion.Dies ist einer der Gründe, warum Sie i386-FreeBSD-Binärdateien nicht einfach unter i386-Linux ausführen können. (Für eine Weile hatte der Linux-Kernel eine Systemaufruf-Kompatibilitätsschicht. Ich denke, mindestens eines der BSDs kann Linux-Binärdateien mit einer ähnlichen Kompatibilitätsschicht ausführen, aber Sie benötigen natürlich Linux-Bibliotheken.)
Wenn Sie Binärdateien verteilen möchten, müssen Sie für jede Kombination aus CPU / Betriebssystem-Version + Version / installierte Bibliotheksversion eine separate erstellen .
In den 80er / 90er Jahren gab es viele verschiedene CPU-Typen, die für Unix-Systeme (MIPS, SPARC, POWER, PA-RISC, m68k usw.) allgemein verwendet wurden, und viele verschiedene Unix-Varianten (IRIX, SunOS, Solaris, AIX, HP-UX, BSD usw.).
Und das sind nur Unix- Systeme. Viele Quellpakete würden auch auf anderen Systemen wie VAX / VMS, MacOS (m68k und PPC), Amiga, PC / MS-DOS, Atari ST usw. kompiliert und funktionieren .
Es gibt immer noch viele CPU-Architekturen und Betriebssysteme, obwohl jetzt eine große Mehrheit der Desktops auf x86 mit einem von drei Hauptbetriebssystemen ausgeführt wird.
Es gibt also bereits mehr CPU / OS-Kombinationen, als Sie sich vorstellen können, noch bevor Sie über Abhängigkeiten von Bibliotheken von Drittanbietern nachdenken, die auf verschiedenen Systemen unterschiedliche Versionen haben können. (Alles, was nicht vom Hersteller des Betriebssystems gepackt wurde, muss von Hand installiert werden.)
Alle Pfade, die in die Binärdatei kompiliert werden, sind ebenfalls systemspezifisch. (Dies spart RAM und Zeit im Vergleich zum Lesen aus einer Konfigurationsdatei beim Start). Unix-Systeme der alten Schule hatten normalerweise viele handgefertigte Dinge, so dass Sie keine gültigen Annahmen darüber treffen können, was wo ist.
Das Verteilen von Binärdateien war für Unix der alten Schule völlig unmöglich, mit Ausnahme von kommerziellen Großprojekten, die es sich leisten können, alle wichtigen Kombinationen zu erstellen und zu testen .
Sogar Binärdateien für gerecht
i386-linux-gnu
undamd64-linux-gnu
schwierig zu machen. Es wurde viel Zeit und Mühe in Dinge wie die Linux Standard Base investiert, um tragbare Binärdateien zu ermöglichen . Selbst das statische Verknüpfen von Binärdateien löst nicht alles. (z. B. wie sollte ein Textverarbeitungsprogramm auf einem RedHat-System im Vergleich zu einem Debian-System gedruckt werden? Wie sollte die Installation einen Benutzer oder eine Gruppe für einen Dämon hinzufügen und dafür sorgen, dass das Startskript nach jedem Neustart ausgeführt wird?) Diese sind nicht großartig Beispiele, weil das Neukompilieren aus dem Quellcode sie nicht löst.Abgesehen davon war die Erinnerung früher kostbarer als heute. Wenn beim Kompilieren optionale Funktionen weggelassen werden, können kleinere Binärdateien (weniger Codegröße) erstellt werden, die auch weniger Speicher für ihre Datenstrukturen benötigen. Wenn für ein Feature in jeder Instanz eines bestimmten Elements ein zusätzliches Mitglied erforderlich ist
class
oderstruct
um etwas zu verfolgen, wird durch Deaktivieren dieses Features das Objekt beispielsweise um 4 Byte verkleinert. Dies ist hilfreich, wenn es sich um ein Objekt handelt, dem das Programm 100.000 zuweist.Optionale Funktionen zur Kompilierungszeit werden heutzutage am häufigsten verwendet, um zusätzliche Bibliotheken optional zu machen. zB können Sie kompilieren
ffmpeg
mit oder ohnelibx264
,libx265
,libvorbis
, und viele andere Bibliotheken für spezifische Video / Audio - Encoder, Untertitel Handling, etc. etc. Häufiger kann eine Menge Dinge , mit oder ohne kompiliert werdenlibreadline
: wenn es verfügbar ist , wenn Sie laufen./configure
, die Die resultierende Binärdatei hängt von der Bibliothek ab und bietet eine ausgefallene Zeilenbearbeitung beim Lesen von einem Terminal. Wenn dies nicht der Fall ist, verwendet das Programm eine Fallback-Unterstützung, um nur Zeilen aus dem Standard mitfgets()
oder so etwas zu lesen .)Einige Projekte verwenden weiterhin optionale Funktionen, um aus Leistungsgründen nicht benötigten Code wegzulassen. Beispielsweise kann der Linux-Kernel selbst ohne SMP-Unterstützung erstellt werden (z. B. für ein eingebettetes System oder einen alten Desktop). In diesem Fall ist ein Großteil der Sperrung einfacher. Oder mit vielen anderen optionalen Funktionen, die sich auf einen Teil des Kerncodes auswirken und nicht nur Treiber oder andere Hardwarefunktionen weglassen. (Obwohl arch- und hardwarespezifische Konfigurationsoptionen einen Großteil des gesamten Quellcodes ausmachen . Siehe Warum enthält der Linux-Kernel mehr als 15 Millionen Codezeilen? )
quelle