Venant du monde du C et du C++, la plupart des systèmes de build ont une cible install
, notamment Makefiles (où il est recommandé par GN par exemple) ou CMake . Cette cible copie les fichiers d'exécution (exécutables, bibliothèques, ...) dans le système d'exploitation (par exemple, dans C:\Program Files\
sous Windows).
Cela semble vraiment hacky, car pour moi ce n'est pas la responsabilité du système de construction d'installer des programmes (qui est en fait la responsabilité du système d'exploitation/package directeur). Cela signifie également que le système de construction ou le script de construction doit connaître l'organisation des programmes installés, avec les variables d'environnement, les variables de registre, les liens symboliques, les autorisations, etc.
Au mieux, les systèmes de construction devraient avoir une cible release
qui produira un programme installable (par exemple .deb
ou .msi
), puis demandez au système d'exploitation d'installer ce programme. Cela permettrait également à l'utilisateur de désinstaller sans avoir à taper make uninstall
.
Donc, ma question: pourquoi le système de construction recommande-t-il généralement d'avoir une cible install
?
De nombreux scripts de construction ou Makefiles ont une cible d'installation car ils ont été créés avant que les gestionnaires de packages n'existent et parce qu'aujourd'hui encore de nombreux systèmes n'ont pas de gestionnaires de packages. De plus, il existe des systèmes où make install
en fait est la manière préférée de gérer les packages.
Un makefile
peut ne pas avoir de cible install
, et plus important encore, vous pouvez avoir des programmes qui ne sont même pas censés être installables (par exemple parce qu'ils doivent s'exécuter à partir de leur répertoire de construction, ou parce qu'ils peuvent s'exécuter installé n'importe où). La cible install
n'est qu'une convention pour les makefile
- s habituels.
Cependant, de nombreux programmes nécessitent l'exécution de ressources externes (par exemple: polices, bases de données, fichiers de configuration, etc.). Et leur exécutable fait souvent des hypothèses sur ces ressources. Par exemple, votre shell bash
lit généralement un fichier d'initialisation à partir de /etc/bash.bashrc
etc .... Ces ressources sont généralement dans le système de fichiers (voir hier (7) pour les conventions sur le hiérarchie des fichiers) et le chemin du fichier par défaut est construit dans votre exécutable.
Essayez d'utiliser strings (1) sur la plupart des exécutables de votre système. Vous découvrirez quels chemins de fichiers lui sont connus.
BTW, pour de nombreux programmes GNU utilisant autoconf
, vous pouvez exécuter make install DESTDIR=/tmp/destdir/
sans être root. Alors /tmp/destdir/
est rempli avec les fichiers qui devraient être mis en package ultérieurement.
FWIW, j'ai tendance à croire que mon programme bismon (sous licence GPLv3 +) (décrit dans mon rapport bismon-chariot-doc.pdf ) ne peut pas être "installé"; Je ne suis pas sûr de pouvoir le prouver et je ne peux pas imaginer comment rendre ce programme installable.
Il y a plusieurs raisons qui me viennent à l'esprit.
$HOME
répertoire. Tous les gestionnaires de packages ne le prennent pas en charge.Eh bien, les développeurs d'applications sont ceux qui savent où chaque fichier doit aller. Ils pourraient laisser cela dans la documentation et demander aux mainteneurs de paquet de le lire et de construire un script pour chaque paquet. Peut-être que les responsables du paquet interpréteront mal la documentation et devront déboguer le script jusqu'à ce qu'il fonctionne. C'est inefficace. Il est préférable que le développeur de l'application écrive un script pour installer correctement l'application qu'il a écrite.
Il pourrait écrire un script d'installation avec un nom arbitraire ou peut-être l'intégrer à la procédure d'un autre script. Cependant, ayant une commande d'installation standard, make install
(une convention qui précède les gestionnaires de packages), il est devenu très facile de créer des packages. Si vous regardez le modèle PKGBUILD pour faire des paquets Archlinux , vous pouvez voir que la fonction qui empaquette fait simplement un make DESTDIR="$pkgdir/" install
. Cela fonctionne probablement pour la majorité des packages et probablement plus avec une petite modification. Grâce à make
(et aux outils automatiques) étant standard, le packaging est vraiment, vraiment facile.
Une raison non mentionnée est qu'il y a de nombreuses fois où vous n'utilisez pas la version actuelle du logiciel ou utilisez une version modifiée du logiciel. Essayer de créer un package personnalisé est non seulement plus de travail, mais il peut entrer en conflit avec les packages actuellement créés et distribués. Dans le code open source, cela se produit souvent, surtout si des changements de rupture sont introduits dans les futures versions que vous utilisez.
Supposons que vous utilisez le projet open source FOO qui est actuellement sur la version 2.0.1 et que vous utilisez la version 1.3.0. Vous ne voulez pas utiliser quoi que ce soit au-dessus de cela parce que la version 2.0.0 est incompatible avec ce que vous faites actuellement, mais il y a une seule correction de bogue dans 2.0.1 dont vous avez désespérément besoin. Avoir le make install
L'option vous permet d'installer le logiciel 1.3.0 modifié sans avoir à vous soucier de créer un package et de l'installer sur votre système.
Les distributions Linux séparent généralement la maintenance des programmes de la maintenance des packages. Un système de construction qui intègre la génération de packages obligerait les responsables de programme à effectuer également la maintenance des packages.
C'est généralement une mauvaise idée. Les distributions disposent de nombreuses infrastructures pour vérifier la cohérence interne, fournir des fichiers binaires pour plusieurs plates-formes cibles, effectuer de petites modifications pour mieux s'intégrer au reste du système et fournir une expérience cohérente aux utilisateurs signalant des bogues.
Pour générer des packages directement à partir d'un système de génération, vous devez soit intégrer, soit contourner toute cette infrastructure. L'intégrer représenterait beaucoup de travail pour un bénéfice discutable, et le contourner donnerait une expérience utilisateur pire.
Il s'agit de l'un des problèmes les plus fréquents de la chaîne alimentaire dans les systèmes multipartites. Si vous avez plusieurs systèmes complexes, il doit y avoir une hiérarchie claire de quel système est responsable de la coordination de tous les autres.
Dans le cas de la gestion de l'installation du logiciel, le gestionnaire de package est ce composant, et il exécutera le système de construction du package, puis prendra la sortie via une interface pratique ("fichiers dans un répertoire après une étape d'installation"), générera un package et préparera pour le télécharger dans un référentiel.
Le gestionnaire de packages se trouve au milieu entre le système de construction et le référentiel ici, et est le mieux placé pour bien s'intégrer aux deux.
Vous avez peut-être remarqué que seuls quelques packages JavaScript sont disponibles via npm
également disponibles via apt
- c'est principalement parce que les gens de JavaScript ont décidé que npm
et le référentiel associé allait être le sommet de leur chaîne alimentaire, ce qui rendait presque impossible l'envoi de ces paquets en tant que paquets Debian.
Avec mon chapeau de développeur Debian allumé: si vous publiez un logiciel open source, veuillez laisser le paquetage aux responsables de la distribution. Cela vous fait économiser beaucoup de travail à vous et à nous.