Wrap-Abhängigkeitssystem-Handbuch
Eines der größten Probleme bei der plattformübergreifenden Entwicklung ist die Verwaltung all Ihrer Abhängigkeiten. Dies ist auf vielen Plattformen umständlich, insbesondere auf denen, die keinen integrierten Paketmanager haben. Letzteres Problem wurde durch die Verwendung von Drittanbieter-Paketmanagern umgangen. Sie sind keine wirkliche Lösung für die Endbenutzer-Bereitstellung, da Sie ihnen nicht befehlen können, einen Paketmanager zu installieren, nur um Ihre App zu verwenden. Auf diesen Plattformen müssen Sie eigenständige Anwendungen erstellen. Dasselbe gilt, wenn auf der Zielplattform (aktuelle Versionen) der Abhängigkeiten Ihrer Anwendung fehlen.
Der traditionelle Ansatz dafür war, Abhängigkeiten in Ihr eigenes Projekt zu bündeln. Entweder als vorkompilierte Bibliotheken und Header oder durch Einbetten des Quellcodes in Ihren Quellcodebaum und Umschreiben Ihres Build-Systems, um sie als Teil Ihres Projekts zu erstellen.
Dies ist sowohl mühsam als auch fehleranfällig, da es immer von Hand geschieht. Das Wrap-Abhängigkeitssystem von Meson zielt darauf ab, eine automatisierte Möglichkeit hierfür bereitzustellen.
Wie es funktioniert
Meson hat das Konzept von Subprojekten. Dies ist eine Möglichkeit, ein Meson-Projekt in ein anderes zu verschachteln. Jedes Projekt, das mit Meson erstellt wird, kann erkennen, dass es als Subprojekt erstellt wird, und sich so erstellen, dass es leicht zu verwenden ist (normalerweise bedeutet dies als statische Bibliothek).
Um diese Art von Projekt als Abhängigkeit zu verwenden, könnten Sie es einfach kopieren und in das Verzeichnis subprojects Ihres Projekts extrahieren.
Es gibt jedoch einen einfacheren Weg. Sie können eine Wrap-Datei angeben, die Meson mitteilt, wie es diese für Sie herunterladen soll. Wenn Sie dieses Subprojekt dann in Ihrem Build verwenden, lädt Meson es während des Builds automatisch herunter und extrahiert es. Dies macht die Einbettung von Subprojekten extrem einfach.
Alle Wrap-Dateien müssen den Namen im Format <project_name>.wrap haben und sich im Verzeichnis subprojects befinden.
Derzeit hat Meson vier Arten von Wraps
- wrap-file
- wrap-git
- wrap-hg
- wrap-svn
Wrap-Format
Wrap-Dateien werden im Ini-Format geschrieben, mit einer einzigen Kopfzeile, die den Typ des Wraps enthält, gefolgt von Eigenschaften, die beschreiben, wie die Quellen bezogen, validiert und bei Bedarf modifiziert werden. Eine Beispiel-Wrap-Datei für den Wrap namens libfoobar hätte den Dateinamen libfoobar.wrap und würde wie folgt aussehen
[wrap-file]
directory = libfoobar-1.0
source_url = https://example.com/foobar-1.0.tar.gz
source_filename = foobar-1.0.tar.gz
source_hash = 5ebeea0dfb75d090ea0e7ff84799b2a7a1550db3fe61eb5f6f61c2e971e57663
Ein Beispiel für wrap-git sieht so aus
[wrap-git]
url = https://github.com/libfoobar/libfoobar.git
revision = head
depth = 1
Akzeptierte Konfigurationseigenschaften für Wraps
-
directory- Name des Stammverzeichnisses des Subprojekts, standardmäßig der Name des Wraps.
Seit 0.55.0 können diese in allen Wrap-Typen verwendet werden, sie waren zuvor für wrap-file reserviert
-
patch_url- Download-URL zum Abrufen eines optionalen Overlay-Archivs -
patch_fallback_url- Fallback-URL, die verwendet wird, wenn der Download vonpatch_urlfehlschlägt Seit: 0.55.0 -
patch_filename- Dateiname des heruntergeladenen Overlay-Archivs -
patch_hash- SHA256-Checksumme des heruntergeladenen Overlay-Archivs -
patch_directory- Seit 0.55.0 Overlay-Verzeichnis, Alternative zupatch_filename, falls Dateien lokal und kein heruntergeladenes Archiv sind. Das Verzeichnis muss insubprojects/packagefilesabgelegt werden. -
diff_files- Seit 0.63.0 Kommagetrennte Liste lokaler Diff-Dateien (siehe Diff-Dateien unten). -
method- Seit 1.3.0 Das von diesem Subprojekt verwendete Build-System. Standardmäßigmeson. Unterstützte Methoden-
mesonerfordert eine Dateimeson.build. -
cmakeerfordert eine DateiCMakeLists.txt. Details siehe. -
cargoerfordert eine DateiCargo.toml. Details siehe.
-
Speziell für wrap-file
-
source_url- Download-URL zum Abrufen des Quellarchivs der Wrap-Datei -
source_fallback_url- Fallback-URL, die verwendet wird, wenn der Download vonsource_urlfehlschlägt Seit: 0.55.0 -
source_filename- Dateiname des heruntergeladenen Quellarchivs -
source_hash- SHA256-Checksumme des heruntergeladenen Quellarchivs -
lead_directory_missing- fürwrap-file, um den Namen des führenden Verzeichnisses zu erstellen. Benötigt, wenn die Quelldatei kein führendes Verzeichnis hat.
Seit 0.55.0 ist es möglich, in einer .wrap-Datei nur die Werte source_filename und patch_filename (ohne source_url und patch_url) zu verwenden, um ein lokales Archiv im Verzeichnis subprojects/packagefiles anzugeben. Die Einträge *_hash sind bei dieser Methode optional. Diese Methode sollte gegenüber dem alten Ansatz packagecache, der unten beschrieben wird, bevorzugt werden.
Seit 0.49.0 wird die Datei source_filename oder patch_filename, wenn sie im Verzeichnis subprojects/packagecache des Projekts gefunden wird, anstelle des Herunterladens verwendet, selbst wenn die Option --wrap-mode auf nodownload gesetzt ist. Die Hash-Prüfung der Datei wird durchgeführt.
Seit 1.3.0 wird, wenn die Umgebungsvariable MESON_PACKAGE_CACHE_DIR gesetzt ist, diese anstelle von subprojects/packagecache des Projekts verwendet. Dies ermöglicht die gemeinsame Nutzung des Caches über mehrere Projekte hinweg. Zusätzlich kann sie einen bereits extrahierten Quellcodebaum enthalten, solange er denselben Verzeichnisnamen wie das Feld directory in der Wrap-Datei hat. In diesem Fall wird das Verzeichnis vor dem Anwenden von Patches nach subprojects/ kopiert.
Speziell für VCS-basierte Wraps
-
url- Name des zu klonenden Git-Repositorys. Erforderlich. -
revision- Name der auszucheckenden Revision. Muss entweder ein gültiger Wert (wie ein Git-Tag) für dencheckout-Befehl des VCS sein oder (für Git)head, um den Standardzweig des Upstreams zu verfolgen. Erforderlich.
Speziell für wrap-git
-
depth- klont das Repository flach mit X Commits. Dies spart Bandbreite und Speicherplatz und sollte normalerweise immer angegeben werden, es sei denn, der Commit-Verlauf wird benötigt. Beachten Sie, dass Git immer flaches Klonen von Branches erlaubt, aber um Commit-IDs flach zu klonen, muss der Serveruploadpack.allowReachableSHA1InWant=trueunterstützen. (seit 0.52.0) -
push-url- alternative URL zur Konfiguration als Git-Push-URL. Nützlich, wenn das Subprojekt entwickelt und Änderungen an den Upstream gesendet werden. (seit 0.37.0) -
clone-recursive- klont auch Submodule des Repositorys (seit 0.48.0)
wrap-file mit Meson Build-Patch
Leider bauen die meisten Softwareprojekte auf der Welt nicht mit Meson. Aus diesem Grund erlaubt Meson die Angabe einer Patch-URL.
Aus historischen Gründen wird dies als "Patch" bezeichnet, dient aber als Overlay, um Dateien hinzuzufügen oder zu ersetzen, anstatt sie zu ändern. Die Datei muss ein Archiv sein; sie wird heruntergeladen und automatisch in das Subprojekt extrahiert. Die extrahierten Dateien enthalten eine Meson-Build-Definition für das gegebene Subprojekt.
Dieser Ansatz macht es extrem einfach, Abhängigkeiten einzubetten, die Änderungen am Build-System erfordern. Sie können die Meson-Build-Definition für die Abhängigkeit völlig isoliert schreiben. Dies ist viel besser, als dies in Ihrem eigenen Quellcodebaum zu tun, insbesondere wenn dieser Hunderttausende von Codezeilen enthält. Sobald Sie eine funktionierende Build-Definition haben, packen Sie einfach die Meson-Build-Dateien (und andere, die Sie geändert haben) in ein Zip-Archiv und legen Sie sie irgendwo ab, wo Sie sie herunterladen können.
Vor 0.55.0 wurden Meson-Build-Patches nur für den wrap-file-Modus unterstützt. Bei Verwendung von wrap-git muss das Repository alle Meson-Build-Definitionen enthalten. Seit 0.55.0 werden Meson-Build-Patches für alle Wrap-Modi unterstützt, einschließlich wrap-git.
Diff-Dateien
Seit: 0.63.0
Sie können auch lokale Patch-Dateien im diff-Format bereitstellen. Aus historischen Gründen werden sie als "Diff-Dateien" bezeichnet, da der Name "Patch" bereits für Overlay-Archive verwendet wird.
Die Diff-Dateien werden durch die Eigenschaft diff_files (eine kommagetrennte Liste) beschrieben und müssen lokal im Verzeichnis subprojects/packagefiles verfügbar sein.
Meson wendet die Diff-Dateien nach dem Extrahieren oder Klonen des Projekts und nach dem Anwenden des Overlay-Archivs (patch_*) an. Für diese Funktion muss das patch- oder git-Kommandozeilenwerkzeug verfügbar sein.
Die Diff-Dateien werden mit -p1 angewendet, d.h. die erste Pfadkomponente wird als zu entfernendes Präfix behandelt. Dies ist der Standard für Diffs, die von Git erzeugt werden.
[wrap-file]
directory = libfoobar-1.0
source_url = https://example.com/foobar-1.0.tar.gz
source_filename = foobar-1.0.tar.gz
source_hash = 5ebeea0dfb75d090ea0e7ff84799b2a7a1550db3fe61eb5f6f61c2e971e57663
diff_files = libfoobar-1.0/0001.patch, libfoobar-1.0/0002.patch
provide-Abschnitt
*Seit 0.55.0
Wrap-Dateien können die von ihnen bereitgestellten Abhängigkeiten im Abschnitt [provide] definieren.
[provide]
dependency_names = foo-1.0
Wenn eine Wrap-Datei die Abhängigkeit foo-1.0 bereitstellt, wie oben, greift jeder Aufruf von dependency('foo-1.0') automatisch auf dieses Subprojekt zurück, auch wenn kein Schlüsselwortargument fallback angegeben ist. Eine Wrap-Datei namens foo.wrap stellt implizit die Abhängigkeit namens foo bereit, auch wenn der Abschnitt [provide] fehlt.
Optionale Abhängigkeiten, wie dependency('foo-1.0', required: get_option('foo_opt')), wobei foo_opt eine Feature-Option ist, die auf auto gesetzt ist, greifen aus zwei Gründen nicht auf das in der Wrap-Datei definierte Subprojekt zurück
- Sie ermöglicht es, die Abhängigkeit zuerst auf andere Weise zu suchen, z.B. mit
cc.find_library('foo'), und greift nur dann zurück, wenn dies fehlschlägt
# this won't use fallback defined in foo.wrap
foo_dep = dependency('foo-1.0', required: false)
if not foo_dep.found()
foo_dep = cc.find_library('foo', has_headers: 'foo.h', required: false)
if not foo_dep.found()
# This will use the fallback
foo_dep = dependency('foo-1.0')
# or
foo_dep = dependency('foo-1.0', required: false, fallback: 'foo')
endif
endif
- Manchmal ist eine nicht gefundene Abhängigkeit einer Rückfallebene vorzuziehen, wenn das Feature nicht explizit vom Benutzer angefordert wurde. In diesem Fall greift
dependency('foo-1.0', required: get_option('foo_opt'))nur zurück, wenn der Benutzerfoo_optaufenabledanstatt aufautosetzt. Seit 0.58.0 greift eine optionale Abhängigkeit wie oben auf das in der Wrap-Datei definierte Subprojekt zurück, wennwrap_modeaufforcefallbackgesetzt ist oderforce_fallback_fordas Subprojekt enthält.
Wenn es gewünscht ist, für eine optionale Abhängigkeit zurückzufallen, müssen die Schlüsselwortargumente fallback oder allow_fallback explizit übergeben werden. Seit 0.56.0 verwendet dependency('foo-1.0', required: get_option('foo_opt'), allow_fallback: true) den Fallback, auch wenn foo_opt auf auto gesetzt ist. In Version 0.55.0 konnte dasselbe erreicht werden mit dependency('foo-1.0', required: get_option('foo_opt'), fallback: 'foo').
Dieser Mechanismus geht davon aus, dass das Subprojekt meson.override_dependency('foo-1.0', foo_dep) aufruft, damit Meson weiß, welches Abhängigkeitsobjekt als Fallback verwendet werden soll. Da diese Methode in Version 0.54.0 eingeführt wurde, können als Übergangshilfe für Projekte, die sie noch nicht nutzen, der Variablenname in der Wrap-Datei mit Einträgen im Format foo-1.0 = foo_dep angegeben werden.
Zum Beispiel, wenn eine ausreichend aktuelle Version von GLib verwendet wird, die meson.override_dependency() verwendet, um glib-2.0, gobject-2.0 und gio-2.0 zu überschreiben, würde eine Wrap-Datei so aussehen
[wrap-git]
url=https://gitlab.gnome.org/GNOME/glib.git
revision=glib-2-62
depth=1
[provide]
dependency_names = glib-2.0, gobject-2.0, gio-2.0
Bei älteren GLib-Versionen müssen die Abhängigkeitsvariablennamen angegeben werden
[wrap-git]
url=https://gitlab.gnome.org/GNOME/glib.git
revision=glib-2-62
depth=1
[provide]
glib-2.0=glib_dep
gobject-2.0=gobject_dep
gio-2.0=gio_dep
Programme können auch über Wrap-Dateien mit dem Schlüssel program_names bereitgestellt werden
[provide]
program_names = myprog, otherprog
Mit einer solchen Wrap-Datei greift find_program('myprog') automatisch auf das Subprojekt zurück, vorausgesetzt, es verwendet meson.override_find_program('myprog').
CMake-Wraps
Hinweis: Dies ist experimentell und hat keine Rückwärts- oder Vorwärtskompatibilitätsgarantien. Siehe Meson's Regeln zum Mischen von Build-Systemen.
Da das CMake-Modul den öffentlichen Namen der bereitgestellten Abhängigkeiten nicht kennt, kann eine CMake-.wrap-Datei nicht die Syntax dependency_names = foo verwenden. Stattdessen sollte die Syntax dep_name = <target_name>_dep verwendet werden, wobei <target_name> der Name einer CMake-Bibliothek ist, bei der alle nicht-alphanumerischen Zeichen durch Unterstriche _ ersetzt wurden.
Zum Beispiel hätte ein CMake-Projekt, das add_library(foo-bar ...) in seiner CMakeList.txt enthält und das Anwendungen normalerweise über den Abhängigkeitsnamen foo-bar-1.0 (z.B. über pkg-config) finden würden, eine Wrap-Datei wie diese
[wrap-file]
...
method = cmake
[provide]
foo-bar-1.0 = foo_bar_dep
Cargo-Wraps
Hinweis: Dies ist experimentell und hat keine Rückwärts- oder Vorwärtskompatibilitätsgarantien. Siehe Meson's Regeln zum Mischen von Build-Systemen.
Cargo-Subprojekte überschreiben automatisch den Abhängigkeitsnamen <package_name>-<version>-rs
-
package_nameist in der Sektion[package] name = ...vonCargo.tomldefiniert. -
versionist die API-Version, die aus[package] version = ...wie folgt abgeleitet wird-
x.y.z-> 'x' -
0.x.y-> '0.x' -
0.0.x-> '0' Dies ermöglicht unterschiedliche Abhängigkeiten für inkompatible Versionen desselben Crates.
-
-
Das Suffix
-rswird hinzugefügt, um es von regulären Systemabhängigkeiten zu unterscheiden, z.B.gstreamer-1.0ist eine systemweite Pkg-Config-Abhängigkeit undgstreamer-0.22-rsist eine Cargo-Abhängigkeit.
Das bedeutet, die .wrap-Datei sollte in ihrem [provide]-Abschnitt dependency_names = foo-1-rs haben, wenn Cargo.toml den Paketnamen foo und die Version 1.2 hat.
Beachten Sie, dass die Versionskomponente in Meson 1.4 hinzugefügt wurde, frühere Versionen verwendeten das Format <package_name>-rs.
Cargo-Subprojekte erfordern einen TOML-Parser. Python >= 3.11 hat einen eingebauten, ältere Python-Versionen erfordern entweder das externe Modul tomli oder das Programm toml2json.
Zum Beispiel würde ein Cargo-Projekt mit dem Paketnamen foo-bar eine Wrap-Datei wie diese haben
[wrap-file]
...
method = cargo
[provide]
dependency_names = foo-bar-0.1-rs
Zusätzlich, wenn die Datei meson/meson.build existiert, ruft Meson subdir('meson') auf, wo das Projekt manuelle Logik hinzufügen kann, die normalerweise Teil von build.rs wäre. Einige Namenskonventionen müssen beachtet werden
- Die Variable
extra_argsist vordefiniert und kann verwendet werden, um beliebige Rust-Argumente hinzuzufügen. Dies wird typischerweise alsextra_args += ['--cfg', 'foo']verwendet. - Die Variable
extra_depsist vordefiniert und kann verwendet werden, um zusätzliche Abhängigkeiten hinzuzufügen. Dies wird typischerweise alsextra_deps += dependency('foo')verwendet.
Seit 1.5.0 können Cargo-Wraps auch mit einer Cargo.lock-Datei im Stammverzeichnis des (Sub-)Projektquellbaums bereitgestellt werden. Meson lädt diese Datei automatisch und wandelt sie in eine Reihe von Wrap-Definitionen um.
Verwendung von gewrappten Projekten
Wraps bieten eine bequeme Möglichkeit, ein Projekt in Ihr Subprojektverzeichnis zu erhalten. Dann verwenden Sie es als reguläres Subprojekt (siehe Subprojekte).
Wraps erhalten
Normalerweise möchten Sie Ihre Wraps nicht von Hand schreiben.
Es gibt ein Online-Repository namens WrapDB, das viele gebrauchsfertige Abhängigkeiten bereitstellt. Sie können mehr über WrapDB hier lesen.
Es gibt auch einen Meson-Unterbefehl zum Abrufen und Verwalten von Wraps (siehe Verwendung von wraptool).
Die Ergebnisse der Suche sind