Pourquoi utiliser make over un script shell?

129

Make me semble simplement un script shell avec une gestion un peu plus facile des arguments de ligne de commande.

Pourquoi est-il standard d'exécuter make au lieu de ./make.sh

HoboBen
la source
pour la question inverse: pourquoi utiliser le script shell sur make (en raison de la manipulation apparemment plus facile des arguments de ligne de commande), en particulier pour les tâches d'administrateur système, lisez ici: unix.stackexchange.com/a/497601/1170
lesmana

Réponses:

126

L'idée générale est que makeprend en charge les reconstructions (raisonnablement) minimales - c'est-à-dire que vous lui dites quelles parties de votre programme dépendent de quelles autres parties. Lorsque vous mettez à jour une partie du programme, il ne reconstruit que les parties qui en dépendent. Bien que vous puissiez le faire avec un script shell, ce serait beaucoup plus de travail (vérifier explicitement les dates de dernière modification sur tous les fichiers, etc.) La seule alternative évidente avec un script shell est de tout reconstruire à chaque fois. Pour les petits projets, c'est une approche parfaitement raisonnable, mais pour un grand projet, une reconstruction complète pourrait facilement prendre une heure ou plus - en utilisant make, vous pourriez facilement accomplir la même chose en une minute ou deux ...

Je devrais probablement aussi ajouter qu'il y a pas mal d'alternatives à faire qui ont au moins des capacités largement similaires. Surtout dans les cas où seuls quelques fichiers d'un grand projet sont en cours de reconstruction, certains d'entre eux (par exemple, Ninja ) sont souvent considérablement plus rapides que make.

Jerry Coffin
la source
67

Make est un système expert

Il y a diverses choses qui sont difficiles à faire avec les scripts shell ...

  • Bien sûr, il vérifie ce qui est obsolète, afin de ne construire que ce dont il a besoin pour construire
  • Il effectue un tri topologique ou une autre sorte d'analyse d'arborescence qui détermine ce qui dépend de quoi et de quel ordre pour construire les éléments obsolètes de sorte que chaque prérequis soit construit avant chaque dépendance, et une seule fois.
  • C'est un langage de programmation déclarative . De nouveaux éléments peuvent être ajoutés sans avoir besoin de les fusionner dans un flux de contrôle impératif.
  • Il contient un moteur d'inférence pour traiter les règles, les modèles et les dates, et cela, lorsqu'il est combiné avec les règles de votre Makefile particulier, est ce qui transforme en un système expert .
  • Il dispose d'un processeur macro.
  • Voir aussi: un précédent résumé de make .
DigitalRoss
la source
2
Il est cependant assez limité en tant que système expert. Par exemple, chaque inférence ne peut utiliser la même règle qu'une seule fois.
reinierpost le
1
Juste pour élaborer sur le point 2) en termes d'ingénierie plus profanes, un script shell applique un ordre linéaire, alors qu'un makefile ressemble à un arbre. Il supprime les dépendances chronologiques inutiles (bien qu'en pratique le processus de création soit exécuté de manière linéaire).
Sridhar Sarnobat
2
... Je pense que le problème avec Makefiles sur les scripts shell est analogue au problème avec CSS sur javascript. L'ordre chronologique dans lequel chaque nœud est exécuté n'est pas aussi évident. Bien qu'au moins avec Makefiles, vous pouvez toujours voir la commande shell réelle. Avec CSS, même cela est abstrait.
Sridhar Sarnobat
J'ai quelques commentaires que j'apprécie si quelqu'un les clarifie. 1 / Votre premier et vos deux points ne sont-ils pas liés, dans le sens où ce tri topologique est la manière dont la construction incrémentale est implémentée? 2 / ne pouvez-vous pas également mettre en œuvre le point numéro 3 en utilisant la composition de fonctions. 3 / Je voudrais en savoir plus sur les avantages du 4 et du 5 pour l'utilisateur final de MakeFile, et pourquoi ces avantages ne peuvent pas être mis en œuvre en composant ensemble des commandes shell
Amine Hajyoussef
C'est la première fois que je rencontre Make décrit comme un système expert. En tant que personne qui a construit des systèmes experts, ce n'est pas quelque chose que j'aurais envisagé. Make a évidemment un moteur d'inférence pour déduire comment construire votre programme à travers les règles déclaratives spécifiées dans le makefile, mais il est moins évident qu'il s'agit d'un système basé sur la connaissance puisque les règles (feuille) sont des commandes shell à exécuter plutôt que des faits. Et le terme «système expert» est utilisé pour désigner un système qui a réussi à capter l'expertise d'un expert de classe mondiale, ce qui n'est pas le cas. Le jury est toujours dehors pour moi.
Dennis
9

Make garantit que seuls les fichiers requis sont recompilés lorsque vous apportez des modifications à vos fichiers source.

Par exemple:

final : 1.o 2.o
    gcc -o final 1.o 2.o

1.o : 1.c 2.h
    gcc -c 1.c

2.o : 2.c 2.h
    gcc -c 2.c

Si je change le fichier 2.huniquement et que makeje l'exécute, il exécute toutes les 3 commandes, dans l'ordre inverse.

Si je change le fichier 1.cuniquement et que je l' exécute make, il n'exécute que les 2 premières commandes dans l'ordre inverse.

Essayer d'accomplir cela avec votre propre script shell impliquera de nombreuses if/elsevérifications.

Chris Dodd
la source
ou utilisez quelque chose comme ça rsync -r -c -I $SOURCE $DEST_DIRdans shell.
Spartacus9
9

En plus de ce qui précède, Make est un langage de programmation parallèle déclaratif (-ish).

Disons que vous avez 4 000 fichiers graphiques à convertir et 4 processeurs. Essayez d'écrire un script shell de 10 lignes (je suis généreux ici) qui le fera de manière fiable tout en saturant vos processeurs.

Peut-être que la vraie question est de savoir pourquoi les gens prennent la peine d'écrire des scripts shell.

bobbogo
la source
1
Oui, vous assouplissez l'ordre linéaire total en un ordre plus arborescent.
Sridhar Sarnobat
4

make gère les dépendances: le makefile les décrit: le binaire dépend des fichiers objets, chaque fichier objet dépend d'un fichier source et des en-têtes ... lorsque make est exécuté, la date des fichiers est comparée pour déterminer ce qui doit être recompilé .

On peut invoquer directement une cible pour ne pas construire tout ce qui est décrit dans le Makefile.

De plus, la syntaxe make fournit une substitution, vpath

Tout cela peut être écrit dans des scripts shell, avec make vous l'avez déjà.

philant
la source