Ein verteiltes (On-Demand) Build-System

Ich habe die langen Bauzeiten satt …

Die Ausrede Nr. 1 für Programmierer, legitim nachzulassen: „Mein Code wird kompiliert.“

Ich interessiere mich für ein verteiltes Build-System, entweder auf der unteren Ebene, auf der das Äquivalent von make ausgeführt wird und nichts anderes als Abhängigkeitsregeln bekannt ist, oder auf der höheren Ebene von etwas wie CMake oder SCons. Das System muss (sich bemühen) alle Kerne auf einer Gruppe von Maschinen zu nutzen.

Beispiel

Angenommen, ich habe die folgenden Quellen, Zwischenziele und Endziele:

und nehmen wir an, das Bauen von jedem davon nimmt viel Zeit in Anspruch, und ich habe zwei Maschinen.

Das Build-System wird einen Maschinen-Build b0 und einen zweiten Maschinen-Build b1 haben, dann einen Maschinen-Build b2 und einen weiteren Maschinen-Build b3 – und es wird sicherstellen, dass nur die relevanten Quellen so schnell wie möglich kopiert/auf relevanten Maschinen verfügbar gemacht werden, nicht kurz nachdem vorherige Vermittler fertig sind. Und es wird diese Abhängigkeiten bestimmen, indem es sich die Quelldatei und minimale zusätzliche Informationen ansieht, die ich bereitstelle - ähnlich wie bei CMake+make.

Anforderungen

Muss:

  • nicht auf eine einzige Programmiersprache beschränkt sein (z. B. nicht distcc oder etwas, das in einer verteilten JVM lebt).
  • benötigen keinen Root-Zugriff auf einem der Computer.
  • Unterstützung auf x86_64-Rechnern
  • unterstützen (mindestens) moderne Linux-Distributionen
  • haben eine Befehlszeilenschnittstelle.
  • On-Demand-Builds unterstützen.
  • gratis sein.

Sollte:

  • irgendwie sprachagnostisch sein, in dem Sinne, wie Make oder CMake es sind (also Mechanismen haben, um mit verschiedenen Sprachen umzugehen, Abhängigkeiten zu erkennen und so weiter, ohne davon auszugehen, dass Ziele in einer bestimmten Sprache oder überhaupt in einer Sprache sind).

Kann oder kann nicht:

  • erfordern eine teilweise oder vollständige Einheitlichkeit der Systemkonfiguration in Bezug auf die Software.
  • mit Versionskontrolle integrieren
  • eine GUI haben
  • webfähig sein
Browserbasierte Schnittstelle oder Befehlszeile? Kontinuierliche Integration oder on demand? Integration mit Versionskontrolle?
@Mawg: Fair genug Fragen. Ich hatte angenommen, dass die Leute einige Standardeinstellungen im Sinn hatten, wenn ich "verteiltes Äquivalent von make/cmake" sage, aber ich denke, ich kann genauer sein. Siehe Bearbeiten.
Aus welchen Sprachen möchten Sie bauen? C und C++? Es wäre schwierig, ein System zu finden, das auf Groovy/F#/OCaml und allen anderen Sprachen aufbaut. Geben Sie besser die an, die Sie wirklich brauchen.
@NicolasRaoul: Ich habe nichts über Sprachen gesagt. Weder CMake noch Make care about them ... deshalb sollte es auch nicht so schwierig sein - Sprachagnostizismus.
Nun, wenn es nur ein Build-System ist, dann reicht die Befehlszeile (aber welches Betriebssystem?). Selbst dann können Sie es in Jenkins einstecken, wenn Sie eine GUI wünschen. Das Erstellen auf der Grundlage des Versionskontroll-Commits kann auch von Jenkins durchgeführt werden. Ich weiß nicht, ob Sie sich auch irgendwie in die Fehlerverfolgung oder in ein Projektplanungs-/Verfolgungstool integrieren möchten. Es gibt wahrscheinlich nicht viele Kandidaten für Sie, aber ich stelle einfach viele Fragen und versuche, genau festzulegen, was sie wollen. Wenn es mehrere Alternativen gibt (was hier wahrscheinlich nicht der Fall ist), können wir Ihnen umso besser helfen, je mehr Details Sie uns mitteilen
Otoh, selbst in diesem Fall schadet es nicht, wenn jemand anderes möglicherweise dumme Fragen stellt, an die Sie vielleicht nicht gedacht haben. Gute Frage, aber +1
CMake ist nicht sprachunabhängig. Jedes Mal, wenn eine neue Sprache/ein neuer Compiler erscheint, müssen Entwickler neue Module schreiben, um sie zu integrieren . Nur weil CMake viele Sprachen unterstützt, heißt das nicht, dass alle Build-Systeme dies tun. Wenn Sie also die Sprachen/Compiler angeben, die Sie tatsächlich benötigen, können Sie Ihre Chancen erhöhen, eine Antwort zu erhalten :-)
@NicolasRaoul: Ok, aber Sie spalten Haare, da die Sprachkenntnisse eher im Modul als in CMake selbst liegen.
@Mawg: Integration ist großartig, ich habe nichts dagegen, dass es möglich ist - aber ich bin hier sehr bescheiden. Außerdem habe ich geschrieben, dass ich es brauche, um Linux zu unterstützen.
Haben Sie versucht, sich Jenkins (jenkins.io) anzusehen? Es kann helfen.
@atp9: Tut es das, woran ich interessiert bin?
Ja, das tut es, aber ich würde vorschlagen, einen Blick darauf zu werfen, bevor Sie eine Entscheidung treffen.
@atp9: Bitte geben Sie eine Antwort, die erklärt, wie Jenkins dazu gebracht werden kann, mehrere Maschinen zu verwenden, um etwas schneller zu bauen, als dies auf einer einzelnen Maschine der Fall gewesen wäre. Vielen Dank!

Antworten (2)

Klingt so, als würden Sie tatsächlich mehrere Tools benötigen, zum Beispiel:

Wählen Sie ein Befehlszeilentool aus, um Builds zu automatisieren, die ausgeführt werden, wenn Sie „./build.sh“ (Linux) oder „build.cmd“ (Windows) eingeben.

  1. ant- Nicht nur für Java, sondern wirklich ein leistungsstarkes Ökosystem mit vielen Plugins, fast jede Build- und Bereitstellungsaufgabe, die Sie automatisieren müssen, kann damit automatisiert werden. Bietet keine Web-Benutzeroberfläche oder einen Planungsdienst, sodass Sie ihn in etwas anderem verwenden können.

  2. makeoder cmake- für Leute auf Systemebene mit vielen Abhängigkeiten und mindestens etwas C oder C++ - für Leute der alten Schule mit mindestens etwas C oder C++.

  3. "RemObjects Train": https://github.com/remobjects/train - für Leute, die Linux-, Mac- und Windows-Produkte erstellen und dafür Javascript verwenden möchten.

Wählen Sie jetzt ein webbasiertes Continuous-Integration-Tool aus, um den Build zu planen oder automatisch auszuführen, wenn jemand Code eincheckt:

A. jenkins- Der große Kerl da draußen. Außerdem gibt es Hudson, von dem Jenkins eine Gabelung ist, aber ich denke, Hudson ist im Grunde tot. Frei.

B. GitLab CI- Ein Neuling, aber wirklich praktisch, wenn Sie möchten, dass Ihre automatischen Builds immer dann ausgeführt werden, wenn jemand auf ein Git-Repo pusht, und Sie die Wahl haben möchten, den Git-Server selbst zu hosten oder ihn im Internet zu haben, das ist großartig Auswahl. Und frei.

Erstellen Sie jetzt Jenkins-Jobs für gemeinsam genutzte Komponenten. Verteilen Sie diese Artefakte jetzt auf die Sekundärstufen. Finden Sie selbst parallele Build-Möglichkeiten und bauen Sie Ihre Jenkins-Tasks, damit es eine "Pipeline" gibt. Verteilte Builds erfordern menschlichen Einfallsreichtum zum Entwerfen und optimieren nicht selbst und entdecken und verteilen binäre Zwischenprodukte nicht selbst.

Was meiner Ansicht nach an Ihrer Anfrage falsch ist, ist, dass Sie sich das Web-Ding als eine "Ebene" Ihres Build-Systems und Ihr Befehlszeilen-Build-Tool als eine weitere Ebene vorstellen müssen.

Beschränken Sie sich auch nicht auf nur ein Build-Tool. Vielleicht brauchen Sie CMake, damit Sie neu bauen können, libffmpegund Sie werden brauchen ant, damit Sie einige Jars neu bauen können, und Sie werden pythonund bashSkripte brauchen, um einige Dinge zu tun, die auf diese Weise am besten zu sein schienen.

Es gibt kein Build-Tool, das sie alle beherrscht, genauso wie in großen Systemen selten nur eine Sprache, ein Compiler oder Editor verwendet wird. Kleinere, zusammensetzbare Tools ergeben bessere Systeme als „ein Tool, um sie alle zu beherrschen“-Tools.

Die von Ihnen beschriebene Lösung baut nichts schneller, als es auf einem einzelnen Computer getan hätte, oder? Wenn mein Projekt (unter anderem) zwei unabhängige Bibliotheken enthält, würde ein verteiltes Build-System jede auf einer separaten Maschine erstellen. Das ist der Sinn der Frage.
Wird Jenkins also in der Lage sein, einige der Zwischenziele auf jeder Maschine zu bauen und sie dann auf verschiedenen Maschinen zusammenzubringen, um zusätzliche Zwischenziele zu bauen? Das klingt nach deiner Beschreibung nicht so. Zumal du es als "Layer" beschreibst. Ich möchte keine weitere Ebene, ich möchte die vorhandene Ebene durch etwas Verteiltes ersetzen.
Das Problem der Verteilung der Arbeit liegt bei Ihnen. Klingt, als wolltest du Magie. Es gibt kein automatisch verteiltes mehrsprachiges verteiltes Build-System. Sie müssen die Arbeit selbst in Stücke teilen, wie es jeder andere Build-System-Designer immer tut. Wenn Sie erwarten, dass ein Magic-Build-System zuerst koordiniert, wer was tut, und garantiert, dass es keine Überschneidungen gibt und garantiert, dass es schneller ist als ein einzelner System-Build, dann stellen Sie ein Optimierungsproblem mit mehreren widersprüchlichen Einschränkungen dar, die im Wesentlichen nicht gleichzeitig gelöst werden können. Mehrere Schichten NP-hart.
Was vernünftige Ingenieure tun, ist, die gemeinsam genutzte Bibliothek als Teil einer Pipeline zu konstruieren und Phasen ihrer Arbeit als Teil ihres Build-Systemdesigns zu erstellen. Sie tun dies in Jenkins, und wenn ein gemeinsam genutztes Artefakt abgeschlossen ist, erstellen sie die sekundären Stufen, die von der Bibliothek selbst abhängen. Es liegt an IHNEN als Build-System-Designer, die Aufgaben zu erstellen und zuzuweisen. Jenkins "Sklaven" tun, was Sie befehlen, sie organisieren sich nicht selbst und weisen Aufgaben nicht automatisch zu.
Beachten Sie, dass Sie den Build beschleunigen können, indem Sie ihn in eine Reihe von Aufgaben aufteilen und Jenkins „Slave“-Instanzen verwenden, um den eigentlichen Build durchzuführen. Zwischenergebnisse können bei Bedarf zwischen Maschinen weitergegeben werden. wiki.jenkins-ci.org/display/JENKINS/Distributed+builds ist lesenswert.
Das Gleiche wird auch automatisch durch die Verwendung von Gitlab CI erreicht. Sobald Sie die manuelle Arbeit zum Aufteilen Ihrer Jobs erledigt haben (innerhalb der .gitlab-ci.yml-Datei, die der travis CI yml oder einer Jenkins 2.0-Jenkins-Datei sehr ähnlich ist), werden Ihren Runnern (CI Multi-Runnern) verfügbare Jobs zugewiesen.

Keine perfekte Lösung, aber das Distributed Plugin von CruiseControl ermöglicht eine rudimentäre Form der Build-Verteilung:

[...] ermöglicht es einem Master-Build-Rechner, Build-Anforderungen an andere physische Rechner zu verteilen, auf denen die Builds ausgeführt werden, und die Ergebnisse an den Master zurückzugeben.

Ihr Build-Skript sieht folgendermaßen aus:

<distributed>
    <ant antscript="ant.bat"
        antworkingdir="C:/cruise-control-agent/checkout/BasicJavaProject" >
    </ant>
</distributed>

Die Ant-Aufgabe wird nicht auf dem Computer ausgeführt, auf dem CruiseControl („Master“) ausgeführt wird, sondern von einem der verfügbaren Agentencomputer (separate Computer, auf denen eine bestimmte Agentensoftware ausgeführt wird).

Sie können Agenten so filtern, dass eine bestimmte Aufgabe beispielsweise nur auf einem Linux 64-Bit-Agenten ausgeführt wird.

Unterstützte Sub-Build-Befehle: ant, maven, maven2, nant, phing, rake, exec, pipedexec, xcode

Schwachstelle: Abhängigkeiten werden vom System nicht aufgelöst. Sie müssen sie selbst finden und dann Ihr Build-Skript entsprechend schreiben.

Kostenlos, Open-Source.

es erlaubt mir nicht, meinen CMake/make-Build zu verteilen “: Ihre Frage verlangt das auch nicht. Ihre Frage fragt nach einem verteilten Build-System und erfordert nicht, dass es mit Ihren vorhandenen Cmake/make-Skripten kompatibel ist.
Lassen Sie mich umformulieren. Es scheint, als würde es mir nicht erlauben, das Erstellen von Zwischenzielen in einem C/C++-Projekt auf verschiedene Maschinen zu verteilen, die dann auf verschiedene Maschinen kopiert würden, um zusätzliche Zwischenziele usw. zu erstellen. Aber lassen Sie mich meine Frage bearbeiten, um dies zu verdeutlichen .