Lernen, Dinge aus dem Quellcode zu kompilieren (unter Unix / Linux / OSX)

47

Während ich Software von Paketen (MacPorts / apt-get) aus installiere, muss ich häufig Pakete aus dem Quellcode kompilieren. ./configure && make && sudo make installist normalerweise genug, aber manchmal funktioniert es nicht - und wenn nicht, stecke ich häufig fest. Dies hängt fast immer mit anderen Bibliotheksabhängigkeiten zusammen.

Ich möchte folgendes lernen:

  • Wie finde ich heraus, an welche Argumente ich weitergeben soll ./configure?
  • Wie Shared Libraries unter OS X / Linux funktionieren - wo sie sich im Dateisystem befinden, wie ./configure && makesie gefunden werden, was tatsächlich passiert, wenn sie miteinander verknüpft werden
  • Was sind die tatsächlichen Unterschiede zwischen einer gemeinsam genutzten und einer statisch verknüpften Bibliothek? Warum kann ich nicht einfach alles statisch verknüpfen (RAM und Festplattenspeicher sind heutzutage billig) und so seltsame Konflikte mit Bibliotheksversionen vermeiden?
  • Wie kann ich feststellen, welche Bibliotheken ich installiert habe und welche Versionen?
  • Wie kann ich mehr als eine Version einer Bibliothek installieren, ohne mein normales System zu beschädigen?
  • Wenn ich bin Sachen auf einem System von der Quelle zu installieren , die sonst verwenden Pakete verwaltet werden , was ist der sauberste Weg , dies zu tun?
  • Angenommen, ich schaffe es, etwas aus dem Quellcode heraus zu kompilieren, wie kann ich das dann verpacken, damit andere Leute nicht durch dieselben Rahmen springen müssen? Besonders unter OS X ....
  • Was sind die Kommandozeilen-Tools, die ich beherrschen muss, um mit diesen Dingen zurechtzukommen? Sachen wie otool, pkg-config etc.

Ich bin bereit, hier einiges an Zeit und Mühe zu investieren - ich möchte nicht unbedingt direkte Antworten auf die oben genannten Fragen, ich möchte vielmehr Empfehlungen zu Büchern / Tutorials / FAQs erhalten, die ich lesen kann und die mir das geben Wissen Ich muss verstehen, was tatsächlich vor sich geht, und daher Probleme selbst herausfinden.

Simon Willison
quelle

Antworten:

40

Ich entschuldige mich für die direkte Beantwortung aller Fragen, aber ich kenne keine nützlichen Tutorials, FAQs usw. Im Grunde genommen sind es 8 Jahre, in denen ich Desktop-Apps (die ich verteile), Frust und Googeln mache:

1. Wie finde ich heraus, welche Argumente an ./configure übergeben werden müssen?

Übe wirklich. Autotools ist einfach genug, da es konsistent ist. Aber es gibt viele Dinge, die mit cmake oder benutzerdefinierten Skripten erstellt werden. Im Allgemeinen sollte es nicht erforderlich sein, etwas zu konfigurieren. Es sollte herausgefunden werden, ob Ihr System foo-tool erstellen kann oder nicht.

Konfigurations- und GNU-Tools suchen alle in /, / usr und / usr / local nach Abhängigkeiten. Wenn Sie irgendwo anders installieren (was die Installation der Abhängigkeit durch MacPorts oder Fink schmerzhaft macht), müssen Sie ein Flag übergeben, um die Shell-Umgebung zu konfigurieren oder zu ändern, damit GNU-Tools diese Abhängigkeiten finden können.

2. Wie Shared Libraries unter OS X / Linux funktionieren - wo sie sich auf dem Dateisystem befinden, wie ./configure && make sie findet, was passiert, wenn sie miteinander verknüpft werden

Unter Linux müssen sie auf einem Pfad installiert werden, den der Dynamic Linker finden kann. Dies wird durch die LD_LIBRARY_PATHUmgebungsvariable und den Inhalt von /etc/ld.conf definiert. Auf Mac ist es für die meisten Open Source-Programme fast immer dasselbe (es sei denn, es ist ein Xcode-Projekt). Ausgenommen die env-Variable ist DYLD_LIBRARY_PATHstattdessen.

Es gibt einen Standardpfad, den der Linker nach Bibliotheken durchsucht. Es ist / lib: / usr / lib: / usr / local / lib

Sie können dies ergänzen, indem Sie die CPATH-Variable oder CFLAGS oder eine beliebige Anzahl anderer Umgebungsvariablen verwenden (praktisch kompliziert). Ich schlage CFLAGS so vor:

export CFLAGS = "$ CFLAGS -L / new / path"

Der Parameter -L fügt den Linkpfad hinzu.

Moderne Sachen benutzen das pkg-config Tool. Modernes Zeug, das Sie installieren, installiert auch eine .pc-Datei, die die Bibliothek beschreibt, wo sie sich befindet und wie sie verlinkt wird. Das kann das Leben leichter machen. Aber es kommt nicht mit OS X 10.5 daher müssen Sie das auch installieren. Auch viele Basic Deps unterstützen es nicht.

Das Verknüpfen ist nur "Diese Funktion zur Laufzeit auflösen", es ist wirklich eine große Zeichenfolgentabelle.

3. Was sind die tatsächlichen Unterschiede zwischen einer gemeinsam genutzten und einer statisch verknüpften Bibliothek? Warum kann ich nicht einfach alles statisch verknüpfen (RAM und Festplattenspeicher sind heutzutage billig) und so seltsame Konflikte mit Bibliotheksversionen vermeiden?

Wenn Sie eine Verknüpfung zu einer statischen Bibliotheksdatei herstellen, wird der Code Teil Ihrer Anwendung. Es wäre, als gäbe es eine riesige .c-Datei für diese Bibliothek, die Sie in Ihre Anwendung kompiliert haben.

Dynamische Bibliotheken haben den gleichen Code, aber wenn die App ausgeführt wird, wird der Code zur Laufzeit in die App geladen (vereinfachte Erklärung).

Sie können statisch auf alles verlinken, aber leider machen kaum Build-Systeme dies einfach. Sie müssten Build-Systemdateien manuell bearbeiten (z. B. Makefile.am oder CMakeLists.txt). Dies lohnt sich jedoch wahrscheinlich, wenn Sie regelmäßig Dinge installieren, die unterschiedliche Versionen von Bibliotheken erfordern, und es schwierig ist, Abhängigkeiten parallel zu installieren.

Der Trick ist, die Verbindungslinie von -lfoo nach -l / path / nach / static / foo.a zu ändern

Sie können wahrscheinlich finden und ersetzen. Überprüfen Sie anschließend, ob das Tool mit ldd foo oder otool -L foo keine Verknüpfung zu .so oder dylib herstellt

Ein weiteres Problem ist, dass nicht alle Bibliotheken zu statischen Bibliotheken kompiliert werden. Viele tun es. Aber dann haben MacPorts oder Debian möglicherweise beschlossen, es nicht zu versenden.

4. Wie kann ich feststellen, welche Bibliotheken ich installiert habe und welche Versionen?

Wenn Sie pkg-config-Dateien für diese Bibliotheken haben, ist es einfach:

pkg-config --list-all

Sonst kann man oft nicht einfach. Die Dylib kann einen Sonamen haben (dh foo.0.1.dylib, der Soname ist 0.1), der der Version der Bibliothek entspricht. Dies ist jedoch nicht erforderlich. Der Soname ist eine binäre Berechenbarkeitsfunktion. Wenn Sie das Format der Funktionen in der Bibliothek ändern, müssen Sie den größten Teil des Sonames verschieben. So kann man zB bekommen. Soname für Version 14.0.5 für eine 2.0-Bibliothek. Obwohl dies nicht üblich ist.

Ich war frustriert über so etwas und habe eine Lösung für dieses Problem auf dem Mac entwickelt, und ich spreche als nächstes darüber.

5. Wie kann ich mehr als eine Version einer Bibliothek installieren, ohne mein normales System zu beschädigen?

Meine Lösung hierfür ist hier: http://github.com/mxcl/homebrew/

Ich mag die Installation von der Quelle und wollte ein Tool, das es einfach machte, aber mit einigem Paketmanagement. Also mit Homebrew baue ich zB. wget mich von der Quelle, aber stellen Sie sicher, um ein spezielles Präfix zu installieren:

/usr/local/Cellar/wget/1.1.4

Ich verwende dann das Homebrew-Tool, um all das mit / usr / local zu verknüpfen, also habe ich immer noch / usr / local / bin / wget und /usr/local/lib/libwget.dylib

Wenn ich später eine andere Version von wget benötige, kann ich diese parallel installieren und einfach die Version ändern, die mit dem / usr / local-Baum verknüpft ist.

6. Was ist die sauberste Methode, wenn ich Inhalte aus dem Quellcode auf einem System installiere, das ansonsten mit Paketen verwaltet wird?

Ich glaube, der Homebrew-Weg ist am saubersten, also benutze ihn oder tue das Gleiche. Installieren Sie in / usr / local / pkgs / name / version und verknüpfen Sie den Rest mit symlink oder hardlink.

Verwenden Sie / usr / local. Jedes existierende Build-Tool sucht dort nach Abhängigkeiten und Headern. Ihr Leben wird viel einfacher sein.

7. Wenn ich es schaffe, etwas aus dem Quellcode zu kompilieren, wie kann ich das dann verpacken, damit andere Leute nicht durch die gleichen Rahmen springen müssen? Besonders unter OS X ....

Wenn es keine Abhängigkeiten gibt, können Sie das Build-Verzeichnis tarieren und an eine andere Person weitergeben, die dann "make install" ausführen kann. Dies ist jedoch nur für genau die gleichen Versionen von OS X zuverlässig möglich. Unter Linux wird es wahrscheinlich für ähnliche Linux-Versionen (z. B. Ubuntu) mit der gleichen Kernel-Version und libc minor-Version funktionieren.

Der Grund, warum es nicht einfach ist, Binärdateien unter Unix zu verteilen, liegt in der Binärkompatibilität. Die GNU-Leute und alle anderen ändern oft ihre binären Schnittstellen.

Verteilen Sie grundsätzlich keine Binärdateien. Die Dinge werden wahrscheinlich auf sehr seltsame Weise brechen.

Unter Mac ist die beste Option, ein Macports-Paket zu erstellen. Jeder nutzt Macports. Unter Linux gibt es so viele verschiedene Build-Systeme und Kombinationen, dass ich nicht denke, dass es einen besseren Rat gibt, als einen Blog-Eintrag darüber zu schreiben, wie es Ihnen gelungen ist, das X-Tool in einer seltsamen Konfiguration zu erstellen.

Wenn Sie eine Paketbeschreibung erstellen (für Macports oder Homebrew), kann jeder das Paket installieren und damit auch die Abhängigkeitsprobleme lösen. Dies ist jedoch oft nicht einfach und es ist auch nicht einfach, Ihr Macports-Rezept in den Haupt-Macports-Baum aufzunehmen. Auch Macports unterstützen keine exotischen Installationstypen. Sie bieten eine Auswahl für alle Pakete.

Eines meiner zukünftigen Ziele bei Homebrew ist es, es zu ermöglichen, auf einen Link auf einer Website zu klicken (z. B. homebrew: // blah) und dieses Ruby-Skript herunterzuladen, die Deps für dieses Paket zu installieren und dann die App zu erstellen. Noch nicht fertig, aber angesichts des von mir gewählten Designs nicht zu knifflig.

8. Was sind die Kommandozeilen-Tools, die ich beherrschen muss, um mit diesen Dingen zurechtzukommen? Sachen wie otool, pkg-config etc.

otool ist eigentlich erst danach sinnvoll. Hier erfahren Sie, worauf die erstellte Binärdatei verweist. Wenn Sie die Abhängigkeiten eines Tools herausfinden, das Sie erstellen müssen, ist es nutzlos. Dasselbe gilt für pkg-config, da Sie die Abhängigkeit bereits installiert haben, bevor Sie sie verwenden können.

Meine Toolkette lautet: Lies die README- und INSTALL-Dateien und führe eine configure -Hilfe aus. Beobachten Sie die Build-Ausgabe, um sicherzustellen, dass sie korrekt ist. Analysieren Sie alle Erstellungsfehler. Vielleicht fragen Sie in Zukunft bei Serverfehler :)

Max Howell
quelle
2
Interessanterweise ähnelt Homebrew Portage (dem Paketmanager von Gentoo Linux). Klingt nach einer schönen Arbeit.
David Z
12

Dies ist ein riesiges Thema. Beginnen wir also mit gemeinsam genutzten Bibliotheken unter Linux (ELF unter Linux und Mach-O unter OS X). Ulrich Drepper hat eine gute Einführung in das Schreiben von DSOs (Dynamic Shared Objects), die einen Teil der Geschichte von gemeinsam genutzten Bibliotheken unter Linux abdecken hier auch, warum sie wichtig sind

Ulrich beschreibt auch, warum statische Verknüpfungen als schädlich eingestuft werden. Einer der wichtigsten Punkte hierbei sind Sicherheitsupdates. Pufferüberläufe in einer allgemeinen Bibliothek (z. B. zlib), die stark statisch verknüpft ist, können einen enormen Overhead für Distributionen verursachen - dies trat mit zlib 1.1.3 auf ( Red Hat Advisory ).

ELF

Die Manpage zum Linker ld.so

man ld.so 

Erklärt die grundlegenden Pfade und Dateien für die dynamische Laufzeitverknüpfung. Auf modernen Linux-Systemen werden zusätzliche Pfade über /etc/ld.so.conf.d/ angezeigt, die normalerweise über ein Glob-Include in /etc/ld.so.conf hinzugefügt werden.

Wenn Sie sehen möchten, was über Ihre ld.so-Konfiguration dynamisch verfügbar ist, können Sie dies ausführen

ldconfig -v -N -X

Wenn Sie das DSO-Howto lesen, sollten Sie über gute Grundkenntnisse verfügen, um anschließend zu verstehen, wie diese Prinzipien für Mach-O unter OS X gelten.

Macho

Unter OS X lautet das Binärformat Mach-O. Lokale Systemdokumentation für den Linker ist

man dyld

Die Mach-Format-Dokumentation ist bei Apple erhältlich

UNIX-Build-Tools

Die gemeinsame configure, make, make installwird Prozess in der Regel von GNU Autotools zur Verfügung gestellt , die eine hat Online - Buch , dass behandelt einige der Geschichte des configure / build Split und der GNU - Toolchain. Autoconf verwendet Tests, um die Verfügbarkeit von Features auf dem Ziel-Build-System zu bestimmen. Es verwendet die Makrosprache M4 , um dies zu steuern. Automake ist im Grunde eine Template-Methode für Makefiles. Die Vorlage heißt im Allgemeinen Makefile.am und gibt ein Makefile.in aus, das die Ausgabe von autoconf (das configure-Skript) in ein Makefile konvertiert.

Das GNU-Hallo- Programm ist ein gutes Beispiel für das Verständnis der GNU-Toolchain - und das Handbuch enthält Autotools-Dokumentation.


quelle
10

Simon! Ich weiß wie du dich fühlst; Ich hatte auch mit diesem Teil des Lernens von Linux zu kämpfen. Aufgrund meiner eigenen Erfahrungen habe ich ein Tutorial zu einigen der von Ihnen angesprochenen Themen geschrieben (hauptsächlich als Referenz für mich!): Http://easyaspy.blogspot.com/2008/12/buildinginstalling-application-from.html . Ich denke, Sie werden meinen Hinweis zu schätzen wissen, wie einfach Python-Anwendungen zu erstellen / installieren sind. :)

Hoffe das hilft! Und viel Spaß beim Kompilieren.

Tim Jones


Erstellen / Installieren einer Anwendung aus dem Quellcode in Ubuntu Linux

Während die Ubuntu-Repositories voll von großartigen Anwendungen sind, werden Sie auf die eine oder andere Weise auf das "Must-Have" -Tool stoßen, das sich nicht in den Repositories befindet (oder kein Debian-Paket hat) oder das Sie brauchen neuere Version als in den Repositories. Wie geht's? Nun, Sie müssen die Anwendung aus dem Quellcode erstellen! Keine Sorge, es ist wirklich nicht so kompliziert, wie es sich anhört. Hier sind einige Tipps, die auf meinen Erfahrungen als Amateur basieren! (Während ich Ubuntu für dieses Beispiel verwende, sollten die allgemeinen Konzepte für die meisten Unix / Linux-Distributionen wie Fedora und sogar für die Cygwin-Plattform unter Windows gelten.)

Der grundlegende Prozess zum Erstellen (Kompilieren) der meisten Anwendungen aus dem Quellcode folgt dieser Reihenfolge: configure -> compile -> install. Die typischen Unix / Linux-Befehle für diese Aufgaben sind: config-> make-> make install. In einigen Fällen finden Sie sogar Webseiten, die zeigen, dass alle diese Befehle zu einem einzigen Befehl kombiniert werden können:

$ config && make && make install

Bei diesem Befehl wird natürlich davon ausgegangen, dass bei keinem dieser Schritte Probleme auftreten. Hier kommt der Spaß ins Spiel!

Anfangen

Wenn Sie noch keine Anwendung aus dem Quellcode auf Ihrem System kompiliert haben, müssen Sie sie wahrscheinlich mit einigen allgemeinen Entwicklungstools wie der gccCompiler-Suite und einigen allgemeinen Header-Dateien einrichten (stellen Sie sich dies als Code vor, der bereits geschrieben wurde von einer anderen Person, die von dem zu installierenden Programm verwendet wird), und dem make-Tool. Glücklicherweise gibt es in Ubuntu ein so genanntes Metapaket build-essential, das dies installiert. Um es zu installieren (oder stellen Sie einfach sicher, dass Sie es bereits haben!), Führen Sie diesen Befehl im Terminal aus:

$ sudo apt-get install build-essential

Nachdem Sie die Grundkonfiguration vorgenommen haben, laden Sie die Anwendungsquelldateien herunter und speichern Sie sie in einem Verzeichnis, für das Sie Lese- / Schreibberechtigungen haben, z. B. in Ihrem Basisverzeichnis. Normalerweise befinden sich diese in einer Archivdatei mit der Dateierweiterung entweder .tar.gzoder .tar.bz2. Das .tarbedeutet einfach , dass es ein „Band - Archiv“, das eine Gruppierung von Dateien, die ihre relative Verzeichnisstruktur erhalten bleiben. Das .gzsteht für gzip (GNU zip), ein beliebtes Unix / Linux-Komprimierungsformat. Ebenso .bz2steht das für bzip2, ein neueres Komprimierungsformat, das eine höhere Komprimierung (kleinere komprimierte Dateigröße) als gzip bietet.

Nachdem Sie die Quelldatei heruntergeladen haben, öffnen Sie ein Terminalfenster (System Terminal aus dem Ubuntu-Menü) und wechseln Sie in das Verzeichnis, in dem Sie Ihre Datei gespeichert haben. ( ~/downloadIn diesem Beispiel verwende ich . Hier ist '~' eine Verknüpfung zu Ihrem "Home" -Verzeichnis.) Verwenden Sie den Befehl tar, um die Dateien aus der heruntergeladenen Archivdatei zu extrahieren:

Wenn Ihre Datei ein gzip-Archiv ist (zB endet mit .tar.gz), verwenden Sie den Befehl:

            $ tar -zxvf filename.tar.gz

Wenn Ihre Datei ein bzip2-Archiv ist (zB endet mit .tar.bz2), verwenden Sie den Befehl:

            $ tar -jxvf filename.tar.gz

Tipp: Wenn Sie sich nicht alle Befehlszeilenoptionen merken müssen, um Archive zu extrahieren, empfehle ich eines (oder beide) dieser Dienstprogramme: dtrx (mein Favorit!) Oder deco (populärer). Mit einem dieser Dienstprogramme geben Sie einfach den Namen des Dienstprogramms (dtrx oder deco) und den Dateinamen ein, den Rest erledigt es. Beide "wissen", wie sie mit den meisten Archivformaten umgehen können, auf die Sie wahrscheinlich stoßen, und sie haben eine hervorragende Fehlerbehandlung.

Beim Erstellen aus dem Quellcode treten wahrscheinlich zwei häufig auftretende Fehlertypen auf:

  1. Konfigurationsfehler treten auf, wenn Sie das Konfigurationsskript (normalerweise config oder configure) ausführen, um ein für Ihr Setup spezifisches Makefile zu erstellen.
  2. Compilerfehler treten auf, wenn Sie den Befehl make ausführen (nachdem das Makefile generiert wurde) und der Compiler nicht den Code findet, den er benötigt.

Wir werden uns jedes dieser Probleme ansehen und besprechen, wie es gelöst werden kann.

Konfiguration und Konfigurationsfehler

Nachdem Sie die Quellcode-Archivdatei extrahiert haben, sollten Sie im Terminal in das Verzeichnis wechseln, das die extrahierten Dateien enthält. In der Regel entspricht dieser Verzeichnisname dem Namen der Datei (ohne die Erweiterung .tar.gzoder .tar.bz2). Manchmal ist der Verzeichnisname jedoch nur der Name der Anwendung ohne Versionsinformationen.

Suchen Sie im Quellverzeichnis nach einer READMEDatei und / oder einer INSTALLDatei (oder etwas mit ähnlichen Namen). Diese Dateien enthalten in der Regel nützliche Informationen zum Erstellen / Kompilieren und Installieren der Anwendung, einschließlich Informationen zu Abhängigkeiten. "Abhängigkeiten" sind nur ein ausgefallener Name für andere Komponenten oder Bibliotheken, die für eine erfolgreiche Kompilierung erforderlich sind.

Nachdem Sie die Datei READMEund / oder gelesen haben INSTALL(und hoffentlich eine relevante Online-Dokumentation für die Anwendung gelesen haben ), suchen Sie nach einer ausführbaren Datei mit dem Namen configoder configure. Manchmal hat die Datei eine Erweiterung, wie .shzB config.sh. Dies ist normalerweise ein Shell-Skript, das einige andere Dienstprogramme ausführt, um zu bestätigen, dass Sie eine "vernünftige" Umgebung zum Kompilieren haben. Mit anderen Worten, es wird überprüft, ob alles installiert ist, was Sie benötigen.

Tipp: Wenn es sich um eine Python-basierte Anwendung handelt, sollten Sie anstelle einer Konfigurationsdatei eine Datei mit dem Namen suchen setup.py. Python-Anwendungen sind normalerweise sehr einfach zu installieren. Um diese Anwendung als root zu installieren (z. B. setzen Sie sudo unter Ubuntu vor den folgenden Befehl), führen Sie diesen Befehl aus:

    $ python setup.py install

Das sollte alles sein, was Sie tun müssen. Sie können den Rest dieses Lernprogramms überspringen und direkt mit der Verwendung und Verwendung Ihrer Anwendung fortfahren.

Führen Sie das Konfigurationsskript im Terminal aus. Normalerweise können (und sollten) Sie Ihr Konfigurationsskript mit Ihrem regulären Benutzerkonto ausführen.

$ ./config

Das Skript zeigt einige Meldungen an, um Ihnen eine Vorstellung davon zu geben, was es tut. Häufig gibt Ihnen das Skript einen Hinweis darauf, ob es erfolgreich war oder fehlgeschlagen ist, und, falls es fehlgeschlagen ist, einige Informationen zur Ursache des Fehlers. Wenn Sie keine Fehlermeldungen erhalten, können Sie normalerweise davon ausgehen, dass alles in Ordnung ist.

Wenn Sie kein Skript finden, das wie ein Konfigurationsskript aussieht, bedeutet dies in der Regel, dass die Anwendung sehr einfach und plattformunabhängig ist. Dies bedeutet, dass Sie einfach mit dem folgenden Schritt zum Erstellen / Kompilieren fortfahren können, da das bereitgestellte Makefileauf jedem System funktionieren sollte.

Ein Beispiel

In diesem Tutorial verwende ich den textbasierten RSS-Reader Newsbeuter als Beispiel für die Arten von Fehlern, die beim Erstellen Ihrer Anwendung auftreten können. Für Newsbeuter lautet der Name des Konfigurationsskripts config.sh. Auf meinem System treten beim Ausführen config.shdie folgenden Fehler auf:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ ./config.sh
Checking for package sqlite3... not found

You need package sqlite3 in order to compile this program.
Please make sure it is installed.

Nach einigen Recherchen stellte ich fest, dass die sqlite3Anwendung tatsächlich installiert war. Da ich jedoch versuche, aus dem Quellcode zu erstellen, ist dies ein Tipp, nach dem config.sheigentlich die Entwicklungsbibliotheken (Header) suchen sqlite3. In Ubuntu haben die meisten Pakete ein zugehöriges Entwicklungs-Gegenstück-Paket, das auf endet -dev. (Andere Plattformen wie Fedora verwenden häufig ein Paketsuffix -develfür die Entwicklungspakete.)

Um das passende Paket für das sqlite3Entwicklungspaket zu finden , können wir das apt-cacheHilfsprogramm in Ubuntu (und ähnlich das yumHilfsprogramm in Fedora) verwenden:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-cache search sqlite

Dieser Befehl gibt eine ziemlich große Liste von Ergebnissen zurück, daher müssen wir ein wenig Detektivarbeit leisten, um das geeignete Paket zu ermitteln. In diesem Fall stellt sich das entsprechende Paket heraus libsqlite3-dev. Beachten Sie, dass das gesuchte Paket manchmal das libPräfix anstelle des gleichen Paketnamens plus hat -dev. Dies liegt daran, dass wir manchmal nur nach einer gemeinsam genutzten Bibliothek suchen, die von vielen verschiedenen Anwendungen verwendet werden kann. libsqlite3-devFühren Sie zum Installieren den typischen Befehl apt-get install im Terminal aus:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-get install libsqlite3-dev

Jetzt müssen wir config.sherneut ausführen , um sicherzustellen, dass wir dieses Abhängigkeitsproblem gelöst haben und keine Abhängigkeitsprobleme mehr haben. (Während ich es hier nicht zeige, musste ich im Falle von Newsbeuter auch das libcurl4-openssl-devPaket installieren .) Auch wenn Sie ein Entwicklungspaket (wie libsqlite3-dev) installieren und das zugehörige Anwendungspaket (zB sqlite3) nicht Bereits installiert, installieren die meisten Systeme gleichzeitig automatisch das zugehörige Anwendungspaket.

Wenn die Konfiguration erfolgreich ausgeführt wird, werden eine oder mehrere Make-Dateien erstellt. Diese Dateien haben normalerweise einen Namen Makefile(denken Sie daran, dass bei Unix / Linux die Groß- und Kleinschreibung des Dateinamens eine Rolle spielt!). Wenn das Erstellungspaket Unterverzeichnisse wie z. B. srcusw. enthält, enthält jedes dieser Unterverzeichnisse Makefileauch ein.

Fehler beim Erstellen und Kompilieren

Jetzt können wir die Anwendung tatsächlich kompilieren. Dies wird oft als Gebäude bezeichnet und der Name ist dem realen Konstruktionsprozess entlehnt. Die verschiedenen "Teile" der Anwendung, bei denen es sich normalerweise um mehrere Quellcodedateien handelt, werden zu einer Gesamtanwendung zusammengefasst. Das Dienstprogramm make verwaltet den Erstellungsprozess und ruft andere Anwendungen wie den Compiler und den Linker auf, um die Arbeit tatsächlich auszuführen. In den meisten Fällen führen Sie make einfach (mit Ihrem regulären Benutzerkonto) aus dem Verzeichnis aus, in dem Sie die Konfiguration ausgeführt haben. (In einigen Fällen, z. B. beim Kompilieren von Anwendungen, die mit der Qt-Bibliothek geschrieben wurden, müssen Sie stattdessen eine andere "Wrapper" -Anwendung wie qmake ausführen. Überprüfen Sie auch hier immer die READMEund / oder INSTALLDokumente auf Details.)

Wie im obigen Konfigurationsskript werden beim Ausführen von make (oder einem ähnlichen Dienstprogramm) im Terminal einige Meldungen zur Ausführung sowie etwaige Warnungen und Fehler angezeigt. Sie können Warnungen in der Regel ignorieren, da sie hauptsächlich für die Entwickler der Anwendung bestimmt sind und ihnen mitteilen, dass gegen einige Standardverfahren verstoßen wird. Normalerweise haben diese Warnungen keinen Einfluss auf die Anwendungsfunktion. Auf der anderen Seite müssen Compilerfehler behoben werden. Als ich mit Newsbeuter make lief, lief es eine Weile gut, aber dann bekam ich einen Fehler:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ make
...
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/configparser.o -c src/configparser.cpp
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/colormanager.o -c src/colormanager.cpp
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:5:18: error: stfl.h: No such file or directory
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:33: error: ISO C++ forbids declaration of \u2018stfl_form\u2019 with no type
./include/stflpp.h:33: error: expected \u2018;\u2019 before \u2018*\u2019 token
./include/stflpp.h:34: error: ISO C++ forbids declaration of \u2018stfl_ipool\u2019 with no type
./include/stflpp.h:34: error: expected \u2018;\u2019 before \u2018*\u2019 token
make: *** [src/colormanager.o] Error 1

Der make-Vorgang wird abgebrochen, sobald der erste Fehler auftritt. Der Umgang mit Compilerfehlern kann manchmal schwierig sein. Sie müssen sich die Fehler ansehen, um Hinweise auf das Problem zu erhalten. In der Regel besteht das Problem darin, dass einige Headerdateien, die normalerweise die Erweiterung .hoder haben .hpp, fehlen. Im Falle des obigen Fehlers ist (oder sollte!) Klar, dass das Problem darin besteht, dass die stfl.hHeader-Datei nicht gefunden werden kann. Wie dieses Beispiel zeigt, sollten Sie sich die ersten Zeilen der Fehlermeldung ansehen und nach unten arbeiten, um die zugrunde liegende Ursache des Problems zu finden.

Nachdem ich mir die Newsbeuter-Dokumentation angesehen hatte (was ich hätte tun sollen, bevor ich anfing, aber dann wäre dieser Teil des Tutorials nicht sehr aussagekräftig!), Stellte ich fest, dass eine Drittanbieter-Bibliothek namens STFL erforderlich ist. Was machen wir also in diesem Fall? Nun, wir wiederholen im Wesentlichen denselben Vorgang für die erforderliche Bibliothek: Besorgen Sie sich die Bibliothek und führen Sie den Configure-Build-Install-Vorgang für sie aus und setzen Sie dann die Erstellung der gewünschten Anwendung fort. Im Fall von STFL musste ich beispielsweise das libncursesw5-devPaket installieren , damit es ordnungsgemäß erstellt wurde. (Normalerweise ist es nicht erforderlich, den Konfigurationsschritt für unsere ursprüngliche Anwendung nach der Installation einer anderen erforderlichen Anwendung erneut durchzuführen, aber es kann auch nie schaden.)

Nach der erfolgreichen Installation des STFL-Toolkits wurde der Make-Prozess für Newsbeuter erfolgreich ausgeführt. Der make-Prozess setzt normalerweise dort an, wo er aufhört (zum Zeitpunkt des Fehlers). Dateien, die bereits erfolgreich kompiliert wurden, werden daher nicht erneut kompiliert. Wenn Sie alles neu kompilieren möchten, können Sie make clean all ausführen, um alle kompilierten Objekte zu entfernen, und make erneut ausführen.

Installieren

Nachdem der Erstellungsprozess erfolgreich abgeschlossen wurde, können Sie die Anwendung installieren. In den meisten Fällen müssen Sie die Installation als Root ausführen , um die Anwendung in den allgemeinen Bereichen des Dateisystems (z. B. /usr/binoder /usr/share/binusw.) zu installieren. Die Installation ist wirklich der einfachste Schritt im gesamten Prozess. So installieren Sie im Terminal:

$ make install

Überprüfen Sie die Ausgabe dieses Prozesses auf Fehler. Wenn alles erfolgreich war, sollten Sie in der Lage sein, den Befehlsnamen im Terminal auszuführen, und es wird gestartet. (Fügen Sie & an das Ende der Befehlszeile an, wenn es sich um eine GUI-Anwendung handelt oder Sie die Terminalsitzung erst verwenden können, wenn die Ausführung der Anwendung abgeschlossen ist.)

Wenn Sie eine Anwendung aus dem Quellcode erstellen, wird den GUI-Menüs in Ubuntu normalerweise kein Symbol oder keine Verknüpfung hinzugefügt. Sie müssen dies manuell hinzufügen.

Und das ist im Grunde der Prozess, wenn auch möglicherweise iterativ, um eine Anwendung aus dem Quellcode in Ubuntu zu erstellen und zu installieren. Nachdem Sie dies nur ein paar Mal getan haben, wird es für Sie zur zweiten Natur!

Tim Jones
quelle
Tim, ich hätte dein Tutorial gerne gelesen, aber der Link, den du gepostet hast, funktioniert nicht.
gareth_bowles
6

Nun, ./configure --help liefert Ihnen eine Menge Informationen zu den von GNU Autotools generierten Konfigurationsdateien. Das meiste ist darauf zurückzuführen, dass --with / - Features nicht aktiviert werden müssen (für diese kann ein zusätzlicher Parameter erforderlich sein, z. B. "shared", um anzugeben, wo sich die Bibliothek befindet).

Andere wichtige sind --prefix (standardmäßig / usr / local / die meiste Zeit), um anzugeben, wohin installiert werden soll (wenn Sie Pakete erstellen, möchten Sie dies normalerweise als --prefix = / usr oder vielleicht --prefix = / opt / YourPackage).

Unter Linux werden / lib, / usr / lib und / usr / local / lib im Allgemeinen in meinem gcc durchsucht und sind in der Standardkonfiguration von ldconfig enthalten. Wenn Sie keinen triftigen Grund haben, möchten Sie hier Ihre Bibliotheken haben. /etc/ld.so.conf kann jedoch zusätzliche Einträge auflisten.

Konfigurieren und finden Sie sie, indem Sie einfach versuchen, "gcc -l" auszuführen und nach Fehlern zu suchen. Sie können Ihrem CFLAGS-Parameter "-L" hinzufügen, um zusätzliche Suchpfade hinzuzufügen.

Sie können mehrere Versionen installieren, und Software, die mit einer älteren Version verknüpft ist, bleibt mit dieser verknüpft (führen Sie ldd aus, um die Bindung unter Linux zu ermitteln). Neue Kompilierungen zielen jedoch im Allgemeinen auf die neueste Version einer dynamischen Bibliothek auf Ihrem System ab.

Die meiste Software setzt dynamische Bibliotheken voraus, insbesondere wenn sie libtool verwendet, sodass Sie möglicherweise feststellen, dass nicht-triviale Apps statisch nicht korrekt erstellt werden.

ls -l ist die beste Wahl, um installierte Bibliotheken zu finden.

Und da habe ich keine Informationen mehr. Wie man gut mit Paketen spielt: Weiß nicht. Wenn möglich, versuche ich, die Dinge in ein Paket zu packen, um das Problem zu vermeiden.

Aaron Brady
quelle
4

"Wie finde ich heraus, welche Argumente an ./configure übergeben werden müssen?"

In der Regel: ./configure --help sagt Ihnen, was Sie dort wollen.

"Wie kann ich feststellen, welche Bibliotheken ich installiert habe und welche Versionen?"

Das hängt vom System ab. Eine Möglichkeit besteht darin, einfach eine find /|grep libname|lessBibliothek zu erstellen, die im Allgemeinen die Version im Dateinamen hat.

"Wie kann ich mehr als eine Version einer Bibliothek installieren, ohne mein normales System zu beschädigen?"

Auch hier kommt es auf das System und die Bibliothek an. sudo make altinstallerstellt einen versionierten Namen für Sie. Bibliotheksdateien versionieren sich jedoch normalerweise selbst. Denken Sie jedoch daran; Da die Versionen häufig Symlinks zu einem "normalisierten" Namen erstellen, kann dies zu Problemen führen.

"Was ist die sauberste Methode, wenn ich auf einem System, das ansonsten mit Paketen verwaltet wird, Dinge aus dem Quellcode installiere?"

Es ist empfehlenswert, die --prefix-Parameter in ./configure zu verwenden und sie irgendwo unterzubringen /opt.

Haftungsausschluss: Ich bin kein Experte, aber ich benutze Linux seit über 5 Jahren aus der cmd-Reihe (Slackware, CentOS, RedHat, Ubuntu, andere und OS X).

Phillip B. Oldham
quelle
4

Um einen Teil Ihrer Frage zu beantworten, habe ich neulich einen guten Weg gefunden, um zu sehen, welche Bibliotheken Sie installiert haben und welche Versionen (Dies ist unter Linux Debian, sollte also auch mit anderen Versionen funktionieren).

dpkg --list

Sie sollten eine wirklich lange Liste mit einer Ausgabe wie dieser erhalten

ii  libssl0.9.8    0.9.8c-4etch5  SSL shared libraries
ii  libssp0        4.1.1-21       GCC stack smashing protection library
ii  libstdc++5     3.3.6-15       The GNU Standard C++ Library v3
ii  libstdc++5-3.3 3.3.6-15       The GNU Standard C++ Library v3 (development
ii  libstdc++6     4.1.1-21       The GNU Standard C++ Library v3
Mark Davidson
quelle
4

Simon,

1.) ./configure --help liefert eine gute Menge an Informationen. Ich schlage vor, es zu überprüfen. Im Allgemeinen stehen Optionen zum Kompilieren statischer / dynamisch verknüpfter Bibliotheken zur Verfügung.

2.) Bibliotheken leben im dynamischen Linkerpfad. Dies wird normalerweise in /etc/ld.so.conf eingestellt. Der Linker sucht nach den entsprechenden Bibliotheken, ähnlich wie die Umgebungsvariable PATH, die der zuerst gefundenen entspricht.

3.) Das führt in der Regel zu Problemen, da Sie bei Änderungen einer Bibliotheksversion alles neu kompilieren müssen. Wenn Sie etwas suchen, werden Sie wahrscheinlich unzählige Gründe finden, warum statisches Verknüpfen eine schlechte Idee ist. Ich habe es so lange nicht mehr gemacht, dass ich hier nicht weiter darauf eingehen kann.

4.) Das ist etwas schwierig. Sie müssen Ihren Bibliothekspfad überprüfen, um absolut sicherzugehen. Bibliotheken haben im Allgemeinen einen symbolischen Link zu der installierten Version.

zB libssh2.so.1 -> libssh2.so.1.0.0

Im Allgemeinen verwalten Leute die Bibliotheken und Programme, die sie installieren, indem sie entweder ihre eigenen Debian-Pakete rollen oder eine andere Technik verwenden. Ich verwalte die installierte Software mit stow ( http://www.gnu.org/software/stow/ ), das sehr einfach ist und die Bibliothek über symbolische Links installiert. Ich finde es einfacher, da ich kein deb / rpm-Paket erstellen / installieren / testen muss.

5.) In Bibliotheksverzeichnissen können normalerweise mehrere Bibliotheksversionen installiert werden. Mit ausführbaren Dateien verknüpfte Bibliotheken bleiben mit den Versionen verknüpft, mit denen sie verknüpft wurden. Wenn Sie ldd auf einer ausführbaren Datei ausführen, erfahren Sie, mit welchen Bibliotheken die ausführbare Datei verknüpft ist.

6.) Wie ich bereits erwähnt habe, ist es wahrscheinlich die sauberste Lösung, eigene Debian-Pakete zu rollen oder stow zu verwenden.

7.) Ich kann nicht wirklich für Mac OS X sprechen, aber für Linux ist das Paketierungssystem der Distribution der beste Weg.

8.) Wahrscheinlich wird eine Menge Frustration gelöst, wenn Sie ldd verwenden und herausfinden, gegen welche Version etwas verlinkt ist oder welche Bibliothek, die gegen eine ausführbare Datei verlinkt ist, nicht gefunden werden kann. pkg-config wird Ihnen viel helfen, aber nur für Software, die es verwendet. Es ist nicht Teil des standardmäßigen Build-Systems für Autotools, obwohl es heutzutage sehr beliebt ist.

Ian Lewis
quelle
4

Statische Bibliotheken sind keine gute Idee - wenn Sie die Bibliothek aktualisieren müssen (um beispielsweise ein Sicherheitsproblem zu beheben), müssen Sie alles mit einer Abhängigkeit von dieser Bibliothek neu kompilieren.

Ich mag die Idee nicht, dass "make install" mein System möglicherweise in Mitleidenschaft zieht, aber wie andere gesagt haben, ist es normalerweise weitaus schmerzfreier, Dinge in / usr / local zu installieren, anstatt --prefix zu verwenden, um sie woanders zu installieren. Also habe ich / usr / local für meinen regulären (nicht privilegierten) Benutzer freigegeben. Auf diese Weise wird "make install" so gut wie garantiert nicht mit wichtigen Systemdateien in Konflikt geraten. (Dies funktioniert auf Mehrbenutzersystemen offensichtlich nicht. Es ist jedoch für virtuelle Server großartig.)

ithinkihaveacat
quelle
4

Obwohl es nicht ausdrücklich in Ihrer Fragenliste steht, erwähnen Sie in Ihrem Vorwort:

./configure && make && sudo make install ist normalerweise genug, aber manchmal funktioniert es nicht - und wenn nicht, stecke ich häufig fest.

Wenn ich auf Debian oder Ubuntu nicht weiterkomme, verwende ich auto-apt, das die Pakete, die die Dateien enthalten, die configure nicht findet, automatisch installiert.

Sehen:

Ein weiteres nützliches Tool ist CheckInstall. Es fügt make installIhrer Liste installierter Pakete Anwendungen hinzu : https://help.ubuntu.com/community/CheckInstall

Swoogan
quelle
3

Für OS X:

  • Wie finde ich heraus, welche Argumente an ./configure übergeben werden müssen?

./configure --help

  • Was sind die tatsächlichen Unterschiede zwischen einer gemeinsam genutzten und einer statisch verknüpften Bibliothek? Warum kann ich nicht einfach alles statisch verknüpfen (RAM und Festplattenspeicher sind heutzutage billig) und so seltsame Konflikte mit Bibliotheksversionen vermeiden?

Durch die Verwendung von gemeinsam genutzten Bibliotheken können Sie ein Upgrade der Bibliothek durchführen, ohne alles neu kompilieren zu müssen, was davon Gebrauch macht.

  • Wie Shared Libraries unter OS X / Linux funktionieren - wo sie sich im Dateisystem befinden, wie ./configure && make sie findet, was passiert, wenn sie miteinander verknüpft werden

Systembibliotheken befinden sich in / usr / lib.

Bibliotheken, die Sie selbst kompilieren, befinden sich in / usr / local / lib (/ usr / local ist das Standard-Präfix-Flag für ./configure).

Mit den Umgebungsvariablen DYLD_FALLBACK_LIBRARY_PATH und LD_LIBRARY_PATH können Sie angeben, in welchen Ordnern gesucht werden soll. Daher sollte sich / usr / local / lib am Anfang der Liste befinden.

  • Wie kann ich mehr als eine Version einer Bibliothek installieren, ohne mein normales System zu beschädigen?

Installieren Sie alles in / usr / local - mit den obigen Umgebungsvariablen hat die Version in / usr / local / lib Vorrang vor der Version in / usr / lib in Ihrer Umgebung.

  • Was ist die sauberste Methode, wenn ich auf einem System, das ansonsten mit Paketen verwaltet wird, Quellmaterial installiere?

Installieren Sie nach / usr / local. In Ubuntu versuche ich zuerst mit checkinstall ein Deb-Paket zu erstellen.

  • Angenommen, ich schaffe es, etwas aus dem Quellcode heraus zu kompilieren, wie kann ich das dann verpacken, damit andere Leute nicht durch dieselben Rahmen springen müssen? Besonders unter OS X ....

Dokumentieren Sie die Kompilierungsschritte in einem Blogbeitrag, würde ich sagen.

Alf Eaton
quelle