Cosa fa go build build? (vai a costruire vs vai a installare)


Risposte:


125

Quello che fa il gocomando dipende dal fatto che lo eseguiamo per un pacchetto "normale" o per il "main"pacchetto speciale .

Per i pacchetti

  • go build  crea il tuo pacchetto quindi scarta i risultati .
  • go installbuilds quindi installa il pacchetto nella tua $GOPATH/pkgdirectory.

Per i comandi (pacchetto main)

  • go build  crea il comando e lascia il risultato nella directory di lavoro corrente .
  • go installcrea il comando in una directory temporanea, quindi lo sposta in $GOPATH/bin.

A cosa passare go build?

Puoi passare pacchetti a go build, pacchetti che vuoi costruire. È anche possibile passare un elenco di .gofile da una singola directory, che viene quindi trattato come l'elenco dei file di origine che specificano un singolo pacchetto.

Se non vengono forniti pacchetti (percorsi di importazione), la build viene applicata alla directory corrente.

Un percorso di importazione può contenere uno o più "..."caratteri jolly (nel qual caso si tratta di un modello ). ...può corrispondere a qualsiasi stringa, ad esempio net/...corrisponde al netpacchetto e ai pacchetti che si trovano in una qualsiasi delle sue sottocartelle. Il comando

go build ./...

spesso usato per costruire il pacchetto nella cartella corrente e tutti i pacchetti che ricorrono. Questo comando emesso in una radice del progetto compila il progetto completo.

Per ulteriori informazioni sulla specifica dei pacchetti, esegui go help packages.

Per quanto riguarda i moduli

Il supporto preliminare per i moduli Go è stato introdotto in Go 1.11 ei moduli sono diventati predefiniti a partire da Go 1.13. Quando lo gostrumento viene eseguito da una cartella che contiene un go.modfile (o uno dei genitori della cartella corrente), lo gostrumento viene eseguito in modalità compatibile con il modulo (la modalità legacy è chiamata modalità GOPATH ).

In modalità module-aware, GOPATH non definisce più il significato delle importazioni durante una compilazione, ma memorizza comunque le dipendenze scaricate (in GOPATH / pkg / mod) e i comandi installati (in GOPATH / bin, a meno che non sia impostato GOBIN).

Quando si creano moduli, ciò che viene creato è specificato dall'elenco di build . L'elenco di compilazione contiene inizialmente solo il modulo principale (il modulo contenente la directory in cui goviene eseguito il comando) e le dipendenze del modulo principale vengono aggiunte all'elenco di compilazione, in modo ricorsivo (vengono aggiunte anche le dipendenze delle dipendenze).

Per maggiori informazioni, corri go help modules.


Fondamentalmente puoi usare go buildcome controllo che i pacchetti possano essere compilati (insieme alle loro dipendenze) mentre go installanche (permanentemente) installa i risultati nelle cartelle appropriate del tuo $GOPATH.

go build terminerà silenziosamente se tutto va bene e ti darà messaggi di errore se i pacchetti non possono essere compilati / compilati.

Ogni volta che lo gostrumento installa un pacchetto o un binario, installa anche tutte le dipendenze che ha, quindi l'esecuzione go installinstallerà automaticamente anche i pacchetti da cui dipende il tuo programma (pacchetti disponibili pubblicamente, "utilizzabili").

Per cominciare, leggi la pagina ufficiale Come scrivere il codice Go .

Ulteriori informazioni sullo gostrumento: Command go

È inoltre possibile ottenere ulteriore assistenza eseguendo il seguente comando:

go help build

Vale anche la pena notare che a partire da Go 1.5 go installrimuove anche gli eseguibili creati da go build( fonte ):

Se "go install" (senza argomenti, ovvero la directory corrente) ha successo, rimuovere l'eseguibile scritto da "go build", se presente. Questo evita di lasciare dietro di sé un binario stantio ...

Per completare l'elenco, go runcompila l'applicazione in una cartella temporanea e avvia il file binario eseguibile. Quando l'app si chiude, pulisce correttamente i file temporanei.

Domanda ispirata da Dave Cheney What does go build build?


1
sembra strano che go install non aggiorni l'eseguibile se è identico a quello precedentemente installato ... qualche intuizione qui?
Scott Stensland

14

Per pacchetto:

go build: crea il tuo pacchetto quindi scarta i risultati

Questo non sarà vero dopo Go 1.10 (Q1 2018), grazie a CL 68116 e CL 75473 . Vedi questo thread , a cui faccio riferimento qui.

Cosa fanno esattamente i comandi go builde go installcompilano

Ogni volta che lo strumento go installa un pacchetto o un binario, installa anche tutte le dipendenze che ha, quindi l'esecuzione di go install installerà anche i pacchetti da cui dipende il tuo programma (pacchetti "go gettable" disponibili pubblicamente), automaticamente.

In realtà ... go installcambierà anche con Go 1.10, oltre alla nuova cache:

Il go installcomando " " non installa più le dipendenze dei pacchetti denominati ( CL 75850 ).

Se esegui " go install foo", l'unica cosa installata èfoo .

Prima variava. Se le dipendenze "" non erano aggiornate, go installinstallavano anche le dipendenze.
L'installazione implicita delle dipendenze durante " go install" causava molta confusione e grattacapi agli utenti, ma in precedenza era necessario abilitare le build incrementali.
Non più.
Pensiamo che la nuova " install what I said" semantica sarà molto più comprensibile, soprattutto perché è chiaro dalle segnalazioni di bug che molti utenti se lo aspettavano già.
Per forzare l'installazione delle dipendenze durante " go install", utilizzare il nuovo " go install -i" , in analogia con " go build -i" e " go test -i".

Il fatto che " go install" installasse qualsiasi dipendenza ricostruita causava confusione molto spesso in combinazione con -a, che significa " force rebuild of all dependencies".
Ora, " go install -a myprog" forzerà una ricostruzione completa di tutte le dipendenze di myprog, così come myprogse stesso, ma myprogverrà solo installato. (Tutte le dipendenze ricostruite verranno comunque salvate nella cache di compilazione, ovviamente.)
Far funzionare questo caso in modo più comprensibile è particolarmente importante in combinazione con la nuova analisi di datazione basata sul contenuto, perché vede buoni motivi per ricostruire le dipendenze più spesso di prima , il che avrebbe aumentato la confusione sul "perché sono state installate le mie dipendenze".
Ad esempio, se esegui "go install -gcflags=-N myprog ", viene installato un filemyprogcostruito senza ottimizzazioni del compilatore, ma non reinstalla più anche i pacchetti myprogutilizzati dalla libreria standard senza ottimizzazioni del compilatore.


go build, gets? Ho un errore di compilazione cannot find package "github.com/spf13/cobra" in any of:…. Non so come dirlo per ottenerlo. Devo ottenere esplicitamente?
ctrl-alt-delor

@ ctrl-alt-delor Con quale versione di Go? Il tuo progetto contiene un go.modfile?
VonC

go version go1.11.4 linux/amd64. Non so go.mod. Sto ricostruendo https://github.com/cbroglie/mustache/blob/master/cmd/mustache/main.go, è strano perché ho appena creato l'intero pacchetto e sto usando questo esempio come base, e ho creato una versione più semplice che ha funzionato (ma non usando questa libreria). Non riesco a vedere come non sia stato installato con il pacchetto baffi.
ctrl-alt-delor

@ ctrl-alt-delor così cobr è venduto su github.com/cbroglie/mustache/tree/master/cmd/mustache/vendor/… . Il tuo GOPATH è impostato correttamente?
VonC

Ho scoperto quello che hai già trovato. Il pacchetto si trova in una sottodirectory del fornitore: questo è il motivo per cui non è stato installato. Tuttavia non so perché non lo installi ora su build. O come utilizzare la directory del fornitore (se lo copio nella mia directory).
ctrl-alt-delor
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.