Pourquoi les makefiles devraient-ils avoir une cible «installer»?

18

Venant du monde du C et du C ++, la plupart des systèmes de build ont une installcible, notamment Makefiles (où il est recommandé par GNU par exemple) ou CMake . Cette cible copie les fichiers d'exécution (exécutables, bibliothèques, ...) dans le système d'exploitation (par exemple, sous C:\Program Files\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 / gestionnaire de packages). 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 doivent avoir une releasecible qui produira un programme installable (par exemple .debou .msi), puis demandera 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 installcible?

Synxis
la source
7
Votre argument selon lequel "make install" ne relève pas de la responsabilité d'un système de build, mais c'est la responsabilité beaucoup plus impliquée et spécifique à la plate-forme de créer un package installable.
pmf
2
Quoi qu'il en soit: vous souhaitez parfois installer une application qui n'est pas gérée par le système d'exploitation / gestionnaire de packages (car elle présente des dépendances qui pourraient entraîner des conflits impossibles à résoudre à l'aide du gestionnaire de packages, etc.). make installinstalle généralement sous /usr/local(ou même /opt) des répertoires qui ne sont pas gérés par le "système de gestion du système d'exploitation / du noyau". Je ne sais pas si Windows a une convention similaire.
Bakuriu
11
"Cela semble vraiment hacky." Eh bien, qu'attendiez-vous du monde du C / C ++? ;-)
Mason Wheeler
1
Notez que make installcela n'a aucun sens lorsque nous parlons de compilation croisée
Hagen von Eitzen
1
@HagenvonEitzen il le fait avec DESTDIR.
Nax 'vi-vim-nvim'

Réponses:

23

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 ne disposent pas de gestionnaires de packages. De plus, il existe des systèmes où estmake install en fait la façon préférée de gérer les packages.

Jörg W Mittag
la source
Je suis curieux de savoir quels systèmes make installsont préférés. En dehors de cela, je voulais dire gestionnaire de programme quand j'ai dit que les makefiles devraient créer des packages installables. Je pense que presque tous les OS sont livrés avec un moyen de gérer les programmes installés? Par exemple, Windows n'a pas de gestionnaire de packages (en dehors du magasin) mais a toujours un moyen de gérer les programmes installés (via des .msipackages pour des exemples)
Synxis
2
@Synxis BSD, Linux, Unix utilisent tous des makefiles. S'il est préférable de les utiliser pour l'installation, je ne sais pas, mais vous avez souvent cette capacité à utiliser make install.
Rob
1
Dans debian au moins, il est préférable d'utiliser checkinstallover make installpour deux raisons: "Vous pouvez facilement supprimer le paquet en une seule étape." et "Vous pouvez installer le package résultant sur plusieurs machines." - comme checkinstall construit un .deb et l'installe, il utilise le gestionnaire de paquets ...
Aaron Hall
1
@Synxis - Il existe plusieurs distributions linux (souvent appelées sources) où le gestionnaire de paquets installe des programmes en téléchargeant un fichier tar, le décompresse puis l'exécutemake install
slebetman
1
@AaronHall Corrigez-moi si je me trompe, mais j'ai l'impression qu'une checkinstallinvocation utilisera make install et surveillera ses actions pour la construction de packages.
cmaster - réintègre monica
5

Un makefilepeut ne pas avoir de installcible, et plus important encore, vous pouvez avoir des programmes qui ne sont même pas censés être installables (par exemple, car ils devraient s'exécuter à partir de leur répertoire de construction, ou parce qu'ils peuvent s'exécuter installés n'importe où). La installcible 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 bashshell devrait généralement lire un fichier d'initialisation à partir de /etc/bash.bashrcetc .... Ces ressources sont généralement dans le système de fichiers (voir hier (7) pour les conventions sur la hiérarchie des fichiers) et le chemin du fichier par défaut est construit dans votre exécutable.

Essayez d'utiliser des chaînes (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. Puis /tmp/destdir/est rempli les fichiers qui devraient être plus tard emballés.

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.

Basile Starynkevitch
la source
2
DESTDIR ou d'autres préfixes sont trop souvent oubliés. Dès que des ressources externes telles que des bibliothèques dynamiques sont impliquées, il n'est pas possible de construire le logiciel sans savoir où il sera installé . Idéal également pour l'installation dans des emplacements non standard, par exemple /optou dans $HOME. La seule façon d'éviter différents préfixes est d'utiliser des conteneurs, mais c'est bien sûr une solution spécifique à Linux.
amon
2
J'ai vu plus d'un paquet qui, si vous essayiez DESTDIR = / tmp / destdir, ne fonctionnerait pas plus tard lorsqu'il serait installé à l'endroit normal car DESTDIR a été utilisé dans la génération du chemin.
Joshua
@amon: Je ne suis pas sûr de caractériser les conteneurs comme étant spécifiques à Linux. Linux peut être une plate-forme cible commune pour la conteneurisation, mais une certaine forme de technologie de conteneur existe dans la plupart des systèmes d'exploitation modernes.
Kevin
1
@Joshua Ce ne devrait pas être le cas, DESTDIR ne devrait être pertinent que pendant l'étape d'installation. Vous devriez pouvoir faire: ./configure --prefix="/opt/foo" && make && DESTDIR=/tmp/foo make install et pouvoir déplacer le package vers /opt/foosans aucun problème.
Nax 'vi-vim-nvim'
3

Il y a plusieurs raisons qui me viennent à l'esprit.

  • De nombreux logiciels de création de paquets - le système de construction Debian par exemple, et le rpm IIRC également - attendent déjà du script de construction "d'installer" le programme dans un sous-répertoire spécial. Il est donc motivé par une compatibilité descendante dans les deux sens.
  • Un utilisateur peut souhaiter installer le logiciel sur un espace local, comme dans le $HOMErépertoire. Tous les gestionnaires de packages ne le prennent pas en charge.
  • Il peut toujours y avoir des environnements qui n'ont pas de packages.
max630
la source
J'ai reformulé la question un peu, je voulais dire gestionnaire de programme quand j'ai dit que les makefiles devraient créer des packages installables.
Synxis
1

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 un seul correctif de bogue dans 2.0.1 dont vous avez désespérément besoin. Cette make installoption 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.

Dom
la source
1

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é qu'il n'y a que quelques-uns des packages JavaScript disponibles via npmégalement disponibles via apt- c'est principalement parce que les gens JavaScript l'ont décidé npmet que le référentiel associé allait être le haut de leur chaîne alimentaire, ce qui l'a rendu presque impossible à expédiez ces paquets en tant que paquets Debian.

Avec mon chapeau de développeur Debian allumé: si vous publiez un logiciel open source, veuillez laisser l'emballage aux responsables de la distribution. Cela vous fait économiser beaucoup de travail à vous et à nous.

Simon Richter
la source
Vous n'avez rien dit sur la raison pour laquelle il y a une cible d'installation, et il me semble que la plupart de ce que vous avez écrit s'appliquerait également à elle ...
curiousdannii
1
@curiousdannii, il doit y avoir une interface entre le système de construction et le gestionnaire de paquets, et cela se trouve être le plus simple, donc il a gagné.
Simon Richter
1

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 créer 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, avec 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 fait réellement les paquets 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, l'emballage est vraiment, vraiment facile.

JoL
la source