Einführung
DasGo programming language wird mit einer umfangreichen Toolchain geliefert, die das Abrufen von Paketen und das Erstellen ausführbarer Dateien unglaublich einfach macht. Eine der leistungsstärksten Funktionen von Go ist die Möglichkeit, ausführbare Dateien für jede von Go unterstützte fremde Plattform zu erstellen. Dies erleichtert das Testen und Verteilen von Paketen erheblich, da Sie keinen Zugriff auf eine bestimmte Plattform benötigen, um Ihr Paket für diese zu verteilen.
In diesem Lernprogramm verwenden Sie die Tools von Go, um ein Paket aus der Versionskontrolle abzurufen und die ausführbare Datei automatisch zu installieren. Anschließend erstellen und installieren Sie die ausführbare Datei manuell, damit Sie mit dem Prozess vertraut sind. Anschließend erstellen Sie eine ausführbare Datei für eine andere Architektur und automatisieren den Erstellungsprozess, um ausführbare Dateien für mehrere Plattformen zu erstellen. Wenn Sie fertig sind, wissen Sie, wie Sie ausführbare Dateien für Windows und macOS sowie für andere Plattformen erstellen, die Sie unterstützen möchten.
Voraussetzungen
Um diesem Tutorial zu folgen, benötigen Sie:
-
Ein Ubuntu 16.04-Server, der von folgendenthe Ubuntu 16.04 initial server setup guide eingerichtet wurde, einschließlich eines Sudo-Nicht-Root-Benutzers und einer Firewall.
-
Gehen Sie wie inHow to Install Go 1.6 on Ubuntu 16.04 beschrieben installiert.
[[Schritt-1 - Installieren von Go-Programmen von der Versionskontrolle]] == Schritt 1 - Installieren von Go-Programmen von der Versionskontrolle
Bevor wir ausführbare Dateien aus einem Go-Paket erstellen können, müssen wir den Quellcode abrufen. Das Toolgo get
kann Pakete von Versionskontrollsystemen wie GitHub abrufen. Unter der Haube klontgo get
Pakete in Unterverzeichnisse des Verzeichnisses$GOPATH/src/
. Gegebenenfalls wird das Paket installiert, indem die ausführbare Datei erstellt und im Verzeichnis$GOPATH/bin
abgelegt wird. Wenn Sie Go wie in den erforderlichen Lernprogrammen beschrieben konfiguriert haben, ist das Verzeichnis$GOPATH/bin
in der Umgebungsvariablen$PATH
enthalten, wodurch sichergestellt wird, dass Sie installierte Pakete von überall auf Ihrem System verwenden können.
Die Syntax für den Befehlgo get
lautetgo get package-import-path
. package-import-path
ist eine Zeichenfolge, die ein Paket eindeutig identifiziert. Dies ist häufig der Speicherort des Pakets in einem Remote-Repository wie Github oder ein Verzeichnis im Verzeichnis$GOPATH/src/
auf Ihrem Computer.
Es ist üblich,go get
mit dem Flag-u
zu verwenden, dasgo get
anweist, das Paket und seine Abhängigkeiten abzurufen, oder diese Abhängigkeiten zu aktualisieren, wenn sie bereits auf dem Computer vorhanden sind.
In diesem Tutorial installieren wirCaddy, einen in Go geschriebenen Webserver. ProCaddy’s instructionsx verwenden wirgithub.com/mholt/caddy/caddy
für den Paketimportpfad. Verwenden Siego get
, um Caddy abzurufen und zu installieren:
go get -u github.com/mholt/caddy/caddy
Der Befehl wird einige Zeit in Anspruch nehmen, aber Sie werden keinen Fortschritt sehen, während er das Paket abruft und installiert. Keine Ausgabe zeigt tatsächlich an, dass der Befehl erfolgreich ausgeführt wurde.
Wenn der Befehl ausgeführt wurde, finden Sie den Quellcode von Caddy unter$GOPATH/src/github.com/mholt/caddy
. Da Caddy über eine ausführbare Datei verfügt, wurde diese automatisch erstellt und im Verzeichnis$GOPATH/bin
gespeichert. Überprüfen Sie dies, indem Siewhich
verwenden, um den Speicherort der ausführbaren Datei zu drucken:
which caddy
Sie sehen die folgende Ausgabe:
Output/home/sammy/work/bin/caddy
[.Hinweis]##
Note: Der Befehlgo get
installiert Pakete aus dem Standardzweig eines Git-Repositorys, in vielen Fällen aus demmaster
-Zweig oder dem in Entwicklung befindlichen Zweig. Lesen Sie unbedingt die Anweisungen, die sich normalerweise in derREADME
-Datei des Repositorys befinden, bevor Siego get
verwenden.
Sie können Git-Befehle wiegit checkout
verwenden, um einen anderen Zweig für Quellen auszuwählen, die mit dem Befehlgo get
erhalten wurden. Lesen Sie das TutorialHow to Use Git Branches, um mehr über das Wechseln von Zweigen zu erfahren.
Schauen wir uns den Installationsprozess von Go-Paketen genauer an und beginnen mit der Erstellung von ausführbaren Dateien aus Paketen, die wir bereits erhalten haben.
[[Schritt 2 - Erstellen einer ausführbaren Datei]] == Schritt 2 - Erstellen einer ausführbaren Datei
Der Befehlgo get
hat die Quelle heruntergeladen und die ausführbare Datei von Caddy für uns in einem einzigen Befehl installiert. Möglicherweise möchten Sie die ausführbare Datei jedoch selbst neu erstellen oder eine ausführbare Datei aus Ihrem eigenen Code erstellen. Der Befehlgo build
erstellt ausführbare Dateien.
Obwohl wir Caddy bereits installiert haben, sollten wir es manuell neu erstellen, damit wir uns mit dem Vorgang vertraut machen können. Führen Siego build
aus und geben Sie den Paketimportpfad an:
go build github.com/mholt/caddy/caddy
Wie zuvor zeigt keine Ausgabe eine erfolgreiche Operation an. Die ausführbare Datei wird in Ihrem aktuellen Verzeichnis mit demselben Namen wie das Verzeichnis erstellt, in dem sich das Paket befindet. In diesem Fall heißt die ausführbare Dateicaddy
.
Wenn Sie sich im Paketverzeichnis befinden, können Sie den Pfad zum Paket weglassen und einfachgo build
ausführen.
Verwenden Sie das Flag-o
, um einen anderen Namen oder Speicherort für die ausführbare Datei anzugeben. Erstellen wir eine ausführbare Datei mit dem Namencaddy-server
und platzieren Sie sie in einembuild
-Verzeichnis im aktuellen Arbeitsverzeichnis:
go build -o build/caddy-server github.com/mholt/caddy/caddy
Dieser Befehl erstellt die ausführbare Datei und das Verzeichnis./build
, falls es nicht vorhanden ist.
Schauen wir uns nun die Installation der ausführbaren Dateien an.
[[Schritt 3 - Installieren einer ausführbaren Datei]] == Schritt 3 - Installieren einer ausführbaren Datei
Durch das Erstellen einer ausführbaren Datei wird die ausführbare Datei im aktuellen Verzeichnis oder im Verzeichnis Ihrer Wahl erstellt. Beim Installieren einer ausführbaren Datei wird eine ausführbare Datei erstellt und in$GOPATH/bin
gespeichert. Der Befehlgo install
funktioniert genauso wiego build
, abergo install
sorgt dafür, dass die Ausgabedatei an der richtigen Stelle für Sie platziert wird.
Verwenden Sie zum Installieren einer ausführbaren Dateigo install
, gefolgt vom Paketimportpfad. Probieren Sie das noch einmal mit Caddy aus:
go install github.com/mholt/caddy/caddy
Genau wie beigo build
wird keine Ausgabe angezeigt, wenn der Befehl erfolgreich war. Und wie zuvor wird die ausführbare Datei mit demselben Namen wie das Verzeichnis erstellt, in dem sich das Paket befindet. Diesmal wird die ausführbare Datei jedoch in$GOPATH/bin
gespeichert. Wenn$GOPATH/bin
Teil der Umgebungsvariablen$PATH
ist, ist die ausführbare Datei von überall auf Ihrem Betriebssystem verfügbar. Sie können den Speicherort mit dem Befehlwhich
überprüfen:
which caddy
Sie sehen die folgende Ausgabe:
Output of which/home/sammy/work/bin/caddy
Nachdem Sie nun verstanden haben, wiego get
,go build
undgo install
funktionieren und wie sie zusammenhängen, wollen wir eine der beliebtesten Go-Funktionen untersuchen: Erstellen von ausführbaren Dateien für andere Zielplattformen.
[[Schritt 4 - Erstellen von ausführbaren Dateien für verschiedene Architekturen]] == Schritt 4 - Erstellen von ausführbaren Dateien für verschiedene Architekturen
Mit dem Befehlgo build
können Sie eine ausführbare Datei für jede von Go unterstützte Zielplattformon your platform erstellen. Dies bedeutet, dass Sie Ihre Anwendung testen, freigeben und verteilen können, ohne die ausführbaren Dateien auf den Zielplattformen zu erstellen, die Sie verwenden möchten.
Cross-Compiling funktioniert, indem erforderliche Umgebungsvariablen festgelegt werden, die das Zielbetriebssystem und die Architektur angeben. Wir verwenden die VariableGOOS
für das Zielbetriebssystem undGOARCH
für die Zielarchitektur. Um eine ausführbare Datei zu erstellen, würde der Befehl die folgende Form annehmen:
env GOOS=target-OS GOARCH=target-architecture go build package-import-path
Der Befehlenv
führt ein Programm in einer geänderten Umgebung aus. Auf diese Weise können Sie Umgebungsvariablen nur für die aktuelle Befehlsausführung verwenden. Die Variablen werden nach Ausführung des Befehls zurückgesetzt oder zurückgesetzt.
Die folgende Tabelle zeigt die möglichen Kombinationen vonGOOS
undGOARCH
, die Sie verwenden können:
GOOS - Zielbetriebssystem |
GOARCH - Zielplattform |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[.Warnung]##
Warning: Für das Cross-Compilieren von ausführbaren Dateien für Android sindAndroid NDK und einige zusätzliche Einstellungen erforderlich, die den Rahmen dieses Lernprogramms sprengen.
Mit den Werten in der Tabelle können wir Caddy für Windows 64-Bit wie folgt erstellen:
env GOOS=windows GOARCH=amd64 go build github.com/mholt/caddy/caddy
Wieder zeigt keine Ausgabe an, dass der Vorgang erfolgreich war. Die ausführbare Datei wird im aktuellen Verzeichnis erstellt, wobei der Paketname als Name verwendet wird. Da wir diese ausführbare Datei jedoch für Windows erstellt haben, endet der Name mit dem Suffix.exe
.
Sie solltencaddy.exe
Datei in Ihrem aktuellen Verzeichnis haben, die Sie mit dem Befehlls
überprüfen können.
ls caddy.exe
In der Ausgabe wird die Dateicaddy.exe
angezeigt:
Outputcaddy.exe
[.note] #Note: Mit dem Flag-o
können Sie die ausführbare Datei umbenennen oder an einem anderen Speicherort ablegen. Wenn Sie jedoch eine ausführbare Datei für Windows erstellen und einen anderen Namen angeben, müssen Sie beim Festlegen des Namens der ausführbaren Datei explizit das Suffix ".exe" angeben.
#
Schauen wir uns die Skripterstellung für diesen Prozess an, um die Freigabe von Software für mehrere Zielumgebungen zu vereinfachen.
[[Schritt 5 - Erstellen eines Skripts zum Automatisieren der Cross-Kompilierung]] == Schritt 5 - Erstellen eines Skripts zum Automatisieren der Cross-Kompilierung
Das Erstellen von ausführbaren Dateien für viele Plattformen kann etwas langwierig sein, wir können jedoch ein Skript erstellen, um die Arbeit zu vereinfachen.
Das Skript verwendet den Paketimportpfad als Argument, durchläuft eine vordefinierte Liste von Betriebssystem- und Plattformpaaren und generiert für jedes Paar eine ausführbare Datei, wobei die Ausgabe im aktuellen Verzeichnis abgelegt wird. Jede ausführbare Datei wird mit dem Paketnamen gefolgt von der Zielplattform und -architektur in der Formpackage-OS-architecture
benannt. Dies ist ein universelles Skript, das Sie für jedes Projekt verwenden können.
Wechseln Sie in Ihr Ausgangsverzeichnis und erstellen Sie in Ihrem Texteditor eine neue Datei mit dem Namengo-executable-build.bash
:
cd ~
nano go-executable-build.bash
Wir beginnen unser Skript mit einershebang-Zeile. Diese Zeile definiert, welcher Interpreter dieses Skript analysiert, wenn es als ausführbare Datei ausgeführt wird. Fügen Sie die folgende Zeile hinzu, um anzugeben, dassbash
dieses Skript ausführen soll:
go-executable-build.bash
#!/usr/bin/env bash
Wir möchten den Paketimportpfad als Befehlszeilenargument verwenden. Dazu verwenden wir die Variable$n
, wobein
eine nicht negative Zahl ist. Die Variable$0
enthält den Namen des Skripts, das Sie ausgeführt haben, während$1
und höher vom Benutzer bereitgestellte Argumente enthalten. Fügen Sie diese Zeile dem Skript hinzu, das das erste Argument aus der Befehlszeile übernimmt und in einer Variablen namenspackage
speichert:
go-executable-build.bash
...
package=$1
Stellen Sie als Nächstes sicher, dass der Benutzer diesen Wert angegeben hat. Wenn der Wert nicht angegeben wird, beenden Sie das Skript mit einer Meldung, in der die Verwendung des Skripts erläutert wird:
go-executable-build.bash
...
if [[z "$package" ]]; then
echo "usage: $0 "
exit 1
fi
Diese Anweisungif
überprüft den Wert der Variablen$package
. Wenn es nicht festgelegt ist, verwenden wirecho
, um die korrekte Verwendung zu drucken, und beenden das Skript dann mitexit
. exit
verwendet einen Rückgabewert als Argument, der für erfolgreiche Ausführungen0
und für nicht erfolgreiche Ausführungen ein Wert ungleich Null sein sollte. Wir verwenden hier1
, da das Skript nicht erfolgreich war.
[.Hinweis]##
Note: Wenn Sie möchten, dass dieses Skript mit einem vordefinierten Paket funktioniert, ändern Sie die Variablepackage
o, dass sie auf diesen Importpfad verweist:
go-executable-build.bash
...
package="github.com/user/hello"
Als Nächstes möchten wir den Paketnamen aus dem Pfad extrahieren. Der Paketimportpfad wird durch/
Zeichen begrenzt, wobei sich der Paketname am Ende des Pfads befindet. Zuerst teilen wir den Paketimportpfad in ein Array auf, wobei wir/
als Trennzeichen verwenden:
go-executable-build.bash
package_split=(${package//\// })
Der Paketname sollte das letzte Element des neuen Arrays$package_split
ein. In Bash können Sie einen negativen Array-Index verwenden, um auf ein Array vom Ende statt vom Anfang zuzugreifen. Fügen Sie diese Zeile hinzu, um den Paketnamen aus dem Array abzurufen und in einer Variablen namenspackage_name
zu speichern:
go-executable-build.bash
...
package_name=${package_split[-1]}
Nun müssen Sie entscheiden, für welche Plattformen und Architekturen Sie ausführbare Dateien erstellen möchten. In diesem Tutorial erstellen wir ausführbare Dateien für Windows 64-Bit-, Windows 32-Bit- und 64-Bit-MacOS. Wir werden diese Ziele in ein Array mit dem FormatOS/Platform
einfügen, damit wir jedes Paar mit der gleichen Methode, mit der wir den Paketnamen aus dem Pfad extrahiert haben, inGOOS
undGOARCH
Variablen aufteilen können . Fügen Sie die Plattformen zum Skript hinzu:
go-executable-build.bash
...
platforms=("windows/amd64" "windows/386" "darwin/amd64")
Als Nächstes durchlaufen wir das Plattformarray, teilen jeden Plattformeintrag in Werte für die UmgebungsvariablenGOOS
undGOARCH
auf und verwenden diese zum Erstellen der ausführbaren Datei. Wir können das mit der folgendenfor
-Schleife tun:
go-executable-build.bash
...
for platform in "${platforms[@]}"
do
...
done
Die Variableplatform
enthält in jeder Iteration einen Eintrag aus dem Arrayplatforms
. Wir müssenplatform
in zwei Variablen aufteilen -GOOS
undGOARCH
. Fügen Sie derfor
-Schleife die folgenden Zeilen hinzu:
go-executable-build.bash
for platform in "${platforms[@]}"
do
platform_split=(${platform//\// })
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
done
Als Nächstes generieren wir den Namen der ausführbaren Datei, indem wir den Paketnamen mit dem Betriebssystem und der Architektur kombinieren. Wenn wir für Windows erstellen, müssen wir dem Dateinamen auch das Suffix.exe
hinzufügen. Fügen Sie diesen Code zurfor
-Schleife hinzu:
go-executable-build.bash
for platform in "${platforms[@]}"
do
platform_split=(${platform//\// })
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
output_name=$package_name'-'$GOOS'-'$GOARCH
if [ $GOOS = "windows" ]; then
output_name+='.exe'
fi
done
Wenn die Variablen festgelegt sind, verwenden wirgo build
, um die ausführbare Datei zu erstellen. Fügen Sie diese Zeile zum Textkörper derfor
-Schleife direkt über dem Schlüsselwortdone
hinzu:
go-executable-build.bash
...
if [ $GOOS = "windows" ]; then
output_name+='.exe'
fi
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
done
Schließlich sollten wir überprüfen, ob Fehler beim Erstellen der ausführbaren Datei aufgetreten sind. Beispielsweise kann ein Fehler auftreten, wenn wir versuchen, ein Paket zu erstellen, für das wir keine Quellen haben. Wir können den Rückkehrcode des Befehlsgo build
auf einen Wert ungleich Null überprüfen. Die Variable$?
enthält den Rückkehrcode aus der Ausführung eines vorherigen Befehls. Wenngo build
etwas anderes als0
zurückgibt, ist ein Problem aufgetreten, und wir möchten das Skript beenden. Fügen Sie diesen Code nach dem Befehlgo build
und über dem Schlüsselwortdone
zur Schleifefor
hinzu.
go-executable-build.bash
...
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
if [ $? -ne 0 ]; then
echo 'An error has occurred! Aborting the script execution...'
exit 1
fi
Damit haben wir jetzt ein Skript, das mehrere ausführbare Dateien aus unserem Go-Paket erstellt. Hier ist das fertige Skript:
go-executable-build.bash
#!/usr/bin/env bash
package=$1
if [[z "$package" ]]; then
echo "usage: $0 "
exit 1
fi
package_split=(${package//\// })
package_name=${package_split[-1]}
platforms=("windows/amd64" "windows/386" "darwin/amd64")
for platform in "${platforms[@]}"
do
platform_split=(${platform//\// })
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
output_name=$package_name'-'$GOOS'-'$GOARCH
if [ $GOOS = "windows" ]; then
output_name+='.exe'
fi
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
if [ $? -ne 0 ]; then
echo 'An error has occurred! Aborting the script execution...'
exit 1
fi
done
Stellen Sie sicher, dass Ihre Datei mit dem vorhergehenden Code übereinstimmt. Speichern Sie dann die Datei und beenden Sie den Editor.
Bevor wir das Skript verwenden können, müssen wir es mit dem Befehlchmod
ausführbar machen:
chmod +x go-executable-build.bash
Testen Sie das Skript, indem Sie ausführbare Dateien für Caddy erstellen:
./go-executable-build.bash github.com/mholt/caddy/caddy
Wenn alles gut geht, sollten Sie ausführbare Dateien in Ihrem aktuellen Verzeichnis haben. Keine Ausgabe zeigt eine erfolgreiche Skriptausführung an. Sie können überprüfen, ob ausführbare Dateien mit dem Befehlls
erstellt wurden:
ls caddy*
Sie sollten alle drei Versionen sehen:
Example ls outputcaddy-darwin-amd64 caddy-windows-386.exe caddy-windows-amd64.exe
Um die Zielplattformen zu ändern, ändern Sie einfach die Variableplatforms
in Ihrem Skript.
Fazit
In diesem Lernprogramm erfahren Sie, wie Sie mit den Tools von Go Pakete aus Versionskontrollsystemen abrufen und ausführbare Dateien für verschiedene Plattformen erstellen und kompilieren.
Sie haben auch ein Skript erstellt, mit dem Sie ein einzelnes Paket für viele Plattformen übergreifend kompilieren können.
Um sicherzustellen, dass Ihre Anwendung ordnungsgemäß funktioniert, können Sie sichtesting undcontinuous integration wieTravis-CI undAppVeyor zum Testen unter Windows ansehen.
Wenn Sie sich für Caddy interessieren und wissen, wie man es benutzt, schauen Sie sichHow to Host a Website with Caddy on Ubuntu 16.04 an.