BazelCon 2022 findet vom 16. bis 17. November in New York und online statt.
Jetzt anmelden

Referenz für die {5/} Abfrage

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

Diese Seite ist das Referenzhandbuch für die Bazel Query Language, die verwendet wird, wenn Sie bazel query zur Analyse von Build-Abhängigkeiten verwenden. Außerdem werden die von bazel query unterstützten Ausgabeformate beschrieben.

Praktische Anwendungsfälle finden Sie in der Anleitung zur Bazel-Abfrage.

Zusätzliche Abfragereferenz

Neben query, das im Zieldiagramm nach der Ladephase ausgeführt wird, enthält Bazel die Aktionsgrafikabfrage und die konfigurierbare Abfrage.

Abfrage für Aktionsgrafik

Die Abfragediagrammabfrage (aquery) basiert auf dem nach der Analyse konfigurierten Zieldiagramm und liefert Informationen zu Aktionen, Artefakten und ihren Beziehungen. aquery ist nützlich, wenn Sie an den Properties der Aktionen/Artefakte interessiert sind, die aus dem konfigurierten Zieldiagramm generiert wurden. Zum Beispiel werden die eigentlichen Befehle und ihre Eingaben, Ausgaben und Gedächtnisse ausgeführt.

Weitere Informationen finden Sie in der Referenz zu Abfragen.

Konfigurierbare Abfrage

Die herkömmliche Bazel-Abfrage wird im Zieldiagramm der Phase nach dem Laden ausgeführt und hat daher kein Konzept für Konfigurationen und die zugehörigen Konzepte. Insbesondere werden Auswahlanweisungen nicht korrekt aufgelöst und stattdessen alle möglichen Auflösungen von Auswahlen zurückgegeben. Die Konfiguration cquery konfiguriert die Abfrageumgebung jedoch korrekt, bietet jedoch nicht alle Funktionen dieser ursprünglichen Abfrage.

Weitere Informationen finden Sie in der Referenz für Abfragen.

Beispiele

Wie wird bazel query verwendet? Typische Beispiele:

Warum hängt der Baum //foo von //bar/baz ab? Pfad anzeigen:

somepath(foo/..., //bar/baz:all)

Welche C++-Bibliotheken hängen von allen foo-Tests ab, wenn das Ziel foo_bin nicht?

kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo:foo_bin))

Tokens: Die lexikalische Syntax

Ausdrücke in der Abfragesprache setzen sich aus den folgenden Tokens zusammen:

  • Keywords, z. B. let Keywords sind die reservierten Wörter der Sprache und jedes davon wird unten beschrieben. Die vollständigen Keywords sind:

  • Wörter, wie "foo/..." oder ".*test rule" oder &br//bar/baz:all. Wenn eine Zeichenfolge keine Anführungszeichen enthält, wird sie möglicherweise trotzdem als Wort geparst. Wörter ohne Anführungszeichen sind Sequenzen von Zeichen aus den Buchstaben A-Za-z, die Ziffern 0-9 und die Sonderzeichen */@.-_:$~[] (Sternchen, Schrägstrich, At, Punkt, Bindestrich, Unterstrich, Doppelpunkt, Dollarzeichen, Tilde, linke eckige Klammer, rechte eckige Klammer). Wörter ohne Anführungszeichen beginnen jedoch nicht mit einem Bindestrich - oder Sternchen *, auch wenn relative [Zielnamen][(/concepts/labels#target-names) mit diesen Zeichen beginnen können.

    Wörter ohne Anführungszeichen dürfen keine Zeichen mit einem Pluszeichen + oder dem Gleichheitszeichen = enthalten, auch wenn diese Zeichen in Zielnamen zulässig sind. Beim Schreiben von Code, der Abfrageausdrücke generiert, sollten Zielnamen in Anführungszeichen gesetzt werden.

    Beim Schreiben von Skripts, mit denen Bazel-Abfrageausdrücke aus von Nutzern bereitgestellten Werten erstellt werden, ist das Anführungszeichen erforderlich.

     //foo:bar+wiz    # WRONG: scanned as //foo:bar + wiz.
     //foo:bar=wiz    # WRONG: scanned as //foo:bar = wiz.
     "//foo:bar+wiz"  # OK.
     "//foo:bar=wiz"  # OK.
    

    Beachten Sie, dass diese Anführungszeichen zusätzlich zu Anführungszeichen vorliegen, die von der Shell möglicherweise benötigt werden. Beispiele:

    bazel query ' "//foo:bar=wiz" '   # single-quotes for shell, double-quotes for Bazel.
    

    Keywords werden in Anführungszeichen als gewöhnliche Wörter behandelt. Beispiel: some ist ein Keyword, aber „einige“ ist ein Wort. Sowohl foo als auch &foot;foo" sind Wörter.

    Seien Sie jedoch vorsichtig, wenn Sie in Zielnamen einfache oder doppelte Anführungszeichen verwenden. Verwenden Sie beim Zitieren eines oder mehrerer Zielnamen nur einen Typ von Anführungszeichen (entweder alle einfachen oder alle doppelten Anführungszeichen).

    Beispiele für den Java-Abfragestring:

      'a"'a'         # WRONG: Error message: unclosed quotation.
      "a'"a"         # WRONG: Error message: unclosed quotation.
      '"a" + 'a''    # WRONG: Error message: unexpected token 'a' after query expression '"a" + '
      "'a' + "a""    # WRONG: Error message: unexpected token 'a' after query expression ''a' + '
      "a'a"          # OK.
      'a"a'          # OK.
      '"a" + "a"'    # OK
      "'a' + 'a'"    # OK
    

    Wir haben diese Syntax gewählt, damit Sie in den meisten Fällen Anführungszeichen setzen können. Das (ungewöhnliche) ".*test rule" Beispiel benötigt Anführungszeichen: Es beginnt mit einem Punkt und enthält ein Leerzeichen. Das Zitieren von "cc_library" ist unnötig, aber harmlos.

  • Zeichensetzung, z. B. Klammern (), Punkt . und Komma ,. Wörter, die Satzzeichen enthalten (außer den oben aufgeführten Ausnahmen), müssen in Anführungszeichen gesetzt werden.

Leerzeichen, die sich nicht in Anführungszeichen befinden, werden ignoriert.

Sprachkonzepte für die Bazel-Abfrage

Die Bazel-Abfragesprache ist eine Sprache von Ausdrücken. Jeder Ausdruck wertet einen partiell angeordneten Satz von Zielen oder gleichwertig einen Graph (DAG) von Zielen aus. Dies ist der einzige Datentyp.

Satz und Grafik beziehen sich auf denselben Datentyp, heben aber verschiedene Aspekte hervor. Beispiel:

  • Festlegen: Die Teilreihenfolge der Ziele ist nicht interessant.
  • Grafik: Die Teilreihenfolge der Ziele ist signifikant.

Zyklen im Abhängigkeitsdiagramm

Build-Abhängigkeitsdiagramme sollten azyklisch sein.

Die von der Abfragesprache verwendeten Algorithmen sind für die Verwendung in azyklischen Graphen gedacht. Sie sind jedoch robust gegenüber Zyklen. Die Details zur Behandlung von Zyklen sind nicht angegeben und sollten nicht als Grundlage dienen.

Implizite Abhängigkeiten

Neben den in BUILD-Dateien definierten Abhängigkeiten fügt Bazel den Regeln weitere implizite Abhängigkeiten hinzu. Beispielsweise hängt jede Java-Regel implizit von dem JavaBuilder ab. Implizite Abhängigkeiten werden mit Attributen erstellt, die mit $ beginnen und in BUILD-Dateien nicht überschrieben werden können.

Standardmäßig berücksichtigt bazel query beim Berechnen des Abfrageergebnisses implizite Abhängigkeiten. Dieses Verhalten kann mit der Option --[no]implicit_deps geändert werden. Da die Abfrage keine Konfigurationen berücksichtigt, werden potenzielle Toolchains nie berücksichtigt.

Klang

Ausdrücke in Bazel-Abfragesprache werden über das Build-Abhängigkeitsdiagramm ausgeführt. Dieses Diagramm ist implizit in allen Regeldeklarationen in allen BUILD-Dateien definiert. Es ist wichtig zu verstehen, dass dieses Diagramm etwas abstrakt ist und keine vollständige Beschreibung dafür bietet, wie alle Schritte eines Builds ausgeführt werden. Zum Ausführen eines Builds ist außerdem eine Konfiguration erforderlich. Weitere Informationen finden Sie im Abschnitt Konfigurationen des Nutzerhandbuchs.

Das Ergebnis der Auswertung eines Ausdrucks in der Bazel-Abfragesprache ist für alle Konfigurationen wahr. Dies bedeutet, dass dies ein konservativer Näherungswert sein kann, jedoch nicht genau. Wenn Sie mit dem Abfragetool alle Quelldateien berechnen, die während eines Build-Vorgangs benötigt werden, enthält der Bericht möglicherweise mehr Informationen als tatsächlich erforderlich, da das Abfragetool beispielsweise alle Dateien enthält, die für die Übersetzung von Nachrichten erforderlich sind, auch wenn Sie dieses Feature nicht in Ihrem Build verwenden möchten.

Für die Aufrechterhaltung der Grafikreihenfolge

Bei Vorgängen werden alle Sortiereinschränkungen beibehalten, die aus ihren Unterausdrücken übernommen wurden. Das ist sozusagen das Gesetz zur Erhaltung von Teilbestellungen. Beispiel: Wenn Sie eine Abfrage ausführen, um die vorübergehende Schließung von Abhängigkeiten eines bestimmten Ziels zu ermitteln, wird der resultierende Satz entsprechend der Abhängigkeitsgrafik angeordnet. Wenn Sie den Filter so festlegen, dass nur die Ziele vom Typ file enthalten sind, wird für jedes Paar von Zielen in der resultierenden Teilmenge dieselbe temporäre Teilreihenfolge-Beziehung beibehalten, auch wenn keines dieser Paare tatsächlich direkt in der ursprünglichen Grafik verbunden ist. Im Build-Abhängigkeitsdiagramm sind keine Dateidateiränder vorhanden.

Während alle Operatoren jedoch die Reihenfolge beibehalten, führen einige Vorgänge wie die Set-Vorgänge nicht zu ihren eigenen Sortiereinschränkungen. Hier ein Beispiel:

deps(x) union y

Die Reihenfolge der endgültigen Ergebnismengen garantiert garantiert die geordneten Einschränkungen der Unterausdrücke, d. h., dass alle Übergangsabhängigkeiten von x korrekt respektiert sind. Die Abfrage garantiert jedoch nichts an der Reihenfolge der Ziele in y oder in der Reihenfolge der Ziele in deps(x) im Vergleich zu den Zielen in y (außer an diesen Zielen in y, die auch in deps(x) vorkommen).

Zu den Operatoren, die Sortiereinschränkungen einführen, gehören: allpaths, deps, rdeps, somepath und die Platzhalter für das Zielmuster package:*, dir/... usw.

Sky-Suchanfrage

Sky Query ist ein Abfragemodus, der über einen festgelegten universellen Bereich arbeitet.

Spezielle Funktionen, die nur in SkyQuery verfügbar sind

Der Sky-Abfragemodus hat die zusätzlichen Abfragefunktionen allrdeps und rbuildfiles. Diese Funktionen arbeiten über den gesamten universellen Bereich, daher sind sie für die normale Abfrage nicht sinnvoll.

Universumsumfang angeben

Der Sky-Abfragemodus wird aktiviert, indem die folgenden beiden Flags übergeben werden: (--universe_scope oder --infer_universe_scope) und --order_output=no. --universe_scope=<target_pattern1>,...,<target_patternN> weist die Abfrage an, das vorübergehende Schließen des Zielmusters vorab zu laden, das von den Zielmustern angegeben wird, die sowohl additiv als auch subtraktiv sein können. Alle Abfragen werden dann in diesem Gültigkeitsbereich ausgewertet. Insbesondere geben die Operatoren allrdeps und rbuildfiles nur Ergebnisse aus diesem Bereich zurück. --infer_universe_scope weist Bazel an, einen Wert für --universe_scope aus dem Abfrageausdruck abzuleiten. Dieser abgeleitete Wert ist die Liste der eindeutigen Zielmuster im Abfrageausdruck, ist jedoch möglicherweise nicht beabsichtigt. Beispiel:

bazel query --infer_universe_scope --order_output=no "allrdeps(//my:target)"

Die Liste der eindeutigen Zielmuster in diesem Abfrageausdruck ist ["//my:target"], daher behandelt Bazel das als Aufruf:

bazel query --universe_scope=//my:target --order_output=no "allrdeps(//my:target)"

Das Ergebnis dieser Abfrage mit --universe_scope ist jedoch nur //my:target. Keine der umgekehrten Abhängigkeiten von //my:target ist im Universum. Berücksichtigen Sie andererseits Folgendes:

bazel query --infer_universe_scope --order_output=no "tests(//a/... + b/...) intersect allrdeps(siblings(rbuildfiles(my/starlark/file.bzl)))"

Dies ist ein aussagekräftiger Abfrageaufruf, mit dem versucht wird, die Testziele in der Erweiterung tests der Ziele in einigen Verzeichnissen zu berechnen, die vorübergehend von Zielen abhängen, deren Definition eine bestimmte .bzl-Datei verwendet. Hier ist --infer_universe_scope eine praktische Option, insbesondere wenn die Auswahl von --universe_scope es ansonsten erforderlich wäre, den Abfrageausdruck selbst zu parsen.

Verwenden Sie daher bei Abfrageausdrücken, die Universums-Operatoren wie allrdeps und rbuildfiles verwenden, --infer_universe_scope nur dann, wenn ihr Verhalten Ihren Vorstellungen entspricht.

Sky Query hat einige Vor- und Nachteile im Vergleich zur Standardabfrage. Der Hauptnachteil besteht darin, dass die Ausgabe nicht nach der Grafikreihenfolge sortiert werden kann und bestimmte Ausgabeformate daher nicht zulässig sind. Der Vorteil besteht darin, dass zwei Operatoren (allrdeps und rbuildfiles) zur Verfügung stehen, die in der Standardabfrage nicht verfügbar sind. Außerdem führt Sky Query die Arbeit aus, indem es die Skyframe-Grafik einführt, anstatt eine neue Grafik zu erstellen. Dies ist die Standardimplementierung. Es gibt daher einige Situationen, in denen es schneller ist und weniger Arbeitsspeicher benötigt.

Ausdrücke: Syntax und Semantik der Grammatik

Dies ist die Grammatik der Bazel-Abfragesprache in EBNF-Notation:

expr ::= word
       | let name = expr in expr
       | (expr)
       | expr intersect expr
       | expr ^ expr
       | expr union expr
       | expr + expr
       | expr except expr
       | expr - expr
       | set(word *)
       | word '(' int | word | expr ... ')'

In den folgenden Abschnitten wird jede Produktion dieser Grammatik der Reihe nach beschrieben.

Zielmuster

expr ::= word

In der Syntax ist ein Zielmuster nur ein Wort. Er wird als (ungeordneter) Satz von Zielen interpretiert. Das einfachste Zielmuster ist ein Label, das ein einzelnes Ziel (Datei oder Regel) identifiziert. Das Zielmuster //foo:bar wird beispielsweise mit einem Satz aus einem Element, dem Ziel, der Regel bar ausgewertet.

Mit Zielmustern werden Labels verallgemeinert, um Platzhalter für Pakete und Ziele einzuschließen. Beispiel: foo/...:all (oder nur foo/...) ist ein Zielmuster, das zu einem Satz mit allen Regeln in jedem Paket gehört, das rekursiv unter dem Verzeichnis foo liegt. bar/baz:all ist ein Zielmuster, das mit einem Satz ausgewertet wird, der alle Regeln im bar/baz-Paket enthält, aber nicht in seinen Unterpaketen.

Ebenso ist foo/...:* ein Zielmuster, das in einem Satz mit allen Zielen (Regeln und Dateien) in jedem Paket rekursiv unter dem Verzeichnis foo ausgewertet wird. bar/baz:* wertet einen Satz aus, der alle Ziele im Paket bar/baz enthält, jedoch nicht seine Unterpakete.

Da der Platzhalter :* sowohl mit Dateien als auch mit Regeln übereinstimmt, ist er für Abfragen oft nützlicher als :all. Umgekehrt ist der Platzhalter :all (implizit in Zielmustern wie foo/...) in der Regel für Builds besser geeignet.

bazel query-Zielmuster funktionieren genauso wie bazel build-Build-Ziele. Weitere Informationen finden Sie unter Zielmuster oder geben Sie bazel help target-syntax ein.

Zielmuster können bei einem Singleton-Set (bei einem Label), bei einem Set mit vielen Elementen (z. B. bei foo/... mit Tausenden von Elementen) oder bei einem leeren Dataset ausgewertet werden, wenn es mit keinem Ziel übereinstimmt.

Alle Knoten im Ergebnis eines Zielmusterausdrucks sind entsprechend der Abhängigkeitsbeziehung korrekt relativ zueinander. Das Ergebnis von foo:* ist also nicht nur die Gruppe von Zielen im Paket foo, sondern auch die Grafik über diese Ziele. (Es gibt keine Garantien für die relative Reihenfolge der Ergebnisknoten im Vergleich zu anderen Knoten.) Weitere Informationen finden Sie im Abschnitt Grafikreihenfolge.

Variablen

expr ::= let name = expr1 in expr2
       | $name

Die Abfragesprache von Bazel ermöglicht Definitionen und Verweise auf Variablen. Das Ergebnis der Auswertung eines let-Ausdrucks ist mit dem von expr2 identisch. Alle kostenlosen Termine der Variablen name werden durch den Wert expr1 ersetzt.

Beispielsweise entspricht let v = foo/... in allpaths($v, //common) intersect $v der allpaths(foo/...,//common) intersect foo/....

Ein Variablenverweis name, der nicht in einem umschließenden let name = ...-Ausdruck enthalten ist, ist ein Fehler. Anders ausgedrückt: Abfrageausdrücke auf oberster Ebene dürfen keine kostenlosen Variablen haben.

In den obigen Grammatikproduktionen ist name wie Wort, aber mit der zusätzlichen Einschränkung, dass es eine rechtliche Kennung in der C-Programmiersprache ist. Verweise auf die Variable müssen vor das Zeichen "$" gesetzt werden.

Jeder let-Ausdruck definiert nur eine einzelne Variable, Sie können sie aber verschachteln.

Sowohl Zielmuster als auch Variablenverweise bestehen nur aus einem einzelnen Token, einem Wort, wodurch eine syntaktische Mehrdeutigkeit entsteht. Es gibt jedoch keine semantische Mehrdeutigkeit, da die Teilmenge der Wörter, die rechtliche Variablennamen haben, von der Teilmenge der Wörter getrennt wird, die rechtliche Zielmuster sind.

Aus technischer Sicht erhöhen let-Ausdrücke nicht die Ausdrucksstärke der Abfragesprache: Jede Abfrage, die in der Sprache ausdrücken kann, kann auch ohne sie ausgedrückt werden. Sie verbessern jedoch die Präzision vieler Abfragen und können auch zu einer effizienteren Abfragebewertung führen.

Ausdrücke in Klammern

expr ::= (expr)

Klammern weisen Unterausdrücke auf, um eine Bewertungsreihenfolge zu erzwingen. Ein Ausdruck in Klammern wird als Wert seines Arguments ausgewertet.

Algebraische Set-Operationen: Kreuzung, Union, Satzunterschied

expr ::= expr intersect expr
       | expr ^ expr
       | expr union expr
       | expr + expr
       | expr except expr
       | expr - expr

Diese drei Operatoren berechnen die üblichen Set-Vorgänge anhand ihrer Argumente. Jeder Operator hat zwei Formen, eine Nominalform wie intersect und eine symbolische Form wie ^. Beide Formen sind gleichwertig. Die symbolischen Formen lassen sich schneller eingeben. Der Rest dieser Seite enthält die Nominalformen.

Beispiel:

foo/... except foo/bar/...

wird als Gruppe von Zielen ausgewertet, die mit foo/..., aber nicht mit foo/bar/... übereinstimmen.

Sie können die folgende Abfrage schreiben:

foo/... - foo/bar/...

Die Vorgänge intersect (^) und union (+) sind kommutativ (symmetrisch). except (-) ist asymmetrisch. Der Parser behandelt alle drei Operatoren als linksassoziativ und von gleicher Priorität. Sie möchten also Klammern setzen. Die ersten beiden dieser Ausdrücke sind beispielsweise gleichwertig, der dritte jedoch nicht:

x intersect y union z
(x intersect y) union z
x intersect (y union z)

Ziele aus einer externen Quelle lesen: festgelegt

expr ::= set(word *)

Der Operator set(a b c ...) berechnet die Kombination von null oder mehr Zielmustern, die durch Leerzeichen (ohne Kommas) getrennt sind.

In Verbindung mit der $(...)-Funktion von Bourne Shell bietet set() die Möglichkeit, die Ergebnisse einer Abfrage in einer normalen Textdatei zu speichern, diese Textdatei mit anderen Programmen zu bearbeiten (z. B. Standard-UNIX-Shell-Tools) und das Ergebnis dann als Wert zur weiteren Verarbeitung wieder in das Abfragetool einzuführen. Beispiel:

bazel query deps(//my:target) --output=label | grep ... | sed ... | awk ... > foo
bazel query "kind(cc_binary, set($(<foo)))"

Im nächsten Beispiel wirdkind(cc_library, deps(//some_dir/foo:main, 5)) durch Filtern der maxrank -Werte mit einem awk -Programm berechnet.

bazel query 'deps(//some_dir/foo:main)' --output maxrank | awk '($1 < 5) { print $2;} ' > foo
bazel query "kind(cc_library, set($(<foo)))"

In diesen Beispielen ist $(<foo) eine Abkürzung für $(cat foo), es können jedoch auch andere Shell-Befehle als cat verwendet werden, z. B. der vorherige awk-Befehl.

Funktionen

expr ::= word '(' int | word | expr ... ')'

Die Abfragesprache definiert mehrere Funktionen. Der Name der Funktion bestimmt die Anzahl und den Typ der erforderlichen Argumente. Die folgenden Funktionen sind verfügbar:

Vorübergehende Schließung von Abhängigkeiten: deps

expr ::= deps(expr)
       | deps(expr, depth)

Der Operator deps(x) wertet das Diagramm aus, das durch die vorübergehende Schließung der Abhängigkeiten des Argumentsatzes x gebildet wird. Der Wert von deps(//foo) ist beispielsweise das Abhängigkeitsdiagramm, das auf dem einzelnen Knoten foo gerootet ist, einschließlich aller Abhängigkeiten. Der Wert von deps(foo/...) ist die Abhängigkeitsgrafik, deren Stamm alle Regeln in jedem Paket unter dem Verzeichnis foo sind. In diesem Zusammenhang stehen „Abhängigkeiten“ nur für die Regel und die Dateiziele. Daher sind die zum Erstellen dieser Ziele erforderlichen BUILD- und Starlark-Dateien hier nicht enthalten. Verwenden Sie dafür den Operator buildfiles.

Die resultierende Grafik wird entsprechend der Abhängigkeitsbeziehung angeordnet. Weitere Informationen finden Sie im Abschnitt zur Reihenfolge der Grafiken.

Der Operator deps akzeptiert ein optionales zweites Argument, bei dem es sich um ein Ganzzahlliteral handelt, das eine Obergrenze für die Suchtiefe angibt. So gibt deps(foo:*, 0) alle Ziele im foo-Paket zurück, während deps(foo:*, 1) die direkten Voraussetzungen aller Ziele im foo-Paket enthält und deps(foo:*, 2) zusätzlich die Knoten enthält, die direkt von den Knoten in deps(foo:*, 1) erreichbar sind, und so weiter. Diese Zahlen entsprechen den Rängen, die im Ausgabeformat minrank angezeigt werden. Wenn der Parameter depth weggelassen wird, ist die Suche unbegrenzt: Es wird die reflexive vorübergehende Schließung von Voraussetzungen berechnet.

Transitives Schließen von umgekehrten Abhängigkeiten: rdeps

expr ::= rdeps(expr, expr)
       | rdeps(expr, expr, depth)

Der Operator rdeps(u, x) führt zu den umgekehrten Abhängigkeiten des Argumentsatzes x innerhalb des provisorischen Abschlusses des Universums. u

Die resultierende Grafik wird entsprechend der Abhängigkeitsbeziehung angeordnet. Weitere Informationen findest du im Abschnitt zur Diagrammreihenfolge.

Der Operator rdeps akzeptiert ein optionales drittes Argument, ein Ganzzahlliteral, das eine Obergrenze für die Suchtiefe angibt. Das resultierende Diagramm enthält nur Knoten, die sich in einem bestimmten Abstand zu einem beliebigen Knoten im Argumentsatz befinden. rdeps(//foo, //common, 1) wird also für alle Knoten im Übergangsabschluss von //foo ausgewertet, die direkt von //common abhängen. Diese Zahlen entsprechen den Rängen, die im Ausgabeformat minrank angezeigt werden. Wenn der Parameter depth weggelassen wird, ist die Suche unbegrenzt.

Transitives Schließen aller umgekehrten Abhängigkeiten: allrdeps

expr ::= allrdeps(expr)
       | allrdeps(expr, depth)

Der Operator allrdeps verhält sich genauso wie der Operator rdeps mit dem Unterschied, dass das --universe_scope -Flag ausgewertet wird und nicht separat angegeben wird. Wenn --universe_scope=//foo/... übergeben wurde, entspricht allrdeps(//bar) dem rdeps(//foo/..., //bar).

Direkte umgekehrte Abhängigkeiten im selben Paket: same_pkg_direct_rdeps

expr ::= same_pkg_direct_rdeps(expr)

Der Operator same_pkg_direct_rdeps(x) führt zu einer vollständigen Gruppe von Zielen, die sich im selben Paket wie ein Ziel im Argumentsatz befinden und direkt davon abhängen.

Mit einem Zielpaket umgehen: Geschwister

expr ::= siblings(expr)

Der Operator siblings(x) führt zum vollständigen Satz von Zielen, die sich im selben Paket wie ein Ziel im Argumentsatz befinden.

Beliebige Auswahl: einige

expr ::= some(expr)

Der Operator some(x) wählt ein beliebiges Ziel aus dem Argumentsatz x aus und führt zu einem Singleton-Satz, der nur dieses Ziel enthält. Der Ausdruck some(//foo:main union //bar:baz) wird beispielsweise mit einem Satz von //foo:main oder //bar:baz ausgewertet, der jedoch nicht definiert ist.

Wenn das Argument ein Singleton ist, berechnet some die Identitätsfunktion: some(//foo:main) entspricht //foo:main.

Wenn der angegebene Argumentsatz wie im Ausdruck some(//foo:main intersect //bar:baz) leer ist, tritt ein Fehler auf.

Pfadoperatoren: Pfad, allpaths

expr ::= somepath(expr, expr)
       | allpaths(expr, expr)

Die Operatoren somepath(S, E) und allpaths(S, E) berechnen Pfade zwischen zwei Gruppen von Zielen. Beide Abfragen akzeptieren zwei Argumente: eine Gruppe von S Startpunkten und eine Gruppe von E Endpunkten. somepath gibt das Knotendiagramm für einen beliebigen Pfad von einem Ziel in S zu einem Ziel in E zurück. allpaths gibt das Diagramm der Knoten in allen Pfaden von jedem Ziel in S zu einem beliebigen Ziel in E zurück.

Die resultierenden Grafiken werden entsprechend der Abhängigkeitsbeziehung angeordnet. Weitere Informationen finden Sie im Abschnitt zur Diagrammreihenfolge.

Pfad
somepath(S1 + S2, E), ein mögliches Ergebnis.
Pfad
somepath(S1 + S2, E), ein weiteres mögliches Ergebnis.
Alle Pfade
allpaths(S1 + S2, E)

Nach Art filtern: Ziel

expr ::= kind(word, expr)

Der Operator kind(pattern, input) wendet einen Filter auf eine Reihe von Zielen an und verwirft diese Ziele, die nicht der erwarteten Art entsprechen. Der Parameter pattern gibt an, welche Art von Ziel abgeglichen werden soll.

In der Tabelle unten sind beispielsweise die Arten für die vier Ziele dargestellt, die in der Datei BUILD (für Paket p) definiert sind:

Code Ziel Art
        genrule(
            name = "a",
            srcs = ["a.in"],
            outs = ["a.out"],
            cmd = "...",
        )
      
//p:a Genrule-Regel
//p:a.in Quelldatei
//p:a.out generierte Datei
//p:BUILD Quelldatei

Daher wertet kind("cc_.* rule", foo/...) als Gruppe aller cc_library-, cc_binary- usw. Regelziele unterhalb von foo aus und kind("source file", deps(//foo)) bewertet für alle Quelldateien beim vorübergehenden Schließen von Abhängigkeiten des //foo-Ziels.

Häufig ist die Anführungszeichen des Arguments pattern erforderlich, da viele reguläre Ausdrücke wie source file und .*_test vom Parser nicht als Wörter betrachtet werden.

Beim Abgleich für package group liefern Ziele, die auf :all enden, möglicherweise keine Ergebnisse. Verwenden Sie stattdessen :all-targets.

Nach Name filtern: Filter

expr ::= filter(word, expr)

Der Operator filter(pattern, input) wendet einen Filter auf eine Gruppe von Zielen an und verwirft Ziele, deren Labels (in absoluter Form) nicht mit dem Muster übereinstimmen. Er wird als Teilmenge einer Eingabe ausgewertet.

Das erste Argument, pattern, ist ein Wort, das einen regulären Ausdruck über Zielnamen enthält. Ein filter-Ausdruck wird für den Satz mit allen Zielen x ausgewertet, sodass x ein Mitglied des Satzes input ist und das Label (in absoluter Form, z. B. //foo:bar) von x eine (nicht verankerte) Übereinstimmung für den regulären Ausdruck pattern enthält. Da alle Zielnamen mit // beginnen, kann es als Alternative zum Anker für reguläre Ausdrücke ^ verwendet werden.

Dieser Operator bietet oft eine viel schnellere und robustere Alternative zum Operator intersect. So können Sie beispielsweise alle bar-Abhängigkeiten des Ziels //foo:foo sehen:

deps(//foo) intersect //bar/...

Diese Anweisung erfordert jedoch das Parsen aller BUILD-Dateien in der bar-Struktur, was langsam und fehleranfällig in irrelevanten BUILD-Dateien ist. Eine Alternative wäre:

filter(//bar, deps(//foo))

Dadurch wird zuerst die Gruppe von //foo-Abhängigkeiten berechnet und dann werden nur Ziele gefiltert, die mit dem angegebenen Muster übereinstimmen – also Namen mit Namen, die //bar als Teilstring enthalten.

Der filter(pattern, expr)-Operator wird auch häufig zum Filtern bestimmter Dateien nach Name oder Erweiterung verwendet. Beispiel:

filter("\.cc$", deps(//foo))

stellt eine Liste aller .cc-Dateien bereit, die zum Erstellen von //foo verwendet wurden.

Regelattributfilter: attr

expr ::= attr(word, word, expr)

Der Operator attr(name, pattern, input) wendet einen Filter auf eine Gruppe von Zielen an und verwirft Ziele, die keine Regeln sind, Regelziele ohne definiertes Attribut name oder Regelziele, bei denen der Attributwert nicht mit dem angegebenen regulären Ausdruck pattern übereinstimmt. Er wird als Teilmenge einer Eingabe ausgewertet.

Das erste Argument, name, ist der Name des Regelattributs, das mit dem angegebenen Muster für reguläre Ausdrücke abgeglichen werden muss. Das zweite Argument, pattern, ist ein regulärer Ausdruck für die Attributwerte. Ein attr-Ausdruck wird als Gruppe mit allen Zielen x ausgewertet, sodass x ein Mitglied der Gruppe input ist, eine Regel mit dem definierten Attribut name ist und der Attributwert eine (nicht verankerte) Übereinstimmung für den regulären Ausdruck pattern enthält. Wenn name ein optionales Attribut ist und in der Regel nicht explizit angegeben ist, wird der Standardattributwert für den Vergleich verwendet. Beispiel:

attr(linkshared, 0, deps(//foo))

wählt alle //foo-Abhängigkeiten aus, die ein Attribut vom Typ „Linkfreigabe“ (z. B. die Regel cc_binary) haben dürfen, das entweder explizit auf 0 festgelegt oder gar nicht festgelegt wurde, aber der Standardwert ist 0 (z. B. bei cc_binary-Regeln).

Listentypattribute (z. B. srcs, data usw.) werden in Strings der Form [value<sub>1</sub>, ..., value<sub>n</sub>] konvertiert, beginnend mit der Klammer [, mit einer eckigen Klammer ] und dem Trennzeichen (Komma, Leerzeichen) mit mehreren Werten. Labels werden mithilfe der absoluten Form in Labels umgewandelt. Ein Attribut deps=[":foo", "//otherpkg:bar", "wiz"] wird beispielsweise in den String [//thispkg:foo, //otherpkg:bar, //thispkg:wiz] konvertiert. Klammern sind immer vorhanden. In der leeren Liste wird daher zu Abgleichszwecken der Stringwert [] verwendet. Beispiel:

attr("srcs", "\[\]", deps(//foo))

wählt alle Regeln aus //foo-Abhängigkeiten aus, die ein leeres srcs-Attribut haben, während

attr("data", ".{3,}", deps(//foo))

wählt alle Regeln aus //foo-Abhängigkeiten aus, die mindestens einen Wert im Attribut data angeben (jedes Label ist aufgrund der // und : mindestens 3 Zeichen lang).

Um alle Regeln unter //foo-Abhängigkeiten mit einem bestimmten value in einem Listentypattribut auszuwählen, verwenden Sie

attr("tags", "[\[ ]value[,\]]", deps(//foo))

Dies funktioniert, da das Zeichen vor value [ oder ein Leerzeichen und das Zeichen nach value ein Komma oder ] ist.

Sichtbarkeitsfilter für Regeln: sichtbar

expr ::= visible(expr, expr)

Der Operator visible(predicate, input) wendet einen Filter auf eine Gruppe von Zielen an und verwirft Ziele ohne die erforderliche Sichtbarkeit.

Das erste Argument (predicate) ist eine Gruppe von Zielen, für die alle Ziele in der Ausgabe sichtbar sein müssen. Ein visible-Ausdruck wird für den Satz mit allen Zielen x ausgewertet, sodass x ein Mitglied des Satzes input ist und für alle Ziele y in predicate x für y sichtbar ist. Beispiel:

visible(//foo, //bar:*)

wählt alle Ziele im Paket //bar aus, von denen //foo abhängig sein kann, ohne die Sichtbarkeitseinschränkungen zu verletzen.

Bewertung der Regelattribute des Typlabels: Labels

expr ::= labels(word, expr)

Der Operator labels(attr_name, inputs) gibt eine Gruppe von Zielen zurück, die in dem Attribut attr_name des Typs vom Typ " oder "list of label" in einer Regel im Satz inputs angegeben sind.

Beispielsweise gibt labels(srcs, //foo) die Gruppe von Zielen zurück, die im Attribut srcs der Regel //foo angezeigt werden. Wenn es mehrere Regeln mit srcs-Attributen im inputs gibt, wird die Vereinigung der jeweiligen srcs zurückgegeben.

Test_suites: Tests maximieren und filtern

expr ::= tests(expr)

Der Operator tests(x) gibt den Satz aller Testregeln im Satz x zurück, wobei alle test_suite-Regeln auf den Satz einzelner Tests, auf die sie sich beziehen, erweitert und nach tag und size gefiltert wird.

Standardmäßig werden bei der Abfragebewertung alle Nicht-Testziele in allen test_suite-Regeln ignoriert. Dies kann mit der Option --strict_test_suite in Fehler geändert werden.

Beispiel: Die Abfrage kind(test, foo:*) listet alle *_test- und test_suite-Regeln im Paket foo auf. Alle Ergebnisse sind (nach Definition) Mitglieder des foo-Pakets. Im Gegensatz dazu gibt die Abfrage tests(foo:*) alle einzelnen Tests zurück, die von bazel test foo:* ausgeführt werden. Dies kann Tests umfassen, die zu anderen Paketen gehören und auf die direkt oder indirekt über test_suite-Regeln verwiesen wird.

Paketdefinitionsdateien: buildfiles

expr ::= buildfiles(expr)

Der Operator buildfiles(x) gibt die Dateien zurück, die die Pakete für jedes Ziel im Dataset x definieren .Mit anderen Worten: Für jedes Paket, seine BUILD-Datei, plus alle BZL-Dateien, auf die es über load verweist. Dabei werden auch die BUILD-Dateien der Pakete zurückgegeben, die diese load-Dateien enthalten.

Dieser Operator wird normalerweise verwendet, um zu bestimmen, welche Dateien oder Pakete zum Erstellen eines bestimmten Ziels erforderlich sind. Dies geschieht häufig in Verbindung mit der Option --output package weiter unten. Beispiel:

bazel query 'buildfiles(deps(//foo))' --output package

gibt den Satz aller Pakete zurück, von denen //foo vorübergehend abhängt.

Paketdefinitionsdateien: rbuildfiles

expr ::= rbuildfiles(word, ...)

Der Operator rbuildfiles verwendet eine durch Kommas getrennte Liste von Pfadfragmenten und gibt den Satz BUILD-Dateien zurück, die vorübergehend von diesen Pfadfragmenten abhängen. Wenn beispielsweise //foo ein Paket ist, gibt rbuildfiles(foo/BUILD) das Ziel //foo:BUILD zurück. Wenn die Datei foo/BUILD load('//bar:file.bzl'... enthält, gibt rbuildfiles(bar/file.bzl) das //foo:BUILD-Ziel sowie die Ziele für alle anderen BUILD-Dateien zurück, die //bar:file.bzl laden.

Der Bereich des Operators rbuildfiles ist das durch das Flag --universe_scope angegebene Universum. Dateien, die nicht direkt BUILD-Dateien und .bzl-Dateien entsprechen, haben keine Auswirkungen auf die Ergebnisse. Beispielsweise werden Quelldateien (z. B. foo.cc) ignoriert, auch wenn sie explizit in der Datei BUILD erwähnt werden. Symlinks werden jedoch berücksichtigt. Wenn foo/BUILD also ein symlink zu bar/BUILD ist, schließt rbuildfiles(bar/BUILD) //foo:BUILD in die Ergebnisse ein.

Der Operator rbuildfiles ist fast moralisch der Kehrwert des Operators buildfiles. Diese moralische Inversion ist jedoch in einer Richtung stärker: Die Ausgaben von rbuildfiles entsprechen den Eingaben von buildfiles. Ersteres enthält nur BUILD-Dateiziele in Paketen, letztere können solche Ziele enthalten. In die andere Richtung ist die Korrespondenz schwächer. Die Ausgaben des Operators buildfiles sind Ziele, die allen Paketen und entsprechen .bzl-Dateien, die für eine bestimmte Eingabe benötigt werden. Die Eingaben des Operators rbuildfiles sind jedoch nicht diese Ziele, sondern die Pfadfragmente, die diesen Zielen entsprechen.

Paketdefinitionsdateien: Loadfiles

expr ::= loadfiles(expr)

Der Operator loadfiles(x) gibt den Satz von Starlark-Dateien zurück, die zum Laden der Pakete jedes Ziels im Dataset x erforderlich sind. Mit anderen Worten: Für jedes Paket werden die BZL-Dateien zurückgegeben, auf die aus den BUILD-Dateien verwiesen wird.

Ausgabeformate

bazel query generiert ein Diagramm. Sie geben den Inhalt, das Format und die Reihenfolge an, in der bazel query dieses Diagramm mithilfe der Befehlszeilenoption --output darstellt.

Bei der Ausführung mit Sky Query sind nur Ausgabeformate zulässig, die mit ungeordneter Ausgabe kompatibel sind. Insbesondere die Ausgabeformate graph, minrank und maxrank sind unzulässig.

Für einige Ausgabeformate sind zusätzliche Optionen zulässig. Dem Namen jeder Ausgabeoption ist das Ausgabeformat vorangestellt, auf das sie angewendet wird. Daher gilt --graph:factored nur, wenn --output=graph verwendet wird. Er hat keine Auswirkungen, wenn ein anderes Ausgabeformat als graph verwendet wird. Entsprechend gilt --xml:line_numbers nur, wenn --output=xml verwendet wird.

Zur Reihenfolge der Ergebnisse

Obwohl Abfrageausdrücke immer dem Gesetz zur Erhaltung der Grafikreihenfolge entsprechen, können die Ergebnisse entweder in abhängiger oder ungeordneter Weise dargestellt werden. Dies wirkt sich nicht auf die Ziele in der Ergebnismenge oder die Berechnung der Abfrage aus. Dies wirkt sich nur darauf aus, wie die Ergebnisse in stdout ausgegeben werden. Darüber hinaus können Knoten, die in der Abhängigkeitsreihenfolge entsprechen, alphabetisch sortiert werden. Mit dem Flag --order_output kann dieses Verhalten gesteuert werden. Das Flag --[no]order_results hat einen Teil der Funktionen des Flags --order_output und ist veraltet.

Der Standardwert dieses Flags ist auto. Dadurch werden Ergebnisse in lexikografischer Reihenfolge ausgegeben. Wenn somepath(a,b) jedoch verwendet wird, werden die Ergebnisse stattdessen in der Reihenfolge deps ausgegeben.

Wenn dieses Flag no ist und --output entweder build, label, label_kind, location, package, proto oder xml ist, werden die Ausgaben in beliebiger Reihenfolge ausgegeben. Dies ist im Allgemeinen die schnellste Option. Dies wird jedoch nicht unterstützt, wenn --output entweder graph, minrank oder maxrank ist: Bei diesen Formaten druckt Bazel immer Ergebnisse, die nach der Abhängigkeitsreihenfolge oder dem Rang geordnet sind.

Wenn dieses Flag deps ist, gibt Bazel die Ergebnisse in einer topologischen Reihenfolge aus, also zuerst Abhängigkeiten. Knoten, die nicht nach der Abhängigkeitsreihenfolge geordnet sind, weil jedoch kein Pfad von einem zum anderen vorhanden ist, können jedoch in beliebiger Reihenfolge ausgegeben werden.

Wenn dieses Flag full ist, gibt Bazel Knoten in einer vollständig deterministischen (Gesamt-)Reihenfolge aus. Erstens sind alle Knoten alphabetisch sortiert. Anschließend wird jeder Knoten in der Liste als Beginn einer nach der Reihenfolge der Tiefe durchgeführten Suche verwendet, bei der ausgehende Kanten zu nicht besuchten Knoten in alphabetischer Reihenfolge der folgenden Knoten durchlaufen werden. Zuletzt werden Knoten in umgekehrter Reihenfolge in der Reihenfolge ihres Besuchs gedruckt.

Das Drucken von Knoten in dieser Reihenfolge kann länger dauern. Daher sollte es nur verwendet werden, wenn Determinismus wichtig ist.

Quellform der Ziele so ausgeben, wie sie in BUILD angezeigt werden

--output build

Bei dieser Option wird jedes Ziel so dargestellt, als wäre es manuell in die BUILD-Sprache geschrieben. Alle Variablen und Funktionsaufrufe (z. B. Glob-Makros und Makros) werden erweitert. So können Sie die Auswirkungen von Starlark-Makros sehen. Außerdem gibt jede effektive Regel einen generator_name- und/oder generator_function-Wert aus, sodass der Name des Makros angegeben wird, das ausgewertet wurde, um die geltende Regel zu erzeugen.

Obwohl die Ausgabe die gleiche Syntax wie BUILD-Dateien verwendet, ist es keine Garantie, dass sie eine gültige BUILD-Datei erzeugt.

--output label

Bei dieser Option werden die Namen (oder Labels) jedes Ziels in der resultierenden Grafik ausgegeben, ein Label pro Zeile in absteigender Reihenfolge (es sei denn, --noorder_results ist angegeben, siehe Hinweise zur Reihenfolge der Ergebnisse). Bei einer topologischen Sortierung wird ein Graphknoten vor allen nachfolgenden Nachfolgern angezeigt. Natürlich gibt es viele mögliche logistische Reihenfolgen einer Grafik (umgekehrte Sortierreihenfolge ist nur eine). Diese wird nicht angegeben.

Beim Drucken der Ausgabe einer somepath-Abfrage entspricht die Reihenfolge, in der die Knoten gedruckt werden, der Reihenfolge des Pfads.

Hinweis: In einigen Eckfällen kann es zwei verschiedene Ziele mit demselben Label geben. So kann beispielsweise eine sh_binary-Regel und die einzelne (implizite) srcs-Datei beide als foo.sh bezeichnet werden. Wenn das Ergebnis einer Abfrage beide Ziele enthält, enthält die Ausgabe (im Format label) ein Duplikat. Wenn Sie das Format label_kind verwenden (siehe unten), wird die Unterscheidung deutlich: Die beiden Ziele haben denselben Namen, aber eines hat die Art sh_binary rule und die andere Art source file.

--output label_kind

Wie bei label werden auch bei diesem Ausgabeformat die Labels der einzelnen Ziele in der resultierenden Grafik in topischer Reihenfolge ausgegeben, aber zusätzlich wird dem Label die Art des Ziels vorangestellt.

--output minrank --output maxrank

Wie bei label werden die Ausgabeformate der Ausgaben minrank und maxrank in der resultierenden Grafik gedruckt. Sie werden jedoch nicht in absteigender Reihenfolge, sondern in Rangreihenfolge vor ihrer Rangnummer angezeigt. Sie sind vom Flag --[no]order_results für die Ergebnissortierung nicht betroffen (siehe Hinweise zur Reihenfolge der Ergebnisse).

Es gibt zwei Varianten dieses Formats: minrank sortiert jeden Knoten nach der Länge des kürzesten Pfads von einem Stammknoten zu diesem. Stammknoten (die keine eingehenden Kanten haben) haben den Rang 0, ihre Nachfolger haben den Rang 1 usw. (Wie immer verweisen die Kanten von einem Ziel auf seine Voraussetzungen: die Ziele, von denen es abhängt.)

maxrank sortiert jeden Knoten nach der Länge des längsten Pfads von einem Stammknoten zu diesem Knoten. Auch hier haben „roots“ einen Rang von 0, alle anderen Knoten einen Rang, der größer als der maximale Rang aller ihrer Vorgänger ist.

Alle Knoten in einem Zyklus haben den gleichen Rang. (Die meisten Grafiken sind azyklisch, aber Zyklen treten auf, weil BUILD-Dateien fehlerhafte Zyklen enthalten.)

Diese Ausgabeformate sind nützlich, um zu ermitteln, wie tief eine Grafik ist. Wenn sie für das Ergebnis einer deps(x)-, rdeps(x)- oder allpaths-Abfrage verwendet wird, entspricht die Rangnummer der Länge des kürzesten (mit minrank) oder längsten Pfads (x) von x zu einem Knoten in diesem Rang. Mit maxrank kann die längste Sequenz von Build-Schritten ermittelt werden, die zum Erstellen eines Ziels erforderlich sind.

Beispielsweise liefert die Grafik links die Ausgaben auf der rechten Seite, wenn --output minrank bzw. --output maxrank angegeben ist.

Auf Rang
      minrank

      0 //c:c
      1 //b:b
      1 //a:a
      2 //b:b.cc
      2 //a:a.cc
      
      maxrank

      0 //c:c
      1 //b:b
      2 //a:a
      2 //b:b.cc
      3 //a:a.cc
      
--output location

Wie bei label_kind wird auch bei dieser Option für jedes Ziel im Ergebnis Typ und Label des Ziels ausgegeben. Dem Präfix wird jedoch ein String vorangestellt, der den Standort des Ziels als Dateinamen und Zeilennummer beschreibt. Das Format ähnelt der Ausgabe von grep. Daher können Tools, mit denen Letzteres geparst werden kann (z. B. Emacs oder vi), auch die Abfrageausgabe verwenden, um eine Reihe von Übereinstimmungen zu durchlaufen. Dadurch kann das Bazel-Abfragetool als abhängige graphenbasierte Datei mit „grep“ für BUILD-Dateien verwendet werden.

Die Standortinformationen variieren je nach Zielart (siehe Operator Kind). Bei Regeln wird der Speicherort der Regeldeklaration in der Datei BUILD ausgegeben. Bei Quelldateien wird der Standort in Zeile 1 der eigentlichen Datei ausgegeben. Bei einer generierten Datei wird der Speicherort der Regel, durch die sie generiert wird, ausgegeben. (Das Abfragetool bietet nicht genügend Informationen, um den tatsächlichen Speicherort der generierten Datei zu ermitteln. Es ist auf jeden Fall nicht vorhanden, wenn ein Build noch nicht ausgeführt wurde.)

--output package

Mit dieser Option wird der Name aller Pakete ausgegeben, zu denen ein Ziel in der Ergebnismenge gehört. Die Namen werden in lexikografischer Reihenfolge gedruckt. Duplikate sind ausgeschlossen. Eigentlich ist dies eine Projektion aus dem Satz von Labels (Paket, Ziel) auf Pakete.

Pakete in externen Repositories haben das Format @repo//foo/bar, während Pakete im Haupt-Repository als foo/bar formatiert sind.

In Verbindung mit der Abfrage deps(...) kann mit dieser Ausgabeoption die Gruppe von Paketen ermittelt werden, die zum Erstellen einer Gruppe von Zielen ausgecheckt werden müssen.

Eine Grafik des Ergebnisses anzeigen

--output graph

Bei dieser Option wird das Abfrageergebnis als gerichtete Grafik im beliebten AT&T;T GraphViz-Format ausgegeben. In der Regel wird das Ergebnis in einer Datei wie .png oder .svg gespeichert. Wenn das Programm dot nicht auf Ihrer Workstation installiert ist, können Sie es mit dem Befehl sudo apt-get install graphviz installieren. Im folgenden Abschnitt finden Sie einen Beispielaufruf.

Dieses Ausgabeformat ist besonders nützlich für allpaths-, deps- oder rdeps-Abfragen, bei denen das Ergebnis eine Gruppe von Pfaden enthält, die beim Rendern in einer linearen Form, z. B. mit --output label, nicht einfach dargestellt werden können.

Standardmäßig wird die Grafik in einem faktorisierten Format gerendert. Das heißt, logisch äquivalente Knoten werden zu einem einzelnen Knoten mit mehreren Labels zusammengeführt. Dadurch wird die Grafik kompakter und lesbarer, da typische Ergebnisgrafiken sich häufig wiederholende Muster enthalten. Eine java_library-Regel kann beispielsweise von Hunderten von Java-Quelldateien abhängen, die alle von demselben genrule generiert werden. Im faktorisierten Graphen werden alle diese Dateien durch einen einzelnen Knoten dargestellt. Dieses Verhalten kann mit der Option --nograph:factored deaktiviert werden.

--graph:node_limit n

Die Option gibt die maximale Länge des Labelstrings für einen Graphknoten in der Ausgabe an. Längere Labels werden abgeschnitten. -1 deaktiviert die Kürzung. Aufgrund der faktorisierten Form, in der Grafiken normalerweise gedruckt werden, können die Knotenlabels sehr lang sein. GraphViz kann keine Labels verarbeiten, die länger als 1.024 Zeichen sind. Dies ist der Standardwert dieser Option. Diese Option ist nur wirksam, wenn --output=graph verwendet wird.

--[no]graph:factored

Standardmäßig werden Grafiken in der faktorisierten Form dargestellt, wie oben erläutert. Wenn --nograph:factored angegeben ist, werden Diagramme ohne Faktorisierung ausgegeben. Dadurch wird die Visualisierung mit GraphViz unpraktisch. Das einfachere Format erleichtert jedoch die Verarbeitung durch andere Tools (z. B. grep). Diese Option ist nur wirksam, wenn --output=graph verwendet wird.

XML

--output xml

Bei dieser Option werden die resultierenden Ziele im XML-Format ausgegeben. Die Ausgabe beginnt mit einem XML-Header wie diesem

  <?xml version="1.0" encoding="UTF-8"?>
  <query version="2">

Anschließend wird für jedes Ziel in der Ergebnisgrafik ein XML-Element in absteigender Reihenfolge angezeigt (es sei denn, ungeordnete Ergebnisse werden angefordert). Danach wird ein letztes Element

</query>

Für Ziele vom Typ file werden einfache Einträge ausgegeben:

  <source-file name='//foo:foo_main.cc' .../>
  <generated-file name='//foo:libfoo.so' .../>

Bei Regeln ist die XML jedoch strukturiert und enthält Definitionen aller Attribute der Regel, einschließlich derer, deren Wert nicht explizit in der Datei BUILD der Regel angegeben wurde.

Außerdem enthält das Ergebnis rule-input- und rule-output-Elemente, sodass die Topologie des Abhängigkeitsdiagramms rekonstruiert werden kann, ohne dass Sie wissen müssen, dass z. B. die Elemente des srcs-Attributs Vorwärtsabhängigkeiten (Voraussetzungen) und der Inhalt des Attributs outs rückwärtsabhängig sind (Nutzer).

rule-input-Elemente für implizite Abhängigkeiten werden unterdrückt, wenn --noimplicit_deps angegeben ist.

  <rule class='cc_binary rule' name='//foo:foo' ...>
    <list name='srcs'>
      <label value='//foo:foo_main.cc'/>
      <label value='//foo:bar.cc'/>
      ...
    </list>
    <list name='deps'>
      <label value='//common:common'/>
      <label value='//collections:collections'/>
      ...
    </list>
    <list name='data'>
      ...
    </list>
    <int name='linkstatic' value='0'/>
    <int name='linkshared' value='0'/>
    <list name='licenses'/>
    <list name='distribs'>
      <distribution value="INTERNAL" />
    </list>
    <rule-input name="//common:common" />
    <rule-input name="//collections:collections" />
    <rule-input name="//foo:foo_main.cc" />
    <rule-input name="//foo:bar.cc" />
    ...
  </rule>

Jedes XML-Element für ein Ziel enthält ein name-Attribut, dessen Wert das Label des Ziels ist, und ein location-Attribut, dessen Wert der Standort des Ziels ist, wie vom --output location ausgegeben.

--[no]xml:line_numbers

Standardmäßig enthalten die in der XML-Ausgabe angezeigten Standorte Zeilennummern. Wenn --noxml:line_numbers angegeben ist, werden keine Zeilennummern gedruckt.

--[no]xml:default_values

Standardmäßig enthält die XML-Ausgabe kein Regelattribut, dessen Wert der Standardwert für diesen Attributtyp ist, z. B. wenn er nicht in der Datei BUILD angegeben ist oder der Standardwert explizit angegeben wurde. Durch diese Option werden solche Attributwerte in die XML-Ausgabe aufgenommen.

Reguläre Ausdrücke

Reguläre Ausdrücke in der Abfragesprache verwenden die Java-Regex-Bibliothek, sodass Sie die vollständige Syntax für java.util.regex.Pattern verwenden können.

Mit externen Repositories abfragen

Wenn der Build von Regeln aus externen Repositories abhängig ist (definiert in der WORKSPACE-Datei), enthalten die Abfrageergebnisse diese Abhängigkeiten. Wenn //foo:bar beispielsweise von //external:some-lib abhängt und //external:some-lib an @other-repo//baz:lib gebunden ist, listet bazel query 'deps(//foo:bar)' sowohl @other-repo//baz:lib als auch //external:some-lib als Abhängigkeiten auf.

Externe Repositories selbst sind keine Abhängigkeiten eines Builds. Das heißt, im obigen Beispiel ist //external:other-repo keine Abhängigkeit. Sie können jedoch als Mitglied des Pakets //external abgefragt werden. Beispiel:

  # Querying over all members of //external returns the repository.
  bazel query 'kind(http_archive, //external:*)'
  //external:other-repo

  # ...but the repository is not a dependency.
  bazel query 'kind(http_archive, deps(//foo:bar))'
  INFO: Empty results