Pendant la majeure partie de ma carrière en programmation, j'ai utilisé la commande "build/compile/run" dans n'importe quel IDE avec lequel je travaille pour produire un programme exécutable. Ceci est un bouton, assez facile . Au fur et à mesure que j'apprends plus sur les différents langages et frameworks, je vois de plus en plus parler de "scripts de construction" (ANT, Maven, Gradle, etc.) pour lancer un projet. Ma compréhension de ceux-ci est qu'ils sont des instructions le compilateur/éditeur de liens/créateur de programme magique qui spécifie les détails de configuration - minuties.
Je me souviens avoir écrit des makefiles à l'école, mais je n'ai vu aucun avantage spécial à l'époque (nous ne les avons utilisés que lors de l'écriture dans un terminal Unix, où un IDE avec son bouton "build" pratique n'était pas Au-delà de cela, j'ai vu d'autres questions ici qui expliquent comment les scripts de construction peuvent faire plus que simplement créer votre programme - ils peuvent exécuter des tests unitaires ainsi que sécurisé ressources quelle que soit la machine hôte .
Je ne peux pas ébranler le sentiment que les scripts de construction sont importants à comprendre en tant que développeur, mais j'aimerais une explication significative; pourquoi devrais-je utiliser/écrire des scripts de construction?
Responsabilités de Build Script et Build Server discute du rôle qu'il joue dans un cadre plus large. Je recherche des avantages spécifiques offerts par un script de construction par rapport à la commande "build/run" d'un IDE ou à des méthodes similaires.
Automatisation.
Lorsque vous développez, ce n'est que dans les projets les plus simples que le bouton "build" par défaut fera tout ce dont vous avez besoin pour faire; vous devrez peut-être créer WS à partir d'API, générer des documents, établir un lien avec des ressources externes, déployer les modifications sur un serveur, etc. Certains IDE vous permettent de personnaliser le processus de génération en ajoutant des étapes ou des constructeurs supplémentaires, mais cela signifie seulement que vous êtes générer votre script de construction via les produits IDE.
Mais développer un système, ce n'est pas seulement écrire du code. Il y a plusieurs étapes impliquées. Un script indépendant IDE peut être exécuté automatiquement, ce qui signifie que:
Lorsque vous validez une modification du contrôle de version, une nouvelle version peut être lancée automatiquement par le serveur. Cela garantira que vous n'avez pas oublié de valider tout ce dont vous avez besoin pour la construction.
De même, une fois la génération terminée, des tests peuvent automatiquement être exécutés pour voir si vous avez cassé quelque chose.
Maintenant, le reste de l'organisation (QA, administrateurs système) a un produit intégré qui
a) est parfaitement reproductible uniquement à partir de la version de contrôle.
b) est commun à tous.
Même lorsque je travaillais en équipe d'un seul homme, j'ai utilisé des scripts à cette fin; une fois le correctif développé, je validerais SVN, l'exporterais dans un autre répertoire et utiliserais le script de construction pour générer la solution, qui irait ensuite aux systèmes de préproduction et plus tard à la production. Si quelques semaines plus tard (avec ma base de code locale déjà modifiée) quelqu'un se plaignait d'un bug, je saurais exactement quelle révision SVN je devrais vérifier afin de déboguer correctement le système.
Comme le code, un script de construction est exécuté par l'ordinateur. Les ordinateurs sont exceptionnellement bons à suivre un ensemble d'instructions. En fait, (en dehors du code auto-modifiant), les ordinateurs exécuteront la même séquence d'instructions exactement de la même manière, avec la même entrée. Cela offre un niveau de cohérence que, bien, seul un ordinateur peut égaler.
En revanche, nous, les sacs de chair remplis d'eau, sommes tout simplement méprisables lorsqu'il s'agit de suivre les étapes. Ce cerveau analytique embêtant a tendance à remettre en question tout ce qu'il rencontre. "Oh ... je n'ai pas besoin de ça", ou "Dois-je vraiment utiliser ce drapeau? Eh ... je vais juste l'ignorer." De plus, nous avons tendance à faire preuve de complaisance. Une fois que nous avons fait quelque chose plusieurs fois, nous commençons à croire que nous connaissons les instructions et n'avons pas à regarder la feuille d'instructions.
Extrait de "The Pragmatic Programmer":
De plus, nous voulons assurer la cohérence et la répétabilité du projet. Les procédures manuelles laissent la cohérence au changement; la répétabilité n'est pas garantie, surtout si certains aspects de la procédure sont ouverts à l'interprétation par différentes personnes.
De plus, nous exécutons HILARIEUSEMENT la lenteur dans l'exécution des instructions (par rapport à un ordinateur). Sur un grand projet, avec des centaines de fichiers et de configurations, il faudrait des années pour exécuter manuellement toutes les étapes d'un processus de génération.
Je vais vous donner un exemple réel. Je travaillais sur des logiciels embarqués, où la majeure partie du code était partagée sur plusieurs plates-formes matérielles différentes. Chaque plate-forme avait un matériel différent, mais la plupart des logiciels étaient les mêmes. Mais il y avait de petites pièces spécifiques à chaque matériel. Idéalement, les pièces communes devraient être placées dans une bibliothèque et reliées à chaque version. Cependant, les pièces communes n'ont pas pu être compilées dans une bibliothèque partagée. Il devait être compilé avec chaque configuration différente.
Au début, j'ai compilé manuellement chaque configuration. Il n'a fallu que quelques secondes pour basculer entre les configurations, et ce n'était pas si compliqué. Vers la fin du projet, un défaut critique a été découvert dans la partie partagée du code, où un périphérique reprendrait essentiellement le bus de communication. C'était MAUVAIS! Vraiment mauvais. J'ai trouvé le bogue dans le code, l'ai corrigé et recompilé chaque version. Sauf un. Pendant le processus de construction, j'ai été distrait et j'en ai oublié un. Les fichiers binaires ont été libérés, la machine a été construite et un jour plus tard, je reçois un appel téléphonique me disant que la machine a cessé de répondre. Je l'ai vérifié et j'ai découvert qu'un appareil avait verrouillé le bus. "Mais j'ai corrigé ce bug!".
Je l'ai peut-être corrigé, mais il n'a jamais trouvé son chemin sur cette seule planche. Pourquoi? Parce que je n'avais pas de processus de construction automatisé qui a construit chaque version en un seul clic.
Si tout ce que vous voulez faire est de <compiler> **/*.<extension>
, Les scripts de construction ne servent à rien (bien que l'on puisse dire que si vous voyez un Makefile
dans le projet, vous savez que vous pouvez le construire avec make
). Le fait est que les projets non triviaux nécessitent généralement plus que cela - à tout le moins, vous devrez généralement ajouter des bibliothèques et (à mesure que le projet mûrit) configurer les paramètres de construction.
Les IDE sont généralement au moins configurables - mais maintenant le processus de construction repose sur des options spécifiques aux IDE. Si vous utilisez Eclipse , Alice préfère NetBeans , et Bob veut utiliser IntelliJ IDEA , vous ne pouvez pas partager la configuration, et quand on d'entre vous pousse une modification du contrôle de code source, ils doivent soit modifier manuellement les fichiers de configuration créés par l'EDI des autres développeurs, soit informer les autres développeurs afin qu'ils le fassent eux-mêmes (ce qui signifie qu'il y aura des validations où le IDE est incorrecte pour certains des IDE ...).
Vous devez également comprendre comment effectuer ce changement dans chacun des IDE utilisés par l'équipe, et si l'un d'eux ne prend pas en charge ce paramètre particulier ...
Maintenant, ce problème dépend de la culture - vos développeurs pourraient trouver acceptable de ne pas avoir le choix des IDE. Mais les développeurs qui ont une expérience avec un IDE sont généralement à la fois plus heureux et plus efficaces lorsqu'ils l'utilisent, et les utilisateurs d'éditeurs de texte ont tendance à être religieusement zélés au sujet de leurs outils préférés, c'est donc l'un des endroits où vous voulez donner liberté aux développeurs - et les systèmes de construction vous permettent de faire exactement cela. Certaines personnes peuvent avoir une préférence pour le système de construction, mais ce n'est pas aussi fanatique que les préférences IDE/éditeur ...
Même si tous les développeurs utilisent le même IDE - bonne chance pour convaincre le serveur de build de l'utiliser ...
Maintenant, c'est pour les personnalisations du processus de construction simples, pour lesquelles les IDE ont tendance à fournir une belle interface graphique. Si vous voulez des choses plus complexes - comme le prétraitement/la génération automatique de fichiers source avant la compilation - vous devrez généralement écrire un script de pré-construction dans une zone de texte de base à l'intérieur de la configuration de l'EDI. Dans quels systèmes de construction vous auriez encore à coder cette partie, mais vous pouvez le faire dans l'éditeur dans lequel vous écrivez le code, et plus important encore: le cadre du système de construction lui-même fournit généralement un certain soutien pour l'organisation de ces scripts.
Enfin - les systèmes de construction sont plus utiles que la construction du projet - vous pouvez les programmer pour effectuer d'autres tâches que tout le monde dans l'équipe pourrait avoir besoin d'effectuer. Dans Ruby on Rails , par exemple, il existe des tâches de système de génération pour exécuter les migrations de base de données, pour nettoyer les fichiers temporaires, etc. Le fait de placer ces tâches dans le système de génération garantit que tout le monde dans l'équipe peut les effectuer de manière cohérente .
De nombreux IDE regroupent simplement les commandes utilisées pour construire quelque chose, puis génèrent un script et l'appellent!
Par exemple, dans Visual Studio, vous pouvez voir les paramètres de ligne de commande pour une compilation C++ dans la zone 'ligne de commande'. Si vous regardez attentivement la sortie de la compilation, vous verrez le fichier temporaire qui contient le script de génération qui a été utilisé pour exécuter la compilation.
De nos jours, c'est tout MSBuild , mais cela est toujours exécuté directement par l'IDE.
Donc, la raison pour laquelle vous utilisez la ligne de commande est que vous allez directement à la source et que vous sautez l'homme du milieu, un intermédiaire qui pourrait avoir été mis à jour ou nécessiter un tas de dépendances dont vous ne voulez pas ou dont vous n'avez pas besoin sur un serveur sans tête qui agit comme votre intégration continue (CI) serveur.
De plus, vos scripts font plus que les étapes orientées développeur habituelles pour lesquelles ils sont conçus. Par exemple, après une génération, vous pouvez souhaiter que vos binaires soient empaquetés et copiés dans un emplacement spécial, ou un package d'installation créé, ou un outil de documentation exécuté sur eux. De nombreuses tâches différentes sont effectuées par un serveur CI qui sont inutiles sur une machine de développeur, donc bien que vous puissiez créer un projet IDE qui a effectué toutes ces étapes, vous devrez alors en conserver deux - un projet pour les développeurs et un autre pour les builds. Certaines tâches de build (analyse statique par exemple) peuvent prendre beaucoup de temps que vous ne voudriez pas pour les projets de développeurs.
En bref cependant, c'est juste plus facile - créez un script pour faire tout ce que vous voulez et c'est rapide et simple de le lancer sur la ligne de commande ou une configuration de serveur de build.
make
est beaucoup plus facile à retenir et à taper que
gcc -o myapp -I/include/this/dir -I/include/here/as/well -I/dont/forget/this/one src/myapp.c src/myapp.h src/things/*.c src/things/*.h
Et les projets peuvent avoir des commandes de compilation très complexes. Un script de génération a également la possibilité de recompiler uniquement les éléments qui ont changé. Si vous voulez faire une construction propre,
make clean
est plus facile et plus fiable une fois configuré correctement que d'essayer de se souvenir de chaque endroit où un fichier intermédiaire peut avoir été produit.
Bien sûr, si vous utilisez un IDE, il est également facile de cliquer sur un bouton de génération ou de nettoyage. Cependant, il est beaucoup plus difficile d'automatiser le déplacement du curseur vers un emplacement spécifique sur l'écran, en particulier lorsque cet emplacement peut se déplacer si la fenêtre se déplace, que d'automatiser une simple commande de texte.
Les réponses ci-dessus couvrent beaucoup de bonnes raisons, mais un exemple concret que j'aimerais ajouter (que je ne peux pas ajouter en tant que commentaire en raison de l'absence de karma) est de Android = programmation.
Je suis un développeur professionnel Android/iOS/Windows Phone et j'utilise beaucoup d'API de services Google (principalement Google Maps) .
Sous Android, ces services nécessitent que j'ajoute un keystore, ou un type de fichier d'ID développeur qui indique à Google que je suis qui je dis que je suis, à une console développeur. Si mon application est compilée avec un magasin de clés différent, la section Google Maps de l'application ne fonctionnera pas.
Au lieu d'ajouter et de gérer une douzaine de fichiers de clés à la console du développeur, dont un seul peut en fait être utilisé pour mettre à jour l'application de toute façon, j'inclus ce fichier de clés dans notre référentiel sécurisé et j'utilise Gradle pour dire Android Studio exactement quel magasin de clés utiliser lors de la construction pour "déboguer" ou "publier". Maintenant, je n'ai plus qu'à ajouter deux magasins de clés à ma console de développeur Google, un pour "déboguer" et un pour "publier", et tous les membres de mon équipe peut cloner le référentiel et passer au développement sans avoir à entrer dans la console de développement et ajouter le hachage SHA de leur magasin de clés particulier, ou pire, faire me les gérer . Cela a l'avantage supplémentaire de donner à chaque membre de l'équipe une copie du magasin de clés de signature, ce qui signifie que si je suis absent du bureau et qu'une mise à jour est prévue, un membre de l'équipe n'a besoin que pour suivre une très courte liste d'instructions afin de pousser une mise à jour.
L'automatisation de la construction comme celle-ci maintient la cohérence des constructions et réduit la dette technique en réduisant considérablement le temps de configuration lorsque nous obtenons un nouveau développeur, une nouvelle machine ou lorsque nous devons réimaginer une machine.
Sinon, comment le feriez-vous? La seule autre façon consiste à spécifier une longue commande de ligne de commande.
Une autre raison est que les makefiles permettent une compilation incrémentielle, ce qui accélère beaucoup le temps de compilation.
Les Makefiles peuvent également créer un processus de construction multiplateforme. CMake génère différents scripts de construction basés sur la plate-forme.
Éditer:
Avec un IDE, vous êtes lié à une façon particulière de faire les choses. Beaucoup de gens utilisent vim ou emacs même s'ils n'ont pas beaucoup de fonctionnalités de type IDE. Ils le font parce qu'ils veulent la puissance de ces éditeurs. Les scripts de construction sont nécessaires pour ceux qui n'utilisent pas d'IDE.
Même pour ceux qui utilisent un IDE, vous voudrez peut-être vraiment savoir ce qui se passe, donc le script de construction vous offre les détails d'implémentation bas qu'une approche GUI n'a pas.
Les IDE eux-mêmes utilisent souvent aussi des scripts de construction en interne; le bouton d'exécution n'est qu'une autre façon d'exécuter la commande make.
Avantages du script de construction:
les changements ressemblent à du code (par exemple, dans une commande git diff), pas à des options cochées différentes dans une boîte de dialogue
créer plus de sortie qu'une simple construction
Dans certains de mes projets précédents, j'ai utilisé les scripts de construction pour:
Vous pouvez souvent appeler le bouton "build" de manière automatisée (Visual Studio accepte les arguments de ligne de commande, par exemple). Les gens écrivent des scripts de build dès qu'ils ont besoin de quelque chose que le bouton de build ne peut pas fournir.
Par exemple, la plupart des IDE ne vous permettent de créer qu'une seule plateforme à la fois. Ou un seul langue à la fois. Ensuite, il y a ce que vous faites avec les sorties intégrées: votre IDE peut-il les regrouper dans un package d'installation?