Was macht Build Build? (go build vs. go install)

105

New Go-Programmierer wissen oft nicht oder sind nicht verwirrt, was der grundlegende Befehl go build bewirkt.

Was genau go buildund go installBefehle bauen und wo setzen sie das Ergebnis / Output?

icza
quelle
go build vs go install
Benyamin Jafari

Antworten:

125

Was der goBefehl tut, hängt davon ab, ob wir ihn für ein "normales" Paket oder für das spezielle "main"Paket ausführen .

Für Pakete

  • go build  erstellt Ihr Paket und verwirft dann die Ergebnisse .
  • go installBuilds installiert dann das Paket in Ihrem $GOPATH/pkgVerzeichnis.

Für Befehle (Paket main)

  • go build  Erstellt den Befehl und belässt das Ergebnis im aktuellen Arbeitsverzeichnis .
  • go installErstellt den Befehl in einem temporären Verzeichnis und verschiebt ihn dann in $GOPATH/bin.

Was soll ich weitergeben go build?

Sie können Pakete an go buildPakete übergeben, die Sie erstellen möchten. Sie können auch eine Liste von .goDateien aus einem einzelnen Verzeichnis übergeben, die dann als Liste der Quelldateien behandelt wird, die ein einzelnes Paket angeben.

Wenn keine Pakete (Importpfade) angegeben sind, wird der Build auf das aktuelle Verzeichnis angewendet.

Ein Importpfad kann einen oder mehrere "..."Platzhalter enthalten (in diesem Fall handelt es sich um ein Muster ). ...kann mit jeder Zeichenfolge übereinstimmen, z. B. net/...mit dem netPaket und den Paketen in einem seiner Unterordner. Der Befehl

go build ./...

Wird häufig verwendet, um das Paket im aktuellen Ordner zu erstellen, und alle Pakete werden erneut ausgeführt. Dieser in einem Projektstamm ausgegebene Befehl erstellt das gesamte Projekt.

Weitere Informationen zum Festlegen von Paketen finden Sie unter go help packages.

In Bezug auf Module

Die vorläufige Unterstützung für Go-Module wurde in Go 1.11 eingeführt, und Module wurden ab Go 1.13 zum Standard. Wenn das goWerkzeug aus einem Ordner ausgeführt wird , die eine enthält go.modDatei (oder einer der Eltern des aktuellen Ordners), das goWerkzeug läuft in Modul-aware - Modus (wird der Legacy - Modus genannt GOPATH Modus ).

Im modulsensitiven Modus definiert GOPATH die Bedeutung von Importen während eines Builds nicht mehr, speichert jedoch heruntergeladene Abhängigkeiten (in GOPATH / pkg / mod) und installierte Befehle (in GOPATH / bin, sofern GOBIN nicht festgelegt ist).

Beim Erstellen von Modulen wird in der Erstellungsliste angegeben, was erstellt wird . Die Erstellungsliste enthält anfänglich nur das Hauptmodul (das Modul, das das Verzeichnis enthält, in dem der goBefehl ausgeführt wird), und die Abhängigkeiten des Hauptmoduls werden rekursiv zur Erstellungsliste hinzugefügt (Abhängigkeiten von Abhängigkeiten werden ebenfalls hinzugefügt).

Weitere Informationen erhalten Sie unter go help modules.


Grundsätzlich können Sie go buildüberprüfen, ob die Pakete (zusammen mit ihren Abhängigkeiten) erstellt werden können, während Sie go installdie Ergebnisse auch (dauerhaft) in den richtigen Ordnern von Ihnen installieren $GOPATH.

go build wird stillschweigend beendet, wenn alles in Ordnung ist, und gibt Ihnen Fehlermeldungen, wenn die Pakete nicht erstellt / kompiliert werden können.

Wenn das goTool ein Paket oder eine Binärdatei installiert, werden auch alle Abhängigkeiten installiert, sodass beim Ausführen go installautomatisch Pakete installiert werden, von denen Ihr Programm abhängt (öffentlich verfügbare "go gettable" -Pakete).

Lesen Sie zunächst die offizielle Seite zum Schreiben von Go-Codes .

Weitere Informationen zum goTool: Befehl go

Sie können auch weitere Hilfe erhalten, indem Sie den folgenden Befehl ausführen:

go help build

Es ist auch erwähnenswert, dass ab Go 1.5 go installauch ausführbare Dateien entfernt werden, die von go build( Quelle ) erstellt wurden:

Wenn 'go install' (ohne Argumente, dh das aktuelle Verzeichnis) erfolgreich ist, entfernen Sie die ausführbare Datei, die von 'go build' geschrieben wurde, falls vorhanden. Dadurch wird vermieden, dass eine veraltete Binärdatei zurückbleibt ...

Um die Liste zu vervollständigen, go runkompilieren Sie Ihre Anwendung in einen temporären Ordner und starten Sie diese ausführbare Binärdatei. Wenn die App beendet wird, werden die temporären Dateien ordnungsgemäß bereinigt.

Frage inspiriert von Dave Cheneys Was macht Build Build?

icza
quelle
1
scheint seltsam, dass go install die ausführbare Datei nicht aktualisiert, wenn sie mit der zuvor installierten identisch ist ... irgendwelche Erkenntnisse hier?
Scott Stensland
14

Für Paket:

go build: erstellt Ihr Paket und verwirft dann die Ergebnisse

Dies wird nach Go 1.10 (Q1 2018) dank CL 68116 und CL 75473 nicht mehr der Fall sein . Siehe diesen Thread , auf den ich hier verweise.

Was genau machen die go buildund go installBefehle

Wenn das go-Tool ein Paket oder eine Binärdatei installiert, werden auch alle Abhängigkeiten installiert. Wenn Sie also go install ausführen, werden automatisch auch Pakete installiert, von denen Ihr Programm abhängt (öffentlich verfügbare "go gettable" -Pakete).

Eigentlich ... go installwird sich auch mit Go 1.10 zusätzlich zum neuen Cache ändern :

Der go installBefehl " " installiert keine Abhängigkeiten der genannten Pakete mehr ( CL 75850 ).

Wenn Sie " go install foo" ausführen , wird nur Folgendes installiertfoo .

Vorher war es unterschiedlich. Wenn Abhängigkeiten veraltet waren, go installinstallierte " " auch alle Abhängigkeiten.
Die implizite Installation von Abhängigkeiten während " go install" verursachte viel Verwirrung und Kopfschmerzen für die Benutzer, aber es war zuvor notwendig, inkrementelle Builds zu aktivieren.
Nicht länger.
Wir glauben, dass die neue " install what I said" Semantik viel verständlicher sein wird, zumal aus Fehlerberichten hervorgeht, dass viele Benutzer sie bereits erwartet haben.
Um die Installation von Abhängigkeiten während " go install" zu erzwingen , verwenden Sie das neue " go install -i" in Analogie zu " go build -i" und " go test -i".

Die Tatsache, dass " go install" verwendet wurde, um neu erstellte Abhängigkeiten zu installieren, verursachte am häufigsten Verwirrung in Verbindung mit -a, was " force rebuild of all dependencies" bedeutet .
Jetzt erzwingt " go install -a myprog" eine vollständige Neuerstellung aller Abhängigkeiten von myprogund von sich myprogselbst, wird jedoch nur myproginstalliert. (Alle neu erstellten Abhängigkeiten werden natürlich weiterhin im Build-Cache gespeichert.)
In Verbindung mit der neuen inhaltsbasierten Analyse der Stalenität ist es besonders wichtig, dass dieser Fall verständlicher funktioniert, da gute Gründe dafür bestehen, Abhängigkeiten häufiger als zuvor neu zu erstellen Dies hätte die Verwirrung über "Warum wurden meine Abhängigkeiten installiert?" erhöht.
Wenn Sie beispielsweise " go install -gcflags=-N myprog" ausführen , wird a installiertmyprogEs wurde ohne Compiler-Optimierungen erstellt, installiert jedoch nicht mehr die verwendeten Pakete myprogaus der Standardbibliothek ohne Compiler-Optimierungen.

VonC
quelle
Tut go build, tut gets? Ich habe einen Build-Fehler cannot find package "github.com/spf13/cobra" in any of:…. Ich weiß nicht, wie ich es sagen soll, um es zu bekommen. Muss ich explizit bekommen?
Strg-Alt-Delor
@ ctrl-alt-delor Mit welcher Version von Go? Enthält Ihr Projekt eine go.modDatei?
VonC
go version go1.11.4 linux/amd64. Ich weiß nichts über go.mod. Ich baue neu https://github.com/cbroglie/mustache/blob/master/cmd/mustache/main.go, es ist seltsam, da ich gerade das gesamte Paket erstellt habe und dieses Beispiel als Basis verwende. Ich habe eine einfachere Version erstellt, die funktioniert hat (aber diese Bibliothek nicht verwendet). Ich kann nicht sehen, wie es nicht mit dem Schnurrbartpaket installiert wurde.
Strg-Alt-Delor
@ ctrl-alt-delor, damit cobr verkauft wird github.com/cbroglie/mustache/tree/master/cmd/mustache/vendor/… . Ist Ihr GOPATH richtig eingestellt?
VonC
Ich habe entdeckt, was du bereits gefunden hast. Das Paket befindet sich in einem Hersteller-Unterverzeichnis. Aus diesem Grund wurde es nicht installiert. Ich weiß jedoch nicht, warum es jetzt beim Build nicht installiert wird. Oder wie man das Herstellerverzeichnis verwendet (wenn ich es in mein Verzeichnis kopiere).
Strg-Alt-Delor