BitBucket mit CMake und Caches
« | 09 May 2020 | »Der Source-Hoster BitBucket bietet neben GIT zur reinen Quellcodeverwaltung auch Tools zum automatischen Bauen von Software an. Dieses Continuous Integration Features (oder kurz “CI”) bietet Support für unterschiedliche Werkzeuge für alles mögliche Zeugs von dotNET Core bis Java.
Das wichtigste fehlt natürlich: nämlich CMake. Zum Glück kann man sich das aber selbst hinbiegen.
Kein CMake auf BitBucket?
OK, bevor man mir vorwirft die Unwahrheit zu sagen, sollte man präzisieren:
BitBucket bietet kein fertiges Docker
Image an, auf welchem CMake
vorkonfiguriert ist, lässt einen aber andere
Images vom Docker Hub einbinden.
Aber “nur wegen” einem “kleinen” C oder C++ Projekt habe ich keine Lust extern auch noch an Docker herumzudoktoren (zumindest heute nicht).
Die Frage ist daher:
Kann man nicht ein Standard-Image so “umkonfigurieren”, dass es CMake builds anstoßen kann?
Die Antwort lautet: Ja
Man muss nur bei jedem Build-Vorgang die nötigen Tools und Bibliotheken
nachinstallieren. Und nachdem die BitBucket Images auf Ubuntu Linux
basieren, reicht ein entsprechendes apt-get
aus.
Die Lösung: apt-get install cmake
Liegt im Root eines BitBucket-Repositories eine Datei namens
bitbucket-pipelines.yml
mit korrektem Inhalt, startet nach jedem Code-Update
die Build-Pipeline.
Kostenlos stehen einem im Monat 50 Minuten Build-Zeit zur Verfügung, wer mehr
braucht, kann natürlich Münzen einwerfen.
Mein ursprüngliches yml
Script für das GATE Projekt sah so aus:
1image: 2 name: atlassian/default-image:2 3pipelines: 4 default: 5 - step: 6 name: Build 7 script: 8 - apt-get update -qq 9 - apt-get install cmake libasound2-dev -y --force-yes 10 - apt-get install v4l-utils libv4l-dev -y --force-yes 11 - apt-get install unixodbc-dev libgtk-3-dev -y --force-yes 12 - mkdir -p build-cmake 13 - cd build-cmake 14 - cmake ../src 15 - make
Das default-image:2
sollte benutzt werden, weil es auf Ubuntu 16.04 aufbaut.
Fehlt dieser Eintrag, so landet man beim Image 1
mit Ubuntu 14.04 und dort
ist CMake nur schwer veraltet nachinstallierbar und auch das nur nach dem
Hinzufügen entsprechender Installationsquellen aus dem Netz.
Der Ablauf sieht in etwa so aus:
- Wir aktualisieren
apt
auf den neuesten Stand und installieren dannCMake
und alle anderen Entwicklungsbibliotheken für unsere Zwecke. - Wir erzeugen ein Unterverzeichnis, in dem CMake arbeiten können soll.
- Wir wechseln in dieses Verzeichnis und führen dort
cmake
so aus, dass es die Dateien aus den Quellcodeverzeichnis abarbeitet. Beim GATE Projekt ist das/src
und somit muss der relative Pfad../src
für CMake benutzt werden. - Danach wird einfach
make
aufgerufen, das die von CMake generierten Anweisungen ausführt.
That’s it!
Caches
Seit noch gar nicht so lange (Stand 2020) bewirbt BitBucket, dass es nun
“Caches” unterstützt.
Während normalerweise jeder Build-Vorgang mit einem leeren Image
beginnt, können mit aktivierten Caches die Ergebnisse eines Builds bzw. die
Inhalte von bestimmten Verzeichnissen gesichert und beim folgenden Build
weiter benutzt werden.
Anfangs dachte ich mir:
Hey das ist DIE Lösung für das Nachinstallieren von Programmen.
Doch Fehlanzeige! Zwar kann man teilweise die apt
Ergebnisse sichern, doch
das Herunterladen dieser Datenmengen dauert genau so lange, wie wenn man die
Installation gleich von vorne beginnt … zumindest bei meinen Paketen
verhält es sich so.
Aber an einer anderen Stelle bewirken “Caches” kleine Wunder:
Und zwar bei den CMake
und make
Build-Verzeichnissen.
Die sind nur einige Megabytes groß und können daher relativ schnell gesichert und wiederhergestellt werden, aber die Ersparnis beim Kompilieren, wo nur noch Änderungen übersetzt werden müssen, ist enorm.
Mein finales GATE Script sieht daher so aus:
1image: 2 name: atlassian/default-image:2 3pipelines: 4 default: 5 - step: 6 name: Build 7 caches: 8 - buildjob 9 script: 10 - rm -rf build-cmake/bin-output 11 - apt-get update -qq 12 - apt-get install cmake libasound2-dev -y --force-yes 13 - apt-get install v4l-utils libv4l-dev -y --force-yes 14 - apt-get install unixodbc-dev libgtk-3-dev -y --force-yes 15 - cmake --version 16 - mkdir -p build-cmake 17 - cd build-cmake 18 - cmake ../src 19 - make 20 - cd .. 21 artifacts: 22 - build-cmake/bin-output/** 23definitions: 24 caches: 25 buildjob: build-cmake
Fazit
Ohne Caches braucht ein gesamter Build zwischen 3,5 und 4 Minuten.
Davon etwa 30 Sekunden upload/download von Daten, etwa 30 Sekunden für apt
,
und der Rest sind CMake
und make
, also zwischen 2 und 3 Minuten.
Abhängig von der Menge der Änderungen dauert ein “inkrementeller” Build mit
Caches aber ebenso nur noch 30 Sekunden.
Das liegt vor allem an der libreSSL.
Diese wird von mir (außer bei halbjährlichen Updates) nicht geändert und macht
den Großteil der Buildzeit aus.
Die GATE Sourcen sind da genügsamer und in etwa 30 Sekunden durchgeackert. Und da im kostenlosen Angebot nur 50 Minuten pro Monat für Buildpipelines inkludiert sind, macht sich der Cache durchaus “bezahlt”.
Abschließend wird innerhalb von CMAKE mit
1set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin-output 2 CACHE PATH "Shared library target directory") 3set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin-output 4 CACHE PATH "Executable target directory") 5set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin-output 6 CACHE PATH "Static library target directory")
definiert, dass die Resultate im Verzeichnis bin-output
untergebracht
werden sollen. Dieses wandert dann ins Build-Artifactory und somit kann das
Ergebnis eines Builds bequem als ZIP heruntergeladen werden.
Ursprünglich dachte ich
Ach was, das brauch ich doch nicht.
Doch nun gefällt mir der BitBucket Linux Build mehr und mehr, vor allem wenn ich von Extern mal schnell die aktuellste Version eines Tools für Linux brauche.
Jetzt fehlt mir noch ein Windows-Build … doch der ist (vorerst) hier nicht zu bekommen.
PS: Natürlich kann man mit make -j4
durch Parallelisierung auch die
Build-Zeit reduzieren, doch da die Ressourcen von mehreren Usern gebraucht
werden, gibt es keine Garantie, dass schnell gebaut wird. Die Reduktion
des Build-Materials ist also immer eine gute Idee.