Warum sollten Makefiles ein Installationsziel haben?

18

Aus der Welt von C und C ++ stammend, haben die meisten Build-Systeme ein installZiel, insbesondere Makefiles (wo es zum Beispiel von GNU empfohlen wird ) oder CMake . Dieses Ziel kopiert die Laufzeitdateien (ausführbare Dateien, Bibliotheken usw.) im Betriebssystem (z. B. C:\Program Files\unter Windows).

Das fühlt sich wirklich abgefahren an, da es für mich nicht in der Verantwortung des Build-Systems liegt, Programme zu installieren (was eigentlich in der Verantwortung des Betriebssystems / Paketmanagers liegt). Dies bedeutet auch, dass das Build-System oder das Build-Skript die Organisation der installierten Programme mit Umgebungsvariablen, Registrierungsvariablen, Symlinks, Berechtigungen usw. kennen muss.

Build-Systeme sollten bestenfalls ein releaseZiel haben, das ein installierbares Programm ausgibt (z. B. .deboder .msi), und dann das Betriebssystem auffordern, dieses Programm zu installieren. Dies würde es dem Benutzer auch ermöglichen, zu deinstallieren, ohne etwas eingeben zu müssen make uninstall.

Meine Frage: Warum empfehlen Build-Systeme normalerweise, ein installZiel zu haben?

Synxis
quelle
7
Ihre Argumentation, dass "make install" nicht in die Verantwortung eines Build-Systems fällt, sondern die weitaus aufwändigere und plattformspezifische Verantwortung für die Erstellung eines installierbaren Pakets.
23.11.18
2
Auf jeden Fall: Manchmal möchten Sie eine Anwendung installieren, die nicht vom Betriebssystem- / Paket-Manager verwaltet wird (da Abhängigkeiten bestehen, die Konflikte verursachen, die mit dem Paket-Manager usw. nicht gelöst werden können). make installWird normalerweise unter /usr/local(oder sogar /opt) installiert, die Verzeichnisse sind, die nicht vom "Kernbetriebssystem / Paketverwaltungssystem" behandelt werden. Keine Ahnung, ob Windows eine ähnliche Konvention hat.
Bakuriu
11
"Das fühlt sich wirklich abgefahren an." Was haben Sie von der Welt von C / C ++ erwartet? ;-)
Mason Wheeler
1
Beachten Sie, make installdass dies keinen Sinn ergibt, wenn wir über Cross-Compiling sprechen
Hagen von Eitzen,
1
@HagenvonEitzen macht es mit DESTDIR.
Nax 'vi-vim-nvim' 24.11.18

Antworten:

23

Viele Build-Skripte oder Makefiles haben ein Installationsziel, da sie vor der Existenz von Paketmanagern erstellt wurden und viele Systeme auch heute noch keine Paketmanager haben. Darüber hinaus gibt es Systeme , bei denen make installtatsächlich ist der bevorzugte Weg , Pakete zu verwalten.

Jörg W. Mittag
quelle
Ich bin neugierig auf Systeme, bei denen make installbevorzugt wird. Abgesehen davon meinte ich Program Manager, als ich sagte, dass Makefiles installierbare Pakete erstellen sollten. Ich denke, fast alle Betriebssysteme haben eine Möglichkeit, die installierten Programme zu verwalten. Zum Beispiel hat Windows keinen Paketmanager (außer dem Store), kann aber trotzdem installierte Programme verwalten ( .msizum Beispiel über Pakete)
Synxis
2
@Synxis BSD, Linux, Unix verwenden alle Makefiles. Ob es bevorzugt wird, sie für die Installation zu verwenden, weiß ich nicht, aber Sie haben oft diese Fähigkeit zu verwenden make install.
Rob
1
Zumindest in Debian ist es aus zwei Gründen vorzuziehen, checkinstallover zu verwenden make install: "Sie können das Paket einfach mit einem Schritt entfernen." und "Sie können das resultierende Paket auf mehreren Computern installieren." - während checkinstall eine .deb erstellt und installiert, benutzt es den Paketmanager ...
Aaron Hall
1
@Synxis - Es gibt verschiedene Linux-Distributionen (oft als Quelldistributionen bezeichnet), bei denen der Paketmanager Programme durch Herunterladen einer make install
TAR-
1
@AaronHall Korrigieren Sie mich, wenn ich falsch liege, aber ich hatte den Eindruck, dass ein checkinstallAufruf tatsächlich seine Aktionen für die Paketerstellung verwendet make install und überwacht.
cmaster
5

A hat makefilemöglicherweise kein installZiel, und was noch wichtiger ist, Sie können Programme haben, von denen nicht einmal angenommen wird, dass sie installierbar sind (z. B. weil sie von ihrem Build-Verzeichnis ausgeführt werden sollen oder weil sie überall installiert werden können). Das installZiel ist nur eine Konvention für übliche makefile-s.

Viele Programme erfordern jedoch die Ausführung externer Ressourcen (z. B. Schriftarten, Datenbanken, Konfigurationsdateien usw.). Und ihre ausführbare Datei macht oft eine Hypothese über diese Ressourcen. Zum Beispiel IhrDeterm bashwürde Shell im Allgemeinen eine Initialisierungsdatei aus lesen /etc/bash.bashrcetc .... Diese Ressourcen im Allgemeinen in dem Dateisystem (siehe hier (7) für die Konventionen über die Dateihierarchie) und das Standarddateipfad wird in der ausführbaren Datei aufgebaut.

Versuchen Sie, Strings (1) für die meisten ausführbaren Dateien Ihres Systems zu verwenden. Sie erfahren, welche Dateipfade ihm bekannt sind.

Übrigens, für viele GNU-Programme autoconf, die Sie verwenden, könnten Sie make install DESTDIR=/tmp/destdir/ohne root laufen . Dann /tmp/destdir/wird mit den Dateien gefüllt, die später gepackt werden sollen.

FWIW, ich neige dazu zu glauben, dass mein Bismon- Programm (GPLv3 + lizenziert) (beschrieben in meinem Bismon-Wagen-Dok.pdf- Bericht) nicht "installiert" werden kann; Ich bin mir nicht sicher, ob ich das beweisen kann, und ich kann mir nicht vorstellen, wie ich das Programm installierbar machen kann.

Basile Starynkevitch
quelle
2
DESTDIR oder andere Präfixe werden zu oft vergessen. Sobald externe Ressourcen wie dynamische Bibliotheken beteiligt sind, ist es nicht möglich , die Software zu erstellen, ohne zu wissen, wo sie installiert werden soll . Ideal auch für die Installation an nicht standardmäßigen Orten, z . B. /optoder in $HOME. Die einzige Möglichkeit, unterschiedliche Präfixe zu vermeiden, besteht in der Verwendung von Containern. Dies ist natürlich eine Linux-spezifische Lösung.
amon
2
Ich habe mehr als ein Paket gesehen, das, wenn Sie DESTDIR = / tmp / destdir ausprobiert haben, später nicht funktioniert, wenn es an der normalen Stelle installiert wird, da DESTDIR bei der Pfadgenerierung verwendet wurde.
Joshua
@amon: Ich bin mir nicht sicher, ob ich Container als Linux-spezifisch bezeichnen würde. Linux mag eine gemeinsame Zielplattform für die Containerisierung sein, aber in den meisten modernen Betriebssystemen gibt es eine Form der Containertechnologie .
Kevin
1
@Joshua Das sollte nicht so sein, DESTDIR sollte nur während des Installationsschritts relevant sein. Sie sollten in der Lage sein: ./configure --prefix="/opt/foo" && make && DESTDIR=/tmp/foo make install und in der Lage sein, das Paket /opt/fooohne Probleme an einen anderen Ort zu verschieben.
Nax 'vi-vim-nvim' 24.11.18
3

Es gibt mehrere Gründe, die mir in den Sinn kommen.

  • Viele Software zur Paketerstellung - zum Beispiel das Debian- Build-System und IIRC-RPM - erwarten bereits vom Build-Skript, dass sie das Programm in einem bestimmten Unterverzeichnis "installieren". Es wird also durch Abwärtskompatibilität in beide Richtungen angetrieben.
  • Ein Benutzer möchte die Software möglicherweise in einem lokalen Bereich wie dem $HOMEVerzeichnis installieren . Nicht alle Paketmanager unterstützen dies.
  • Möglicherweise gibt es noch Umgebungen ohne Pakete.
max630
quelle
Ich habe die Frage ein wenig umformuliert, ich meinte Programmmanager, als ich sagte, dass Makefiles installierbare Pakete erstellen sollten.
Synxis
1

Ein Grund, der nicht erwähnt wird, ist, dass Sie häufig nicht die aktuelle Version der Software oder eine geänderte Version der Software verwenden. Der Versuch, ein benutzerdefiniertes Paket zu erstellen, ist nicht nur aufwändiger, sondern kann auch zu Konflikten mit derzeit erstellten und verteilten Paketen führen. Im Open-Source-Code geschieht dies häufig, insbesondere wenn in zukünftigen Versionen, die Sie verwenden, wichtige Änderungen vorgenommen werden.

Angenommen, Sie verwenden das Open Source-Projekt FOO, das sich derzeit in Version 2.0.1 befindet, und Sie verwenden Version 1.3.0. Sie möchten darüber hinaus nichts weiter verwenden, da die Version 2.0.0 nicht mit dem kompatibel ist, was Sie gerade tun. In 2.0.1 gibt es jedoch eine einzige Fehlerkorrektur, die Sie dringend benötigen. Mit dieser make installOption können Sie die geänderte 1.3.0-Software installieren, ohne ein Paket erstellen und auf Ihrem System installieren zu müssen.

Dom
quelle
1

Linux-Distributionen trennen die Programmwartung im Allgemeinen von der Paketwartung. Ein Build-System, das die Paketerstellung integriert, würde Programmbetreuer dazu zwingen, auch die Paketverwaltung durchzuführen.

Dies ist normalerweise eine schlechte Idee. Distributionen verfügen über eine umfangreiche Infrastruktur zur Überprüfung der internen Konsistenz, zur Bereitstellung von Binärdateien für mehrere Zielplattformen, zur Durchführung kleiner Änderungen zur besseren Integration mit dem Rest des Systems und zur Bereitstellung einer konsistenten Erfahrung für Benutzer, die Fehler melden.

Um Pakete direkt aus einem Build-System zu generieren, müssten Sie diese gesamte Infrastruktur entweder integrieren oder umgehen. Die Integration wäre eine Menge Arbeit für fragwürdigen Nutzen, und die Umgehung würde zu einer schlechteren Benutzererfahrung führen.

Dies ist eines der "Top of the Food Chain" -Probleme, die für Mehrparteiensysteme typisch sind. Wenn Sie mehrere komplexe Systeme haben, muss es eine klare Hierarchie geben, welches System für die Koordination aller anderen verantwortlich ist.

Im Falle der Softwareinstallationsverwaltung ist der Paketmanager diese Komponente. Er führt das Build-System des Pakets aus und führt die Ausgabe über eine praktische Schnittstelle ("Dateien in einem Verzeichnis nach einem Installationsschritt") aus, generiert ein Paket und bereitet es vor es zum Hochladen in ein Repository.

Der Paketmanager steht hier in der Mitte zwischen dem Build-System und dem Repository und ist in der besten Position, um sich gut in beide zu integrieren.

Möglicherweise haben Sie bemerkt, dass nur wenige der über npmverfügbaren JavaScript-Pakete auch über verfügbar sind. aptDies liegt hauptsächlich daran, dass sich die JavaScript-Benutzer dafür entschieden haben npmund das zugehörige Repository an der Spitze ihrer Nahrungskette stehen sollte, was es nahezu unmöglich machte Versenden Sie diese Pakete als Debian-Pakete.

Mit meinem Debian-Entwickler-Hut auf: Wenn Sie Open Source-Software freigeben, überlassen Sie die Verpackung bitte den Betreuern der Distribution. Das erspart Ihnen und uns viel Arbeit.

Simon Richter
quelle
Sie haben nichts darüber gesagt, warum es ein Installationsziel gibt, und es scheint mir, dass das meiste, was Sie geschrieben haben, auch darauf zutrifft ...
curiousdannii
1
@curiousdannii muss es sein , einige Schnittstelle zwischen Build - System und Paket - Manager, und dies geschieht am einfachsten zu sein, so dass er gewonnen.
Simon Richter
1

Nun, Anwendungsentwickler sind diejenigen, die wissen, wohin jede Datei gehen soll. Sie könnten das in der Dokumentation belassen und die Paketbetreuer das lesen lassen und ein Skript für jedes Paket erstellen. Möglicherweise interpretieren die Paketbetreuer die Dokumentation falsch und müssen das Skript debuggen, bis es funktioniert. Das ist ineffizient. Für den Anwendungsentwickler ist es besser, ein Skript zu schreiben, um die von ihm geschriebene Anwendung ordnungsgemäß zu installieren.

Er könnte ein Installationsskript mit einem beliebigen Namen schreiben oder es zum Teil der Prozedur eines anderen Skripts machen. Mit einem Standardinstallationsbefehl make install(eine Konvention vor Paketmanagern) ist es jedoch wirklich einfach geworden, Pakete zu erstellen. Wenn Sie sich die PKGBUILD-Vorlage für die Erstellung von Archlinux-Paketen ansehen , können Sie feststellen, dass die Funktion, mit der tatsächlich Pakete erstellt werden, einfach a ausführtmake DESTDIR="$pkgdir/" install . Dies funktioniert wahrscheinlich für die meisten Pakete und wahrscheinlich auch für mehr mit einer kleinen Änderung. Dank makedem Standard (und den Autowerkzeugen) ist das Verpacken wirklich sehr einfach.

JoL
quelle