Pourquoi les outils de construction utilisent-ils un langage de script différent du langage de programmation sous-jacent?

23

J'ai récemment utilisé des outils de construction pour un projet Nodejs au travail lorsque j'ai réalisé que la plupart des outils / systèmes de construction principaux utilisent un langage différent du langage de programmation sous-jacent lui-même.

Par exemple, make n'utilise pas C ou C ++ pour écrire des scripts et ant (ni Maven) n'utilise pas Java comme langage de script.

Les langages plus récents comme Ruby utilisent le même langage pour construire des outils comme rake , ce qui est logique pour moi. Mais pourquoi cela n'a-t-il pas toujours été le cas? Quel est l'avantage d'avoir un outil de construction qui utilise une langue différente de la langue sous-jacente?

joshin4colours
la source
14
Peut-être que le langage à usage général n'est pas assez adapté à l'utilisation spécialisée de l'outil? Par exemple, je ne voudrais pas écrire des fichiers make en C! Parfois, une DSL est meilleure.
Andres F.
13
Regardez-le sous un autre angle: pourquoi ne pas utiliser make pour écrire des logiciels d'application?
whatsisname
4
Cet article traite principalement de ce que l'auteur pense faire de Lisp, mais contient des informations pertinentes sur les raisons pour lesquelles Ant utilise XML au lieu de Java.
8bittree
6
Si vous vouliez écrire un programme en C qui automatise la construction de programmes C, ne finiriez-vous pas par makerecommencer à écrire (qui est quand même implémenté en C)?
Brandin
6
@ joshin4colours make est écrit en C. Le langage qui utilise, cependant, est un langage déclaratif qui invoque le shell selon les besoins.

Réponses:

36

Le choix du langage de programmation à utiliser pour accomplir quelque chose doit dépendre des caractéristiques spécifiques de cet objectif et non des autres tâches liées à ce projet.

Un outil de construction fait un travail très spécifique, et quelle que soit la langue que vous utilisez pour le projet principal, un outil de construction est un logiciel en soi.

Essayer de lier le projet principal et son outil de construction pourrait être une très mauvaise décision. Ce dont vous avez besoin avec un outil de construction est principalement un processus rapide de règles simples, avec une gestion rapide des fichiers et des E / S.

Si des langues comme ruby ​​utilisent elles-mêmes pour implémenter leur outil de construction, elles sont davantage liées aux caractéristiques de cette langue qu'à la nécessité supposée de tout conserver écrit dans la même langue.

Nicolás
la source
18

Il n'est pas impossible d'écrire un outil de construction qui utilise un langage tel que C ou Java comme langage de script. Cependant, les outils de génération bénéficient de l'utilisation de langages de script plus déclaratifs . Imaginez la douleur et le passe-partout de l'écriture d'un makefile (ou build.xml, ou autre) en C.

Les outils de construction bénéficient de l'utilisation des DSL, une tâche pour laquelle C n'est pas un choix particulièrement bon. C est trop général pour un outil de construction et trop préoccupé par les détails sujets aux erreurs et de bas niveau. Par exemple, vous ne voulez pas vous préoccuper de la gestion explicite de la mémoire dans un outil de construction! Donc, même si vous utilisez une syntaxe de type C, vous utiliserez probablement la récupération de place dans votre outil de script, à quel point pourquoi ne pas simplement utiliser un DSL dédié?

Il est logique que Ruby puisse être utilisé pour cela, car il s'agit d'un langage de niveau supérieur et plus déclaratif que C ou Java. Voir aussi: Gradle, sbt.

Andres F.
la source
13
Imagine the pain and boilerplate of writing a makefile (or build.xml, or whatever) in C.Imaginez la douleur et le gâchis d'essayer d'exprimer une logique conditionnelle non triviale (vous savez, des choses impératives standard) dans un script XML déclaratif. Oh, attendez, vous n'avez pas besoin d'imaginer; vous avez probablement dû y faire face, et c'était probablement un gâchis et demi, n'est-ce pas? Les builds sont l'un des pires choix possibles pour un langage de script déclaratif, car de graves problèmes finissent rapidement par se heurter aux limites de la déclaration-ness, et ceux qui ne sont pas assez simples pour ne pas avoir besoin d'un outil de build.
Mason Wheeler
7
@MasonWheeler Il y a des cas où les outils de build existants m'ont fait souffrir, oui. Aucun d'eux n'aurait été aidé en utilisant un langage impératif de type C de bas niveau. Je vois quelque chose comme Ruby comme probablement idéal: suffisamment déclaratif et impératif, au besoin. C me donnerait des cauchemars pour cette tâche. Pour moi, les systèmes de construction sont un bon cas d'utilisation pour les DSL déclaratifs (principalement): vous vous souciez de ce qu'il faut faire, pas de la façon de le faire (la plupart du temps).
Andres F.
2
C'est suffisant. J'ai toujours pensé que C est l'une de ces technologies «si X est la réponse, vous posez la mauvaise question», pour être parfaitement honnête; c'est juste que travailler avec des "scripts" XML a été un cauchemar à chaque fois que j'en ai plongé un. Je suis d'accord qu'un langage impératif de niveau supérieur avec des capacités DSL serait idéal.
Mason Wheeler
@AndresF .: Des choses comme créer des fichiers nécessitent un mélange d'approches. L'état de sortie souhaité est spécifié de manière déclarative, mais les actions nécessaires pour atteindre cet état sont spécifiées impérativement.
supercat
1
@MasonWheeler Je pense que c'est autant un problème pour les personnes qui ont conçu le langage de configuration que XML lui-même. L'erreur courante des auteurs de ces langages est de supposer que, simplement parce que quelque chose est en XML, il sera automatiquement lisible par l'homme. (Je sais que j'ai fait cette erreur plus de fois que je ne suis pas à l'aise. C'est tellement tentant.) Un langage de configuration bien conçu et allégé peut fonctionner aussi bien sur XML que sous toute autre forme.
biziclop
12

Donnons-nous un exemple du monde réel.

Il y a environ 15 ans, j'ai travaillé sur le portage d'un grand système écrit en C d'Unix vers Windows, il s'agissait d'environ 3 millions de lignes de code. Pour vous donner une idée de l'échelle, il a fallu plus de 24 heures pour compiler sur certains de nos systèmes Unix (RS6000), Windows pourrait compiler le système en environ 4 heures.

(Nous avions également 2 millions de lignes de code dans notre propre langage interprété, mais avons décidé de ne pas utiliser notre langage pour les systèmes de génération car il n'a jamais été conçu pour le traitement de fichiers. Nous avions également besoin d'un système de génération pour compiler le code C qui implémentait notre langue .)

Au moment où le système de construction était écrit dans un mélange de scripts shell et de création de fichiers, ceux-ci n'étaient pas portables sur Windows - nous avons donc décidé d'écrire notre propre système de construction.

Nous aurions pu utiliser C, mais nous avons décidé d'utiliser python, il y avait peu de raisons. (Nous avons également réécrit notre système de contrôle de code source en python en même temps, il était très intergradé avec le système de construction, donc les fichiers objets pour les modules archivés pouvaient être partagés par les développeurs.)

  • La plupart de notre code a pu être construit avec quelques règles simples (seulement quelques milliers de lignes de python pour toutes les plates-formes, Windows, VMS et 6 versions d'Unix) dérivées des conventions de dénomination des fichiers.

  • À l'époque, RegEx n'était pas très standard entre les systèmes C sur différentes plates-formes, Python avait intégré RegEx.

  • Quelques modules nécessitaient des étapes de construction personnalisées, Python permettait le chargement dynamique des fichiers de classe. Nous avons autorisé l'utilisation d'une classe personnalisée pour construire un module (lib), basée sur le fait d'avoir le fichier python avec un nom magique dans le dossier. C'était la principale raison d'utiliser python.

  • Nous avons considéré Java, mais il n'était pas disponible sur toutes les plateformes à ce stade.

(L'interface utilisateur de notre système de contrôle de code source utilisait un navigateur Web car il était portable sur toute la plate-forme. C'était 6 mois avant que nous ayons une connexion Internet. Nous avons dû télécharger le navigateur sur X25!)

Ian
la source
Ayant travaillé sur plusieurs systèmes bigish, j'ai parfois l'impression d'avoir une idée de l'évolution du développement. Ensuite, j'ai lu des histoires comme celle-ci. Sheesh.
dmckee
@immibis C'était la chose à la mode à faire il y a 15 ans. Plus encore, cette pratique a été réellement approuvée et encouragée par les principaux fournisseurs Unix (SGI et DEC en particulier, mais IBM aussi).
oakad
1
Les gens ont tendance à oublier qu'Unix signifiait «cher». Windows a gagné la guerre des postes de travail / postes de travail en étant moins cher. C'est pour la même raison que Linux a plus tard gagné la guerre des serveurs.
slebetman
1
Si je veux qu'un ordinateur exécute un logiciel que j'ai écrit moi-même, alors je veux qu'il soit flexible et dispose de 101 options pour la compilation des noyaux, etc. Cependant, si je vends des logiciels à installer sur l'ordinateur du client, je veux que le client soit exécuter un système d'exploitation qui n'est pas flexible, de sorte que je sais que cela fonctionnera sur leur ordinateur s'il fonctionne sur le mien. C'était un facteur important lorsque l'on considérait Linux comme un fournisseur de logiciels - le support semblait tout simplement trop cher. Linux a remporté la guerre des logiciels de serveurs hébergés , où le serveur est fourni par le fournisseur de logiciels - par exemple la plupart des logiciels déployés sur le Web.
Ian
3
@slebetman Ce n'est que juste - Unix a gagné la "guerre" précédente en étant moins cher (par rapport aux machines LISPM et similaires). Il était absolument horrible, terriblement conçu et se bloquait constamment (mais il démarre tellement plus vite qu'un LISPM!: P), en utilisant C comme langage de programmation principal (une chute assez élevée de LISP et similaire), mais c'était beaucoup moins cher. En fait, beaucoup l'ont adopté parce qu'il était gratuit (il y a eu beaucoup de mutations libres bien avant Linux). En fait, j'ai rencontré beaucoup de LISPers de la vieille école qui préféraient MS-DOS aux unix de l'époque. Oui, c'est horrible.
Luaan
3

La réponse courte à cette question est que c'est ce qu'est un outil de construction . Un outil qui automatise l'utilisation d'autres outils, dans le but de construire un produit final à partir de certains fichiers source. Si nous écrivons le script de construction dans le même langage que le produit lui-même, nous sommes dans le domaine des outils spécifiques au langage, qui ne seraient pas considérés comme des outils de construction de la même manière.

Cela soulève la question - pourquoi les compilateurs ne fournissent-ils pas le type d'automatisation de construction auquel nous sommes habitués à partir d'outils comme make? À quoi la réponse est simplement parce que make existe . La philosophie Unix de «faire une chose et bien le faire» suggère qu'il n'est pas de la responsabilité du compilateur de fournir ceci *. Cela dit, j'ai personnellement vécu ma part de maux de tête et je serais intéressé d'essayer un compilateur qui fournit son propre système de construction "natif" entre guillemets.

Pour un exemple de compilateur conçu de cette façon, voir Jai de Jon Blow (non encore publié), un langage destiné à remplacer C ++. Les liens vers les présentations et les démos du compilateur sont rassemblés ici . Ce langage se compile en byte-code qui s'exécute dans le compilateur, la compilation en binaire étant une fonction standard fournie par la bibliothèque, accessible à partir du byte-code. L'intention est de permettre à la fois l'automatisation de la construction et la méta-programmation dans la syntaxe native du langage.

* Un regard sur Visual Studio de Microsoft vous montrera un exemple de la philosophie opposée. :)

CD Haddon.
la source
2

L'outil de construction est d'abord et avant tout un outil, tout comme 'gcc', 'ls', 'awk' ou 'git'. Vous alimentez l'outil une entrée (nom de fichier, paramètres, etc.) et il fera quelques trucs en conséquence.

Tous ces outils vous permettent de transmettre votre contribution d'une manière qui devrait être assez simple à écrire et à comprendre. Dans le cas particulier des outils de construction, l'entrée est un fichier de recette, un fichier qui décrit comment votre projet passe des fichiers source au produit fini.

Si votre recette est aussi simple que de passer dans le dossier qui contient le projet et le compilateur à utiliser, alors un "langage" déclaratif suffit. Une fois que la recette devient de plus en plus compliquée, avec plus de logique, il devient difficile de la gérer avec des langages déclaratifs et des langages plus généraux sont utilisés.

Il devrait maintenant être évident qu'il n'y a aucun lien entre le langage utilisé pour écrire vos recettes de construction et les langages utilisés pour écrire votre code produit simplement parce qu'ils ont des objectifs et des exigences différents. Il n'y a aucun lien même entre la langue dans laquelle l'outil de construction est écrit et la «langue» dans laquelle les recettes de construction doivent être écrites. Utilisez toujours le meilleur outil pour le travail!

Tibos
la source