Goのコアコマンド:run, build, install, get のマスター
Olivia Novak
Dev Intern · Leapcell

Goのシンプルさと効率性は、言語設計だけでなく、その強力で直感的なコマンドラインツールにも表れています。すべてのGo開発者にとって、go run、go build、go install、go get をしっかりと理解することは基本となります。これらのコマンドは、迅速なプロトタイピングからデプロイ、依存関係管理に至るまで、Go開発ワークフローのバックボーンを形成します。それぞれを実践的な例とともに詳しく見ていきましょう。
1. go run: クイックレスポンスプロトタイパー
go run コマンドは、特に開発の初期段階や簡単なスクリプトにおいて、Go開発者が最も頻繁に使用するコマンドと言えるでしょう。指定されたGoソースファイルを、現在のディレクトリに実行可能ファイルを作成することなく、コンパイルして実行します。これにより、迅速なイテレーションとテストが非常に便利になります。
仕組み:
go run を実行すると、Goは内部的にソースコードを一時的な実行可能ファイルにコンパイルしてから実行します。完了後、この一時的な実行可能ファイルは削除されます。
構文:
go run [build flags] [packages]
一般的なユースケース:
- 簡単なスクリプトの実行: 一度きりのタスクや小さなコードスニペットのテストに。
- 迅速なプロトタイピング: バイナリをビルドする中間ステップなしに、コード変更の即時出力を確認したい場合。
例1: 単一ファイルの実行
hello.go というファイルがあるとします。
// hello.go package main import "fmt" func main() { fmt.Println("Hello Go World!") }
このファイルを実行するには、次のように実行します。
go run hello.go
出力:
Hello Go World!
例2: パッケージ内の複数ファイルの実行
main パッケージが複数のファイルに分割されている場合でも、go run は対応できます。
main.go と util.go が同じディレクトリにあると仮定します。
// main.go package main import "fmt" func main() { fmt.Println("Result of calculation:", calculateSum(5, 3)) }
// util.go package main func calculateSum(a, b int) int { return a + b }
このプログラムを実行するには:
go run main.go util.go
または、より慣習的な方法として、現在のディレクトリの main パッケージを実行するには:
go run .
出力:
Result of calculation: 8
重要事項: go run は開発には非常に便利ですが、永続的な実行可能ファイルを作成しないため、デプロイメントシナリオには適していません。デプロイメントには、go build または go install が適切な選択肢です。
2. go build: 分布のためのコンパイル
go build コマンドは、Goパッケージと依存関係をコンパイルするために使用されます。go run とは異なり、配布および独立して実行できる実行可能バイナリファイル(またはパッケージアーカイブ)を作成します。
仕組み:
go build はGoソースコードをコンパイルします。パッケージが main パッケージの場合、実行可能ファイルが生成されます。ライブラリパッケージの場合、通常、コンパイルされたパッケージアーカイブ(例: .a ファイル)をビルドキャッシュ(通常は GOCACHE)にキャッシュし、後続のビルドを高速化します。
構文:
go build [build flags] [packages]
一般的なユースケース:
- 実行可能バイナリの作成: アプリケーションのデプロイ用。
- クロスコンパイル: 異なるオペレーティングシステムやアーキテクチャ用のバイナリの生成。
- コンパイルのテスト: 実際に実行せずにコードがコンパイルされることを確認するため。
例1: シンプルな実行可能ファイルのビルド
前述の hello.go を使用します。
// hello.go package main import "fmt" func main() { fmt.Println("Hello Go World!") }
実行可能ファイルをビルドするには:
go build hello.go
これにより、現在のディレクトリに hello(Linux/macOSの場合)または hello.exe(Windowsの場合)という名前の実行可能ファイルが作成されます。その後、直接実行できます。
./hello
出力:
Hello Go World!
例2: 出力名(-o)を指定したビルド
-o フラグを使用して、出力実行可能ファイルの名前を指定できます。
go build -o myapp hello.go
これで、実行可能ファイルの名前は myapp になります。
./myapp
出力:
Hello Go World!
例3: クロスコンパイル
Goの最も強力な機能の1つは、クロスコンパイルの組み込みサポートです。GOOS および GOARCH 環境変数を設定することで、異なるターゲットプラットフォーム(OSとアーキテクチャ)用のバイナリを簡単にビルドできます。
macOSマシンからARM 64ビットアーキテクチャ(例: Raspberry Pi)用のLinuxバイナリ hello.go をビルドするには:
GOOS=linux GOARCH=arm64 go build -o hello_linux_arm64 hello.go
これにより、Linux ARM64システムで実行できる hello_linux_arm64 という実行可能ファイルが生成されます。
モジュールのビルド:
Goモジュール内で作業する場合、引数が指定されていない場合、go build はデフォルトで現在のディレクトリのパッケージをビルドします。
# モジュールルートで、main.go が存在すると仮定 go build
これにより、現在のディレクトリのメインパッケージがビルドされ、実行可能ファイルが現在のディレクトリに配置されます。
3. go install: バイナリとパッケージのインストール
go install コマンドは go build と似ていますが、重要な違いがあります。コンパイルされた実行可能ファイルまたはパッケージアーカイブを、Go環境の標準的な場所、具体的には $GOPATH/bin($GOBIN が設定されていない場合)または GOBIN 環境変数で指定されたパスに配置します。これにより、システム全体で利用可能にしたいコマンドラインツールやライブラリのインストールに最適です。
仕組み:
go install はまずパッケージをコンパイルします。それが main パッケージの場合、結果の実行可能バイナリを GOBIN ディレクトリに移動します。ライブラリパッケージの場合、Goモジュールキャッシュ内の pkg ディレクトリにコンパイルされたパッケージアーカイブをインストールします。
構文:
go install [build flags] [packages]
一般的なユースケース:
- コマンドラインツールのインストール: Goプログラムをシステムコマンドとして使用したい場合(例: golangci-lint、delve)。
- グローバルユーティリティの管理: さまざまなGoベースのツールをすぐに利用できるようにする。
- 依存関係のビルドとキャッシュ: ライブラリパッケージの場合、go installはそれらをビルドしてキャッシュし、将来のビルドを高速化します。
例1: コマンドラインツールのインストール
簡単なツール greeter.go を作成しましょう。
// greeter.go package main import ( "fmt" "os" ) func main() { if len(os.Args) < 2 { fmt.Println("Usage: greeter <name>") return } name := os.Args[1] fmt.Printf("Greetings, %s!\n", name) }
このツールをインストールするには:
go install greeter.go
インストール後、greeter 実行可能ファイルは $GOPATH/bin または $GOBIN ディレクトリに配置されます。このディレクトリがシステムの PATH に含まれていることを確認してください。
これで、ターミナルからどこでも実行できます。
greeter Alice
出力:
Greetings, Alice!
例2: リモートリポジトリからのインストール(Go Modules)
Go Modulesを使用すると、go install は外部リポジトリから直接 GOBIN に実行可能ファイルをインストールするのに推奨される方法です。これにより、リポジトリを手動でクローンする手間が省けます。
go install github.com/spf13/cobra@latest
このコマンドは cobra モジュールを取得し、その main パッケージをコンパイルして、実行可能ファイル(おそらく cobra という名前)を GOBIN ディレクトリに配置します。@latest サフィックスは、Goに最新の安定バージョンを取得するように指示します。特定のバージョンタグ(例: @v1.2.3)を指定することもできます。
go build と go install の違い:
- go buildは実行可能ファイルを現在のディレクトリ(または- -oで指定された場所)に配置します。
- go installは実行可能ファイルを- $GOBIN(または- $GOPATH/bin)に配置します。
- go installは、コンパイルされたパッケージをビルドキャッシュにもインストールし、それらのパッケージに依存する後続の- go buildコマンドを高速化します。
4. go get: 依存関係の管理(レガシーとモダン)
go get コマンドは、Go Modules の導入により大幅に進化しました。
Go Modules 前(GOPATH モード):
古い GOPATH モードでは、go get は主にパッケージをリモートリポジトリから $GOPATH/src ディレクトリにダウンロードしてインストールするために使用されていました。また、依存関係を再帰的にダウンロードすることで管理していました。
Go Modules(モダンなアプローチ):
Go Modules(Go 1.11で導入、Go 1.16以降デフォルト)では、go get の役割が変わりました。主な機能は次のとおりです。
- go.modファイルの依存関係の追加、アップグレード、ダウングレード。
- go.modおよび- go.sumファイルの同期。
仕組み(Go Modules):
モジュール内で go get を実行すると、go.mod および go.sum ファイルが更新され、指定された依存関係のバージョンが反映されます。その後、必要なモジュールがモジュールキャッシュ(通常は $GOPATH/pkg/mod)にフェッチされます。後続の go build、go run、go test コマンドは、これらのキャッシュされた依存関係を自動的に使用します。
構文:
go get [build flags] [packages]
一般的なユースケース(Go Modules):
- 新しい依存関係の追加: 新しい外部パッケージを使用したい場合。
- 依存関係のアップグレード: 既存のパッケージの最新の互換性のあるバージョンを取得する場合。
- 依存関係のダウングレード: 古いバージョンに戻す場合。
- 未使用の依存関係のクリーンアップ: 通常は go mod tidyによって処理されます。
例1: 新しい依存関係の追加
Goモジュールが初期化されていると仮定します。
mkdir mymodule cd mymodule go mod init mymodule
ここで、例として rsc.io/quote のような外部ライブラリを使用する main.go を作成します。
// main.go package main import ( "fmt" "rsc.io/quote" // この依存関係はまだ go.mod にありません ) func main() { fmt.Println(quote.Go()) }
go run main.go または go build を試すと、Goは不足している依存関係を検出し、go mod tidy を実行するように促すか、自動的に取得しようとします。
明示的に追加(および取得)するには:
go get rsc.io/quote
このコマンドの後、go.mod ファイルは次のようなものに更新されます。
module mymodule go 1.22 require rsc.io/quote v1.5.0 // または類似のバージョン
そして、go.sum ファイルが作成/更新され、暗号化されたチェックサムが含まれます。これでプログラムを実行できます。
go run main.go
出力:
Don't communicate by passing memory, share memory by communicating.
例2: 依存関係のアップグレード
既存の依存関係を最新の互換性のあるバージョンにアップグレードするには:
go get rsc.io/quote@latest
これにより、go.mod および go.sum ファイルが最新の安定リリースを指すように更新されます。
例3: 依存関係のダウングレードまたはバージョンの指定
特定のバージョンが必要な場合:
go get rsc.io/quote@v1.5.2
go get と go install に関する注意:
前述のように、go install はコマンドラインツールを「取得してインストール」するための推奨される方法です。以前は go get もこれを行うことができましたが(特に GOPATH モード)、go install はより曖昧さがなく、ツールのインストールにおけるモジュールシステムとの統合が優れています。
例えば、delve(Goデバッガ)をインストールするには:
go install github.com/go-delve/delve/cmd/dlv@latest
これは通常、go get github.com/go-delve/delve/cmd/dlv よりも推奨されます。
結論
go run、go build、go install、go get コマンドは、Go開発ツールの柱です。
- go run: クイック実行と開発イテレーションに使用します。
- go build: アプリケーションの配布可能な実行可能ファイルを作成するために使用します。
- go install: Goプログラムをシステム全体で利用可能なツールとしてインストールしたり、ライブラリパッケージをキャッシュするために使用します。
- go get(Go Modules内): プロジェクトの依存関係を管理し、正しいバージョンと再現可能なビルドを保証するために使用します。
これらのコマンドをマスターすることで、Go開発者は最初のコード行の記述から堅牢なアプリケーションのデプロイまで、プロジェクトを効率的に管理できるようになります。これらは、シンプルで効率的なGoの哲学を体現しており、明確で簡潔なコマンドを通じて強力な機能を提供します。