Die meiste Zeit meiner Programmierkarriere habe ich den Befehl "build / compile / run" in der IDE verwendet, mit der ich arbeite, um ein lauffähiges Programm zu erstellen. Dies ist eine Taste, ziemlich einfach. Wenn ich jedoch mehr über verschiedene Sprachen und Frameworks lerne, spreche ich immer häufiger von "Build-Skripten" (ANT, Maven, Gradle usw.), um ein Projekt zum Laufen zu bringen. Ich verstehe dies so, dass es sich um Anweisungen für den Compiler / Linker / Magical-Program-Maker handelt, die Konfigurationsdetails angeben - Minutien.
Ich erinnere mich, Makefiles in der Schule geschrieben zu haben, aber ich sah damals keinen besonderen Vorteil (wir haben sie nur beim Schreiben in einem Unix-Terminal verwendet, in dem eine IDE mit dem praktischen "Build" -Button nicht vorhanden war). Darüber hinaus habe ich hier andere Fragen gesehen , die darüber diskutieren , wie die Build - Skripte kann mehr tun , als nur Ihr Programm erstellen - sie können Unit - Tests laufen sowie sichere Ressourcen unabhängig von der Host - Maschine .
Ich kann das Gefühl nicht loswerden, dass das Erstellen von Skripten wichtig ist, um als Entwickler verstanden zu werden, aber ich hätte gerne eine aussagekräftige Erklärung. Warum sollte ich Build-Skripte verwenden / schreiben?
In den Verantwortlichkeiten von Build Script und Build Server wird die Rolle erläutert, die es in einem breiteren Bereich spielt. Ich suche nach spezifischen Vorteilen, die ein Build-Skript gegenüber dem Befehl "build / run" einer IDE oder ähnlich einfachen Methoden bietet.
quelle
important to understand as a developer
, aber sicherlich nicht immer. Selbst in Umgebungen, in denen Build-Skripte praktische Anforderungen sind, kümmern sich viele "Entwickler" nicht im geringsten darum. Aber die Skripte sind dann eher für "Builder" als für die Entwickler wichtig. An den letzten Stellen, an denen ich gearbeitet habe, hatten die meisten Entwickler praktisch keine Verbindung zum Erstellen von Skripten.Antworten:
Automatisierung.
Wenn Sie entwickeln, wird nur in den einfachsten Projekten die Standardschaltfläche "Erstellen" alles tun, was Sie dazu benötigen. Möglicherweise müssen Sie WS aus APIs erstellen, Dokumente generieren, mit externen Ressourcen verknüpfen, die Änderungen auf einem Server bereitstellen usw. Bei einigen IDEs können Sie den Erstellungsprozess anpassen, indem Sie zusätzliche Schritte oder Builder hinzufügen. Dies bedeutet jedoch nur, dass Sie dies tun Generieren Sie Ihr Build-Skript über die IDE-Komponenten.
Bei der Entwicklung eines Systems wird jedoch nicht nur Code geschrieben. Es sind mehrere Schritte erforderlich. Ein IDE-unabhängiges Skript kann automatisch ausgeführt werden. Dies bedeutet:
Wenn Sie eine Änderung an der Versionskontrolle vornehmen, kann ein neuer Build automatisch vom Server gestartet werden. Dadurch wird sichergestellt, dass Sie nicht vergessen haben, die für den Build erforderlichen Vorgänge auszuführen.
Ebenso können nach Abschluss des Builds automatisch Tests ausgeführt werden, um festzustellen, ob Sie etwas kaputt gemacht haben.
Jetzt hat der Rest der Organisation (QS, Sysadmins) ein eingebautes Produkt, das
a) ist bereits ab der Steuerungsversion perfekt reproduzierbar.
b) ist allen gemeinsam.
Selbst wenn ich als Ein-Mann-Team gearbeitet habe, habe ich zu diesem Zweck Skripte verwendet. Wenn ich das Update entwickelt hatte, übernahm ich SVN, exportierte das SVN zurück in ein anderes Verzeichnis und verwendete das Build-Skript, um die Lösung zu generieren, die dann zu Vorproduktionssystemen und später zur Produktion ging. Wenn sich ein paar Wochen später (mit bereits geänderter lokaler Codebasis) jemand über einen Fehler beschwert, würde ich genau wissen, welche SVN-Revision ich auschecken müsste, um das System ordnungsgemäß zu debuggen.
quelle
Wie der Code wird ein Build-Skript vom Computer ausgeführt. Computer sind außergewöhnlich gut darin, eine Reihe von Anweisungen zu befolgen. Tatsächlich führen Computer (außerhalb des sich selbst ändernden Codes) dieselbe Befehlssequenz bei gleicher Eingabe genauso aus. Dies bietet ein Konsistenzniveau, mit dem nur ein Computer mithalten kann.
Im Gegensatz dazu sind uns mit Wasser gefüllte Fleischsäcke bei den folgenden Schritten geradezu unwürdig. Dieses nervige analytische Gehirn hat die Tendenz, alles in Frage zu stellen, was ihm begegnet. "Oh ... das brauche ich nicht", oder "Soll ich diese Flagge wirklich benutzen? Eh ... ich werde es einfach ignorieren." Darüber hinaus neigen wir dazu, selbstgefällig zu werden. Sobald wir ein paar Mal etwas getan haben, glauben wir, dass wir die Anweisungen kennen und müssen nicht auf das Anweisungsblatt schauen.
Aus "The Pragmatic Programmer":
Darüber hinaus sind wir bei der Ausführung von Anweisungen (im Vergleich zu einem Computer) AUSSERGEWÖHNLICH träge. Bei einem großen Projekt mit Hunderten von Dateien und Konfigurationen würde es Jahre dauern, alle Schritte in einem Erstellungsprozess manuell auszuführen.
Ich gebe Ihnen ein reales Beispiel. Ich arbeitete an einer eingebetteten Software, bei der der größte Teil des Codes auf verschiedenen Hardwareplattformen geteilt wurde. Jede Plattform hatte unterschiedliche Hardware, aber der größte Teil der Software war derselbe. Aber es gab kleine Stücke, die für jede Hardware spezifisch waren. Idealerweise werden die gemeinsamen Stücke in eine Bibliothek gestellt und mit jeder Version verknüpft. Die allgemeinen Stücke konnten jedoch nicht zu einer gemeinsam genutzten Bibliothek zusammengestellt werden. Es musste mit jeder anderen Konfiguration kompiliert werden.
Zuerst habe ich jede Konfiguration manuell kompiliert. Es dauerte nur ein paar Sekunden, um zwischen den Konfigurationen zu wechseln, und das war kein großer Schmerz. Gegen Ende des Projekts wurde ein kritischer Fehler im gemeinsam genutzten Teil des Codes entdeckt, bei dem ein Gerät im Wesentlichen den Kommunikationsbus übernehmen würde. Das war SCHLECHT! Wirklich schlecht. Ich habe den Fehler im Code gefunden, ihn behoben und jede Version neu kompiliert. Außer einem. Während des Erstellungsprozesses wurde ich abgelenkt und vergaß einen. Die Binärdateien wurden freigegeben, die Maschine wurde gebaut, und einen Tag später erhalte ich einen Anruf mit der Meldung, dass die Maschine nicht mehr reagiert. Ich überprüfe es und stelle fest, dass ein Gerät den Bus gesperrt hat. "Aber ich habe diesen Fehler behoben!"
Ich habe es vielleicht repariert, aber es hat nie den Weg auf dieses eine Board gefunden. Warum? Weil ich keinen automatisierten Erstellungsprozess hatte, der jede einzelne Version mit einem Klick erstellte.
quelle
Wenn alles, was Sie jemals tun möchten, ist
<compiler> **/*.<extension>
, Skripte zu erstellen, hat dies wenig Sinn (obwohl man argumentieren kann, dass SieMakefile
es mit erstellen können, wenn Sie in dem Projekt ein sehenmake
). Die Sache ist - nicht-triviale Projekte erfordern normalerweise mehr als das - zumindest müssen Sie normalerweise Bibliotheken hinzufügen und (wenn das Projekt ausgereift ist) Build-Parameter konfigurieren.IDEs sind normalerweise mindestens so konfigurierbar - aber der Erstellungsprozess basiert jetzt auf IDE-spezifischen Optionen. Wenn Sie Eclipse verwenden , bevorzugt Alice NetBeans , und Bob möchte IntelliJ IDEA verwenden . Sie können die Konfiguration nicht freigeben. Wenn einer von Ihnen eine Änderung an der Quellcodeverwaltung vornimmt, muss er die von der IDE erstellte Konfiguration entweder manuell bearbeiten Dateien der anderen Entwickler, oder benachrichtigen Sie die anderen Entwickler, damit sie es selbst tun (was bedeutet, es wird Commits geben, bei denen die IDE-Konfiguration für einige der IDEs falsch ist ...).
Sie müssen auch herausfinden, wie diese Änderung in den einzelnen vom Team verwendeten IDEs vorgenommen werden kann und ob eine dieser IDs diese bestimmte Einstellung nicht unterstützt ...
Nun, dieses Problem ist kulturabhängig - Ihre Entwickler halten es möglicherweise für akzeptabel, nicht die Wahl zwischen IDEs zu haben. Entwickler, die Erfahrung mit einer IDE haben, sind in der Regel zufriedener und effizienter, und Benutzer von Texteditoren neigen dazu, religiös begeistert von ihren bevorzugten Tools zu sein. Daher ist dies einer der Orte, an denen Sie den Entwicklern Freiräume einräumen möchten - und Build-Systeme ermöglichen es Ihnen, genau das zu tun. Einige Leute mögen ein Build-System bevorzugen, aber es ist nicht annähernd so fanatisch wie IDE / Editor-Vorlieben ...
Selbst wenn Sie alle Entwickler dazu bringen, dieselbe IDE zu verwenden - viel Glück, den Build-Server davon zu überzeugen, sie zu verwenden ...
Nun, das ist für die einfachen Anpassungen des Erstellungsprozesses, für die IDEs normalerweise eine schöne GUI bereitstellen. Wenn Sie komplexere Inhalte benötigen, z. B. die Vorverarbeitung / automatische Generierung von Quelldateien vor der Kompilierung, müssen Sie in der Regel ein vorab erstelltes Skript in einen Textbereich in der IDE-Konfiguration schreiben. Welche Build-Systeme müssten Sie noch codieren, aber Sie können dies im eigentlichen Editor tun, in dem Sie den Code schreiben, und was noch wichtiger ist: Das Framework des Build-Systems selbst bietet normalerweise eine gewisse Unterstützung für die Organisation dieser Skripte.
Schließlich können Sie Build-Systeme nicht nur zum Erstellen des Projekts verwenden, sondern auch für andere Aufgaben programmieren, die möglicherweise von allen Teammitgliedern ausgeführt werden müssen. In Ruby on Rails gibt es beispielsweise Build-System-Tasks zum Ausführen von Datenbankmigrationen, zum Bereinigen der temporären Dateien usw. Durch das Einfügen dieser Tasks in das Build-System wird sichergestellt, dass jeder im Team sie konsistent ausführen kann.
quelle
Viele IDEs packen einfach die Befehle, mit denen etwas erstellt wurde, und generieren dann ein Skript und rufen es auf!
In Visual Studio können Sie beispielsweise die Befehlszeilenparameter für eine C ++ - Kompilierung im Feld "Befehlszeile" anzeigen. Wenn Sie sich die Build-Ausgabe genau ansehen, sehen Sie die temporäre Datei, die das Build-Skript enthält, mit dem die Kompilierung ausgeführt wurde.
Heutzutage ist alles MSBuild , aber das wird immer noch direkt von der IDE ausgeführt.
Der Grund, warum Sie die Befehlszeile verwenden, ist, dass Sie direkt zur Quelle gehen und den Mittelsmann überspringen, einen Mittelsmann, der möglicherweise aktualisiert wurde oder eine Menge Abhängigkeiten benötigt, die Sie auf einem kopflosen Server einfach nicht wollen oder brauchen fungiert als Ihr CI-Server ( Continuous Integration ).
Darüber hinaus können Ihre Skripte mehr als die üblichen entwicklerorientierten Schritte ausführen, für die sie entwickelt wurden. Nach einem Build möchten Sie möglicherweise Ihre Binärdateien in ein spezielles Verzeichnis packen und kopieren oder ein Installationspaket erstellen oder ein Dokumentations-Tool ausführen. Viele verschiedene Aufgaben werden von einem CI-Server ausgeführt, die auf einem Entwicklermaschine sinnlos sind. Während Sie also ein IDE-Projekt erstellen könnten, das alle diese Schritte ausführt, müssten Sie zwei davon verwalten - ein Projekt für Entwickler und ein anderes für Builds. Einige Build-Aufgaben (z. B. statische Analyse) können viel Zeit in Anspruch nehmen, die Sie für Entwicklerprojekte nicht benötigen.
Kurz gesagt, es ist einfach einfacher: Erstellen Sie ein Skript, das alle gewünschten Aufgaben ausführt, und starten Sie es schnell und einfach über die Befehlszeile oder eine Build-Server-Konfiguration.
quelle
ist viel einfacher zu merken und zu tippen als
Und Projekte können sehr komplexe Kompilierungsbefehle haben. Ein Build-Skript kann auch nur die geänderten Elemente neu kompilieren. Wenn Sie einen sauberen Build machen wollen,
Ist es erst einmal richtig eingerichtet, ist es einfacher und zuverlässiger, als sich an jeden Ort zu erinnern, an dem eine Zwischendatei erstellt wurde.
Wenn Sie eine IDE verwenden, ist es natürlich auch ganz einfach, auf eine Build- oder Clean-Schaltfläche zu klicken. Es ist jedoch viel schwieriger, das Verschieben des Cursors an eine bestimmte Stelle auf dem Bildschirm zu automatisieren, insbesondere dann, wenn sich diese Stelle möglicherweise bewegt, wenn sich das Fenster bewegt, als einen einfachen Textbefehl zu automatisieren.
quelle
Wie würdest du es sonst tun? Die einzige andere Möglichkeit besteht darin, einen langen Befehlszeilenbefehl anzugeben.
Ein weiterer Grund ist, dass Makefiles eine inkrementelle Kompilierung ermöglichen, was die Kompilierungszeit erheblich verkürzt.
Makefiles können auch einen Build-Prozess plattformübergreifend gestalten. CMake generiert verschiedene Build-Skripte basierend auf der Plattform.
Bearbeiten:
Mit einer IDE sind Sie an eine bestimmte Vorgehensweise gebunden. Viele Leute benutzen vim oder emacs, obwohl sie nicht viele IDE-ähnliche Funktionen haben. Sie tun es, weil sie die Macht haben wollen, die diese Editoren bieten. Build-Skripte sind für Benutzer erforderlich, die keine IDE verwenden.
Selbst für diejenigen, die eine IDE verwenden, möchten Sie vielleicht wirklich wissen, was gerade vor sich geht. Das Build-Skript bietet Ihnen die Details der Implementierung, die ein GUI-Ansatz nicht hat.
IDEs selbst verwenden häufig auch interne Build-Skripte. Die Schaltfläche "Ausführen" ist nur eine andere Möglichkeit, den Befehl "make" auszuführen.
quelle
Die obigen Antworten decken viele gute Gründe ab, aber ein reales Beispiel, das ich hinzufügen möchte (das ich wegen fehlendem Karma nicht als Kommentar hinzufügen kann), stammt aus der Android-Programmierung.
Ich bin ein professionelles Android / iOS / Windows Phone Entwickler, und ich verwende Google - Services - APIs (meist Google Maps) eine Menge .
In Android erfordern diese Dienste, dass ich einer Entwicklerkonsole einen Keystore oder eine Art Entwickler-ID-Datei hinzufüge , die Google mitteilt, dass ich der bin, von dem ich sage, dass ich ich bin. Wenn meine App mit einem anderen Keystore kompiliert wurde, funktioniert der Google Maps-Bereich der App nicht.
Anstatt der Entwicklerkonsole ein Dutzend Keystores hinzuzufügen und zu verwalten, von denen ohnehin nur einer zum Aktualisieren der App verwendet werden kann, füge ich diesen Keystore in unser sicheres Repo ein und teile Android Studio mit Gradle genau mit, welcher Keystore beim Erstellen verwendet werden soll "debug" oder "release". Jetzt muss ich meiner Google-Entwicklerkonsole nur noch zwei Keystores hinzufügen, einen für "Debug" und einen für "Release", und alle Teammitglieder können das Repo klonen und können mit der Entwicklung beginnen, ohne sich an den Entwickler wenden zu müssen Konsole und füge den SHA-Hash ihres jeweiligen Schlüsselspeichers hinzu, oder noch schlimmer, ich muss sie verwalten. Dies hat den zusätzlichen Vorteil, dass jedem Teammitglied eine Kopie des signierenden Keystores zur Verfügung gestellt wird. Wenn ich nicht im Büro bin und ein Update geplant ist, muss ein Teammitglied nur eine sehr kurze Liste von Anweisungen befolgen, um eine zu pushen aktualisieren.
Eine Build-Automatisierung wie diese sorgt dafür, dass die Builds konsistent bleiben, und verringert die technische Verschuldung, indem die Einrichtungszeit verkürzt wird, wenn wir einen neuen Entwickler, eine neue Maschine oder eine Maschine neu erstellen müssen.
quelle
Erstellen Sie Skriptvorteile:
Änderungen sehen wie Code aus (z. B. in einem git diff-Befehl), nicht wie verschiedene aktivierte Optionen in einem Dialogfeld
Erstellen Sie mehr Leistung als ein einfacher Build
In einigen meiner vorherigen Projekte habe ich die Build-Skripte verwendet, um:
quelle
Häufig können Sie die Schaltfläche "Erstellen" automatisiert aufrufen (Visual Studio akzeptiert beispielsweise Befehlszeilenargumente). Die Leute schreiben Build-Skripte, sobald sie etwas brauchen, das die Build-Schaltfläche nicht bieten kann.
In den meisten IDEs können Sie beispielsweise jeweils nur eine Plattform erstellen. Oder nur eine Sprache gleichzeitig. Mit den integrierten Ausgaben können Sie dann Folgendes tun: Kann Ihre IDE sie alle zu einem Installationspaket zusammenfassen?
quelle