Einführung
In Go ist ein Build-Tag, oder eine Build-Einschränkung, eine Kennung, die einem Codeabschnitt hinzugefügt wird und bestimmt, wann die Datei beim build
-Prozess in ein Paket eingebunden werden sollte. Dies ermöglicht es Ihnen, verschiedene Versionen Ihrer Go-Anwendung aus dem gleichen Quellcode zu erstellen und schnell und organisiert zwischen ihnen umzuschalten. Viele Entwickler verwenden Build-Tags, um den Workflow beim Bau跨-Plattform-kompatibler Anwendungen zu verbessern, wie z.B. Programme, die Änderungen am Code erforderlich haben, um Unterschiede zwischen verschiedenen Betriebssystemen zu berücksichtigen. Build-Tags werden auch für Integrations-Tests verwendet, um schnell zwischen dem integrierten Code und dem Code mit einem Mock-Service oder Stub umzuschalten und für unterschiedliche Ebenen von FunktionalitätsSets innerhalb einer Anwendung.
Lassen Sie uns das Problem unterschiedlicher Kundenfunktionssätze als Beispiel nehmen. Bei der Entwicklung einiger Anwendungen möchten Sie möglicherweise steuern, welche Funktionen in das Binary aufgenommen werden sollen, wie bei einer Anwendung, die die Ebenen Free, Pro und Enterprise anbietet. Wenn der Kunde sein Abonnementlevel in diesen Anwendungen erhöht, werden weitere Funktionen freigeschaltet und verfügbar. Um dieses Problem zu lösen, könnten Sie separate Projekte pflegen und versuchen, sie durch die Verwendung von import
-Anweisungen synchron zu halten. Während dieser Ansatz funktionieren würde, würde er mit der Zeit langweilig und fehleranfällig werden. Ein alternativer Ansatz wäre die Verwendung von Build-Tags.
In diesem Artikel werden Sie Build-Tags in Go verwenden, um verschiedene ausführbare Binärdateien zu erstellen, die die Funktionssätze Free, Pro und Enterprise einer Beispielanwendung bieten. Jede wird einen anderen Satz an Funktionen bereitstellen, wobei die Free-Version die Standardauswahl ist.
Voraussetzungen
Um dem Beispiel in diesem Artikel zu folgen, benötigen Sie:
- Eine Go-Arbeitsumgebung, die durch das Followen von Wie man Go installiert und eine lokale Programmierumgebung einrichtet eingerichtet wurde.
Erstellung der kostenlosen Version
Lassen Sie uns damit beginnen, die kostenlose Version der Anwendung zu erstellen, da sie Standard sein wird, wenn Sie go build
ohne jegliche Build-Tags ausführen. Später werden wir Build-Tags verwenden, um ausgewählte andere Teile zu unserem Programm hinzuzufügen.
Erstellen Sie im Verzeichnis src
einen Ordner mit dem Namen Ihrer Anwendung. Dieser Tutorial verwendet app
:
Wechseln Sie in diesen Ordner:
Als nächstes erstellen Sie eine neue Textdatei in Ihrem bevorzugten Texteditor namens main.go
:
Nun definieren wir die kostenlose Version der Anwendung. Fügen Sie die folgenden Inhalte in main.go
ein:
In dieser Datei haben wir ein Programm erstellt, das eine slice namens features
deklariert, die zwei strings enthält, die die Funktionen unserer kostenlosen Anwendung darstellen. Die main()
-Funktion in der Anwendung verwendet eine for
-Schleife, um durch die features
-Slice zu range
und alle verfügbaren Funktionen auf dem Bildschirm anzuzeigen.
Datei speichern und beenden. Nun, da diese Datei gespeichert ist, müssen wir sie für den Rest des Artikels nicht mehr bearbeiten. Stattdessen werden wir Build-Tags verwenden, um die Eigenschaften der daraus zu bauenden Binäre zu ändern.
Programm bauen und ausführen:
Du erhälst die folgende Ausgabe:
Output> Free Feature #1
> Free Feature #2
Das Programm hat unsere beiden kostenlosen Features ausgegeben, was die kostenlose Version unserer App abgeschlossen hat.
Bis jetzt hast du eine Anwendung erstellt, die über ein sehr grundlegendes Feature-Satz verfügt. Nächstes Mal baut du eine Methode auf, um weitere Features in der Anwendung während des Buildvorganges hinzuzufügen.
Kostenpflichtige Features hinzufügen mit go build
Bisher haben wir die Änderung von main.go
vermieden, um ein typisches Produktionsumfeld zu simulieren, in dem Code ohne Änderungen und möglicherweise Breakage des Hauptcodes hinzugefügt werden muss. Da wir die Datei main.go
nicht bearbeiten können, werden wir eine andere Mechanik brauchen, um weitere Features in den features
-Slice während des Buildvorganges einzufügen.
Lege eine neue Datei namens pro.go
an, die eine init()
-Funktion verwendet, um weitere Features zum features
-Slice hinzuzufügen:
Sobald der Editor die Datei geöffnet hat, füge die folgenden Zeilen hinzu:
In diesem Code haben wir init()
verwendet, um Code vor der main()
-Funktion unserer Anwendung auszuführen, gefolgt von append()
, um die Pro-Funktionen zum features
-Slice hinzuzufügen. Speichern Sie die Datei und beenden Sie sie.
Kompilieren und führen Sie die Anwendung mit go build
aus:
Da es nun zwei Dateien in unserem aktuellen Verzeichnis gibt (pro.go
und main.go
), wird go build
eine Binärdatei aus beiden erstellen. Führen Sie dieses Binary aus:
Dies gibt Ihnen die folgende Funktionsauswahl:
Output> Free Feature #1
> Free Feature #2
> Pro Feature #1
> Pro Feature #2
Die Anwendung enthält nun sowohl die Pro- als auch die Free-Funktionen. Dies ist jedoch nicht wünschenswert: Da es keine Unterscheidung zwischen den Versionen gibt, enthält die Free-Version nun Funktionen, die nur in der Pro-Version verfügbar sein sollen. Um dies zu beheben, könnten Sie mehr Code hinzufügen, um die verschiedenen Ebenen der Anwendung zu verwalten, oder Sie könnten Build-Tags verwenden, um der Go-Werkzeugkette mitzuteilen, welche .go
-Dateien erstellt und welche ignoriert werden sollen. Lassen Sie uns in der nächsten Schritt Build-Tags hinzufügen.
Build-Tags hinzufügen
Sie können nun Build-Tags verwenden, um die Pro-Version Ihrer Anwendung von der Free-Version zu unterscheiden.
Beginnen wir damit, zu untersuchen, wie ein Build-Tag aussieht:
Durch das Setzen dieser Codezeile als erste Zeile Ihres Pakets und das Ersetzen von tag_name
durch den Namen Ihres Build-Tags, markieren Sie dieses Paket als Code, der选择性 in die endgültige Binärdatei aufgenommen werden kann. Lassen Sie uns das in Aktion sehen, indem wir einen Build-Tag zum pro.go
-File hinzufügen, um dem go build
-Befehl mitzuteilen, es zu ignorieren, es sei denn, der Tag ist angegeben. Öffnen Sie die Datei in Ihrem Texteditor:
Dann fügen Sie die folgende hervorgehobene Zeile hinzu:
// +build pro
package main
func init() {
features = append(features,
"Pro Feature #1",
"Pro Feature #2",
)
}
Am Anfang des pro.go
-Files haben wir // +build pro
gefolgt von einer leeren neuen Zeile hinzugefügt. Diese abschließende Neue Zeile ist erforderlich, sonst interpretiert Go dies als Kommentar. Build-Tag-Deklarationen müssen auch am Anfang einer .go
-Datei stehen. Nichts, nicht einmal Kommentare, dürfen über den Build-Tags stehen.
Die +build
-Deklaration teilt dem go build
-Befehl mit, dass dies kein Kommentar ist, sondern ein Build-Tag. Der zweite Teil ist der pro
-Tag. Durch Hinzufügen dieses Tags am Anfang des pro.go
-Files wird der go build
-Befehl nur das pro.go
-File einbeziehen, wenn der pro
-Tag vorhanden ist.
Kompilieren und führen Sie die Anwendung erneut aus:
Sie erhalten die folgende Ausgabe:
Output> Free Feature #1
> Free Feature #2
Da das pro.go
-File erfordert, dass ein pro
-Tag vorhanden ist, wird die Datei ignoriert und die Anwendung wird ohne sie kompiliert.
Wenn Sie den go build
-Befehl ausführen, können wir die -tags
-Flag verwenden, um bedingentlich Code in die kompilierte Quelle aufzunehmen, indem wir das Tag selbst als Argument hinzufügen. Lassen Sie uns das für den pro
-Tag tun:
Dies wird die folgende Ausgabe erzeugen:
Output> Free Feature #1
> Free Feature #2
> Pro Feature #1
> Pro Feature #2
Nun erhalten wir die zusätzlichen Funktionen nur, wenn wir die Anwendung mit dem pro
-Build-Tag erstellen.
Das ist in Ordnung, wenn es nur zwei Versionen gibt, aber die Dinge werden komplizierter, wenn Sie weitere Tags hinzufügen. Um die Enterprise-Version unserer App im nächsten Schritt hinzuzufügen, verwenden wir mehrere Build-Tags, die mit boolscher Logik verbunden sind.
Build-Tag-Boolsche Logik
Wenn es mehrere Build-Tags in einem Go-Paket gibt, interagieren die Tags miteinander mittels boolscher Logik. Um dies zu demonstrieren, fügen wir die Enterprise-Ebene unserer Anwendung hinzu, indem wir sowohl das pro
-Tag als auch das enterprise
-Tag verwenden.
Um eine Enterprise-Binärdatei zu erstellen, müssen wir sowohl die Standardfunktionen, die Pro-Ebene-Funktionen als auch eine neue Reihe von Funktionen für Enterprise einschließen. Öffnen Sie zuerst einen Editor und erstellen Sie eine neue Datei enterprise.go
, die die neuen Enterprise-Funktionen hinzufügt:
Der Inhalt von enterprise.go
wird fast identisch zu pro.go
sein, aber enthält neue Funktionen. Fügen Sie die folgenden Zeilen in die Datei ein:
Speichern Sie die Datei und beenden Sie den Editor.
Derzeit hat die Datei enterprise.go
keine Build-Tags, und wie du gelernt hast, als du pro.go
hinzugefügt hast, bedeutet das, dass diese Funktionen zur Free-Version hinzugefügt werden, wenn go.build
ausgeführt wird. Für pro.go
hast du // +build pro
und eine neue Zeile am Anfang der Datei hinzugefügt, um go build
mitzuteilen, dass es nur dann eingebunden werden soll, wenn -tags pro
verwendet wird. In dieser Situation musstest du nur ein Build-Tag hinzufügen, um das Ziel zu erreichen. Bei dem Hinzufügen der neuen Enterprise-Funktionen musst du jedoch zunächst auch die Pro-Funktionen haben.
Lass uns zunächst den Support für das pro
-Build-Tag in enterprise.go
hinzufügen. Öffne die Datei mit deinem Texteditor:
Füge dann vor der Deklaration package main
das Build-Tag ein und stelle sicher, dass nach dem Build-Tag eine neue Zeile folgt:
// +build pro
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
Speichere und verlasse die Datei.
Kompiliere und führe die Anwendung ohne Tags aus:
Du erhältst die folgende Ausgabe:
Output> Free Feature #1
> Free Feature #2
Die Enterprise-Funktionen erscheinen nicht mehr in der Free-Version. Jetzt fügen wir das pro
-Build-Tag hinzu und bauen und führen die Anwendung erneut aus:
Du erhältst die folgende Ausgabe:
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
> Pro Feature #1
> Pro Feature #2
Das ist immer noch nicht genau das, was wir benötigen: Die Enterprise-Funktionen erscheinen jetzt, wenn wir versuchen, die Pro-Version zu erstellen. Um dies zu lösen, benötigen wir ein weiteres Build-Tag. Im Gegensatz zum pro
-Tag müssen wir jetzt sicherstellen, dass sowohl die pro
– als auch die enterprise
-Funktionen verfügbar sind.
Das Go-Build-System berücksichtigt diese Situation, indem es die Verwendung grundlegender Boolean-Logik im Build-Tags-System ermöglicht.
Lassen Sie uns enterprise.go
noch einmal öffnen:
Fügen Sie einen weiteren Build-Tag, enterprise
, in der gleichen Zeile wie das pro
-Tag ein:
// +build pro enterprise
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
Speichern Sie die Datei und schließen Sie sie.
Nun compilieren und starten wir die Anwendung mit dem neuen enterprise
-Build-Tag.
Das gibt folgendes:
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
Nun haben wir die Pro-Funktionen verloren. Das liegt daran, dass wir, wenn wir mehrere Build-Tags in der gleichen Zeile in einer .go
-Datei setzen, go build
diese als ODER
-Logik interpretiert. Mit der Zeile // +build pro enterprise
wird die Datei enterprise.go
erstellt, wenn entweder das pro
-Build-Tag oder das enterprise
-Build-Tag vorhanden ist. Wir müssen die Build-Tags korrekt einrichten, um beide zu erfordern und stattdessen UND
-Logik zu verwenden.
Anstatt beide Tags in derselben Zeile zu setzen, interpretiert go build
diese Tags mit UND
-Logik, wenn wir sie in separate Zeilen setzen.
Öffnen Sie enterprise.go
noch einmal und teilen Sie die Build-Tags in mehrere Zeilen auf.
// +build pro
// +build enterprise
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
Nun compilieren und starten Sie die Anwendung mit dem neuen enterprise
-Build-Tag.
Sie erhalten die folgende Ausgabe:
Output> Free Feature #1
> Free Feature #2
Noch nicht ganz perfekt: Da eine UND
-Aussage erfordert, dass beide Elemente als wahr
betrachtet werden, müssen wir beide pro
– und enterprise
-Build-Tags verwenden.
Lassen Sie uns noch einmal versuchen:
Sie erhalten die folgende Ausgabe:
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
> Pro Feature #1
> Pro Feature #2
Jetzt kann unsere Anwendung aus dem gleichen Quellbaum in mehrere Wege gebaut werden, um die Funktionen der Anwendung entsprechend freizuschalten.
In diesem Beispiel haben wir einen neuen // +build
-Tag verwendet, um eine UND
-Logik zu signalisieren, aber es gibt alternative Möglichkeiten, Boolean-Logik mit Build-Tags darzustellen. Die folgende Tabelle enthält einige Beispiele für andere syntaktische Formatierungen für Build-Tags sowie deren Boolean-Äquivalent:
Build Tag Syntax | Build Tag Sample | Boolean Statement |
---|---|---|
Space-separated elements | // +build pro enterprise |
pro OR enterprise |
Comma-separated elements | // +build pro,enterprise |
pro AND enterprise |
Exclamation point elements | // +build !pro |
NOT pro |
Schlussfolgerung
In dieser Anleitung haben Sie Build-Tags verwendet, um zu steuern, welcher Teil Ihres Codes in das Binary kompiliert wird. Zuerst haben Sie Build-Tags deklariert und sie mit go build
verwendet, dann haben Sie mehrere Tags mit Boolean-Logik kombiniert. Sie haben dann ein Programm gebaut, das die unterschiedlichen Feature-Sets einer Free-, Pro- und Enterprise-Version darstellt und die mächtige Kontrollmöglichkeit zeigt, die Build-Tags über Ihr Projekt geben können.
Wenn Sie mehr über Build-Tags erfahren möchten, schauen Sie sich die Golang-Dokumentation zu diesem Thema an oder erkunden Sie unsere How To Code in Go-Reihe weiter.
Source:
https://www.digitalocean.com/community/tutorials/customizing-go-binaries-with-build-tags