IDE-Integration

Meson bietet Exporter für Visual Studio und XCode, aber das Schreiben eines benutzerdefinierten Backends für jede verfügbare IDE ist kein skalierbarer Ansatz. Um dieses Problem zu lösen, bietet Meson eine API, die es jeder IDE oder jedem Build-Tool erleichtert, Meson-Builds zu integrieren und eine Erfahrung zu bieten, die mit einer nativen Lösung für die IDE vergleichbar ist.

Alle für eine solche IDE-Integration erforderlichen Ressourcen finden Sie im Verzeichnis meson-info im Build-Verzeichnis.

Das erste, was Sie tun müssen, wenn Sie ein Meson-Projekt in einer IDE einrichten, ist die Auswahl der Quell- und Build-Verzeichnisse. Für dieses Beispiel gehen wir davon aus, dass sich die Quelle in einem Eclipse-ähnlichen Verzeichnis namens workspace/project befindet und der Build-Baum darin als workspace/project/build verschachtelt ist. Zuerst initialisieren wir Meson, indem wir den folgenden Befehl im Quellverzeichnis ausführen.

meson setup builddir

Mit diesem Befehl konfiguriert Meson das Projekt und generiert auch Introspektionsinformationen, die in den Dateien intro-*.json im Verzeichnis meson-info gespeichert werden. Der Introspektions-Dump wird automatisch aktualisiert, wenn Meson (neu) konfiguriert wird oder sich die Build-Optionen ändern. Somit kann eine IDE auf Änderungen in diesem Verzeichnis achten, um zu wissen, wann sich etwas geändert hat. Beachten Sie, dass meson-info.json garantiert die zuletzt geschriebene Datei ist.

Das Verzeichnis meson-info sollte die folgenden Dateien enthalten

Datei Beschreibung
intro-benchmarks.json Listet alle Benchmarks auf
intro-buildoptions.json Enthält eine vollständige Liste der Meson-Konfigurationsoptionen für das Projekt
intro-buildsystem_files.json Vollständige Liste aller Meson-Build-Dateien
intro-dependencies.json Listet alle im Projekt verwendeten Abhängigkeiten auf
intro-installed.json Enthält eine Zuordnung von Dateien zu ihrem Installationsort
intro-install_plan.json Wörterbuch von Datentypen mit den Quelldateien und ihren Installationsdetails
intro-projectinfo.json Speichert grundlegende Informationen über das Projekt (Name, Version usw.)
intro-targets.json Vollständige Liste aller Build-Ziele
intro-tests.json Listet alle Tests mit Anweisungen zur Ausführung auf

Der Inhalt der JSON-Dateien wird im Rest dieses Dokuments näher erläutert.

Der Abschnitt targets

Die wahrscheinlich wichtigste Datei für eine IDE ist intro-targets.json. Hier sind die einzelnen Ziele mit ihren Quellen und Compilerparametern aufgeführt. Das JSON-Format für ein Ziel ist wie folgt definiert

{
    "name": "Name of the target",
    "id": "The internal ID meson uses",
    "type": "<TYPE>",
    "defined_in": "/Path/to/the/targets/meson.build",
    "subproject": null,
    "filename": ["list", "of", "generated", "files"],
    "build_by_default": true / false,
    "target_sources": [],
    "extra_files": ["/path/to/file1.hpp", "/path/to/file2.hpp"],
    "installed": true / false,
}

Wenn der Schlüssel installed auf true gesetzt ist, ist auch der Schlüssel install_filename vorhanden. Er speichert den Installationsort für jede Datei in filename. Wenn eine Datei in filename nicht installiert ist, ist ihr entsprechender Installationsort auf null gesetzt.

Der Schlüssel subproject gibt den Namen des Unterprojekts an, in dem dieses Ziel definiert wurde, oder null, wenn das Ziel im Top-Level-Projekt definiert wurde.

(Neu seit 0.56.0) Der Schlüssel extra_files listet alle Dateien auf, die über das extra_files-Keyword-Argument eines Build-Ziels angegeben wurden. Siehe executable().

Ein Ziel generiert normalerweise nur eine Datei. Es ist jedoch möglich, dass benutzerdefinierte Ziele mehrere Ausgaben haben.

Zielquellen

Die Datei intro-targets.json speichert auch eine Liste aller Quellobjekte des Ziels in target_sources. Mit diesen Informationen kann eine IDE Code-Vervollständigung für alle Quelldateien bereitstellen.

{
    "language": "language ID",
    "compiler": ["The", "compiler", "command"],
    "parameters": ["list", "of", "compiler", "parameters"],
    "sources": ["list", "of", "all", "source", "files", "for", "this", "language"],
    "generated_sources": ["list", "of", "all", "source", "files", "that", "where", "generated", "somewhere", "else"]
}

Es sei darauf hingewiesen, dass die in parameters gespeicherten Compilerparameter von den tatsächlich zum Kompilieren der Datei verwendeten Parametern abweichen. Dies liegt daran, dass die Parameter für die Verwendung in einer IDE zur Unterstützung der Autovervollständigung usw. optimiert sind. Daher wird nicht empfohlen, diese Introspektionsinformationen für die tatsächliche Kompilierung zu verwenden.

Mögliche Werte für type

Die folgende Tabelle zeigt alle gültigen Typen für ein Ziel.

Wert von type Beschreibung
executable Dieses Ziel generiert eine ausführbare Datei
static library Ziel für eine statische Bibliothek
shared library Ziel für eine freigegebene Bibliothek
shared module Eine freigegebene Bibliothek, die eher mit dlopen verwendet werden soll, anstatt in etwas anderes zu linken
custom Ein benutzerdefiniertes Ziel
run Ein Meson-Run-Ziel
jar Ein Java-JAR-Ziel

Installationsplan

Die Datei intro-install_plan.json enthält eine Liste der Dateien, die auf dem System installiert werden.

Die Daten enthalten eine Liste von Dateien, gruppiert nach Datentyp. Jede Datei wird einem Wörterbuch zugeordnet, das die Schlüssel destination und tag enthält, wobei der Schlüssel der Dateipfad zur Build-Zeit ist. destination ist der Zielpfad mit Platzhaltern für die Basisverzeichnisse. Zukünftig können neue Schlüssel hinzugefügt werden.

{
    "targets": {
        "/path/to/project/builddir/some_executable": {
            "destination": "{bindir}/some_executable",
            "tag": "runtime"
        },
        "/path/to/project/builddir/libsomelib.so": {
            "destination": "{libdir_shared}/libsomelib.so",
            "tag": "runtime"
        }
    },
    "data": {
        "/path/to/project/some_data": {
            "destination": "{datadir}/some_data",
            "tag": null
        }
    },
    "headers": {
        "/path/to/project/some_header.h": {
            "destination": "{includedir}/some_header.h",
            "tag": "devel"
        }
    }
}

Zusätzlich enthält die Datei intro-installed.json die Zuordnung des Dateipfads zur Build-Zeit zum absoluten Systempfad.

{
    "/path/to/project/builddir/some_executable": "/usr/bin/some_executable",
    "/path/to/project/builddir/libsomelib.so": "/user/lib/libsomelib.so",
    "/path/to/project/some_data": "/usr/share/some_data",
    "/path/to/project/some_header.h": "/usr/include/some_header.h"
}

Verwendung von --targets ohne Build-Verzeichnis

Es ist auch möglich, die meisten Ziele ohne Build-Verzeichnis abzurufen. Dies kann durch Ausführen von meson introspect --targets /Pfad/zu/meson.build geschehen.

Die generierte Ausgabe ähnelt der Introspektion mit einem Build-Verzeichnis oder dem Lesen von intro-targets.json. Es gibt jedoch einige wichtige Unterschiede

  • Die Pfade in filename sind nun *relativ* zum zukünftigen Build-Verzeichnis
  • Der Schlüssel install_filename fehlt vollständig
  • Es gibt nur einen Eintrag in target_sources
    • Mit der Sprache auf unknown gesetzt
    • Leere Listen für compiler und parameters sowie generated_sources
    • Die Liste sources *sollte* alle Quellen des Ziels enthalten

Es gibt keine Garantie, dass die Liste der Quellen in target_sources korrekt ist. Es kann Unterschiede aufgrund interner Einschränkungen geben. Es ist auch nicht garantiert, dass alle Ziele in der Ausgabe aufgeführt werden. Es ist sogar möglich, dass Ziele aufgeführt werden, die bei einem normalen Meson-Lauf nicht existieren. Dies kann passieren, wenn ein Ziel innerhalb einer if-Anweisung definiert ist. Verwenden Sie diese Funktion mit Vorsicht.

Build-Optionen

Die Liste aller Build-Optionen (Build-Typ, Warnlevel usw.) wird in der Datei intro-buildoptions.json gespeichert. Hier ist das JSON-Format für jede Option.

{
    "name": "name of the option",
    "description": "the description",
    "type": "type ID",
    "value": "value depends on type",
    "section": "section ID",
    "machine": "machine ID"
}

Die unterstützten Typen sind

  • string
  • boolean
  • combo
  • integer
  • array

Für den Typ combo ist auch der Schlüssel choices vorhanden. Hier werden alle gültigen Werte für die Option gespeichert.

Die möglichen Werte für section sind

  • core
  • backend
  • base
  • compiler
  • directory
  • user
  • test

Der Schlüssel machine gibt die Maschinenkonfiguration für die Option an. Mögliche Werte sind

  • any
  • host
  • build

Um die Optionen festzulegen, verwenden Sie den Befehl meson configure.

Seit Meson 0.50.0 ist es auch möglich, die Standard-Build-Optionen ohne Build-Verzeichnis zu erhalten, indem Sie die Root-meson.build anstelle eines Build-Verzeichnisses an meson introspect --buildoptions übergeben.

Das Ausführen von --buildoptions ohne Build-Verzeichnis erzeugt dieselbe Ausgabe wie die Ausführung mit einem frisch konfigurierten Build-Verzeichnis.

Dieses Verhalten ist jedoch nicht garantiert, wenn Unterprojekte vorhanden sind. Aufgrund interner Einschränkungen werden alle Unterprojekte verarbeitet, auch wenn sie in einem echten Meson-Lauf nie verwendet werden. Aus diesem Grund können die Optionen für die Unterprojekte abweichen.

Der Abschnitt Abhängigkeiten

Die Liste aller *gefundenen* Abhängigkeiten kann aus intro-dependencies.json abgerufen werden. Hier werden der Name, die Version sowie die Compiler- und Linker-Argumente für eine Abhängigkeit aufgelistet.

Abhängigkeiten scannen mit --scan-dependencies

Es ist auch möglich, die meisten verwendeten Abhängigkeiten ohne Build-Verzeichnis abzurufen. Dies kann durch Ausführen von meson introspect --scan-dependencies /Pfad/zu/meson.build geschehen.

Das Ausgabeformat ist wie folgt

[
  {
    "name": "The name of the dependency",
    "required": true,
    "version": [">=1.2.3"],
    "conditional": false,
    "has_fallback": false
  }
]

Das Schlüsselwort required gibt an, ob die Abhängigkeit in der meson.build als erforderlich markiert ist (alle Abhängigkeiten sind standardmäßig erforderlich). Der Schlüssel conditional gibt an, ob die Funktion dependency() innerhalb eines bedingten Blocks aufgerufen wurde. In einem echten Meson-Lauf werden diese Abhängigkeiten möglicherweise nicht verwendet, daher sind sie *möglicherweise* nicht erforderlich, auch wenn der Schlüssel required gesetzt ist. Der Schlüssel has_fallback gibt nur an, ob ein Fallback direkt in der Funktion dependency() gesetzt wurde. Der Schlüssel version enthält immer eine Liste von Versionsanforderungen aus der meson.build und *nicht* die tatsächliche Version der Abhängigkeit auf der Festplatte. Die Versionsliste ist leer, wenn keine Version in der meson.build angegeben wurde.

Tests

Kompilierung und Unit-Tests werden wie üblich durch Ausführen der Befehle meson compile und meson test durchgeführt. Ein JSON-formatiertes Ergebnisprotokoll finden Sie unter workspace/project/builddir/meson-logs/testlog.json.

Wenn diese Tests fehlschlagen, möchte der Benutzer den fehlgeschlagenen Test wahrscheinlich in einem Debugger ausführen. Um dies so integriert wie möglich zu gestalten, extrahieren Sie die Tests aus den Dateien intro-tests.json und intro-benchmarks.json. Dies liefert Ihnen alle Informationen, die Sie benötigen, um den Test auszuführen: welcher Befehl ausgeführt werden soll, Befehlszeilenargumente, Umgebungsvariableneinstellungen und wie die Ausgabe verarbeitet werden soll.

{
    "name": "name of the test",
    "workdir": "the working directory (can be null)",
    "timeout": "the test timeout",
    "suite": ["list", "of", "test", "suites"],
    "is_parallel": true / false,
    "protocol": "exitcode" / "tap",
    "cmd": ["command", "to", "run"],
    "depends": ["target1-id", "target2-id"],
    "env": {
        "VARIABLE1": "value 1",
        "VARIABLE2": "value 2"
    }
}

Der Eintrag depends * (seit 0.56.0) * enthält Ziel-IDs; sie können in den Zieldaten der Introspektion nachgeschlagen werden. Die ausführbare Datei, auf die cmd verweist, ist ebenfalls im Eintrag enthalten, ebenso wie alle Argumente für den Test, die Build-Produkte sind.

Build-System-Dateien

Es ist auch möglich, Meson-Build-Dateien zu erhalten, die in Ihrem aktuellen Projekt verwendet werden. Dies kann durch Ausführen von meson introspect --buildsystem-files /Pfad/zu/builddir geschehen.

Das Ausgabeformat ist wie folgt

[
    "/Path/to/the/targets/meson.build",
    "/Path/to/the/targets/meson.options",
    "/Path/to/the/targets/subdir/meson.build"
]

Programmatische Schnittstelle

Meson bietet auch meson introspect für die Projektinspektion über die Befehlszeile. Verwenden Sie meson introspect -h, um alle verfügbaren Optionen anzuzeigen.

Diese API kann auch ohne Build-Verzeichnis für den Befehl --projectinfo funktionieren.

AST einer meson.build

Seit Meson *0.55.0* ist es möglich, den AST einer meson.build als JSON-Objekt auszugeben. Die Schnittstelle hierfür ist meson introspect --ast /Pfad/zu/meson.build.

Jeder Knoten des AST hat mindestens die folgenden Einträge

Schlüssel Beschreibung
node Typ des Knotens (siehe folgende Tabelle)
lineno Zeilennummer des Knotens in der Datei
colno Spaltennummer des Knotens in der Datei
end_lineno Markiert das Ende des Knotens (kann dasselbe wie lineno sein)
end_colno Markiert das Ende des Knotens (kann dasselbe wie colno sein)

Mögliche Werte für node mit zusätzlichen Schlüsseln

Knotentyp Zusätzliche Schlüssel
BooleanNode value: bool
IdNode value: str
NumberNode value: int
StringNode value: str
ContinueNode
BreakNode
ArgumentNode positional: node list; kwargs: accept_kwargs
ArrayNode args: node
DictNode args: node
EmptyNode
OrNode left: node; right: node
AndNode left: node; right: node
ComparisonNode left: node; right: node; ctype: str
ArithmeticNode left: node; right: node; op: str
NotNode right: node
CodeBlockNode lines: node list
IndexNode object: node; index: node
MethodNode object: node; args: node; name: str
FunctionNode args: node; name: str
AssignmentNode value: node; var_name: str
PlusAssignmentNode value: node; var_name: str
ForeachClauseNode items: node; block: node; varnames: list
IfClauseNode ifs: node list; else: node
IfNode condition: node; block: node
UMinusNode right: node
TernaryNode condition: node; true: node; false: node

Wir garantieren keine Stabilität dieses Formats, da es stark an die interne Meson AST gebunden ist. Brüche (Entfernung eines Knotentyps oder eines Schlüssels) sind jedoch unwahrscheinlich und werden in den Release Notes angekündigt.

JSON-Referenzhandbuch

Zusätzlich zum Online- Referenzhandbuch bietet Meson das Handbuch auch als JSON-Datei an. Der Inhalt dieser Datei wird aus derselben Quelle generiert wie die Online-Dokumentation. Die beiden Versionen sind somit inhaltlich identisch.

Dieses JSON-Dokument ist jeder Meson-Version seit *0.60.0* beigefügt. Das JSON-Schema wird durch die Klassenstruktur in jsonschema.py definiert

Bestehende Integrationen

Die Ergebnisse der Suche sind