「go buildって何をするコマンド?」
「Goのプログラムをどうやって配布用にビルドするの?」
「クロスコンパイルで他のOSでも動くバイナリを作りたい」
Go言語でプログラムを書いたら、次は実行可能ファイルを作る必要がありますよね。その時に使うのがgo buildコマンドです。
このコマンドは、書いたGoのソースコードを、パソコンで直接実行できる形式(バイナリファイル)に変換してくれます。とてもシンプルで使いやすいツールなんです。
この記事では、go buildの基本から、実践的なオプション、クロスコンパイル、最適化まで、初心者の方でも分かるように丁寧に解説していきますね。
go buildって何?基本を理解しよう

ビルドとは
まず、ビルド(build)という言葉について確認しておきましょう。
ビルドは、人間が読み書きできるソースコード(プログラムの文章)を、コンピューターが直接実行できる形式(機械語)に変換する作業のことです。
例えるなら:
- ソースコード = 設計図や材料
- ビルド = 組み立て作業
- 実行可能ファイル = 完成品
Go言語で書いた.goファイルを、Windowsなら.exe、LinuxやMacならそのまま実行できるバイナリファイルに変換するのがビルドです。
go buildの役割
go buildは、Goの標準ツールの1つで、コンパイル(変換)とリンク(結合)を行ってくれます。
具体的には:
.goファイルを読み込む- 構文をチェックする
- 依存するパッケージも含めてコンパイルする
- 1つの実行可能ファイルにまとめる
これらが全部、go buildというコマンド1つで完了します。便利ですよね。
go runとの違い
Goにはgo runというコマンドもあります。違いを理解しておきましょう。
go run
go run main.go
- その場でコンパイルして実行
- 実行可能ファイルは作らない(一時的に作って削除)
- 開発中のテストに便利
go build
go build main.go
- 実行可能ファイルを作成
- 何度でも実行できる
- 他の人に配布できる
開発中はgo run、配布用はgo buildと使い分けるのが一般的です。
基本的な使い方
実際にgo buildを使ってみましょう。
最もシンプルな例
main.goというファイルを作ります:
package main
import "fmt"
func main() {
fmt.Println("Hello, Go!")
}
ビルドします:
go build main.go
これで実行可能ファイルが作られます。
Windowsの場合:main.exeが作られます。
LinuxやMacの場合:mainが作られます。
実行してみましょう:
Windows:
.\main.exe
Linux/Mac:
./main
「Hello, Go!」と表示されれば成功です!
プロジェクト全体をビルド
プロジェクトのフォルダ内で、ファイル名を指定せずに実行すると、プロジェクト全体がビルドされます:
cd my-project
go build
この場合、フォルダ名と同じ名前の実行可能ファイルが作られます。
フォルダ構造:
my-project/
├── main.go
├── utils.go
└── config.go
実行:
go build
結果:my-project(またはmy-project.exe)が作られます。
出力ファイル名を指定
-oオプションで、好きな名前を付けられます:
go build -o app main.go
これでapp(またはapp.exe)という名前のファイルが作られます。
実用例:
go build -o bin/myapp
go build -o dist/production-app.exe
便利なオプション一覧
go buildには様々なオプションがあります。よく使うものをご紹介しますね。
-o(出力ファイル名指定)
go build -o myapp main.go
カスタムの名前で保存できます。
-v(詳細表示)
go build -v
ビルド中のパッケージ名が表示されます。何が処理されているか分かるので、デバッグに便利です。
-a(全て再ビルド)
go build -a
キャッシュを使わず、全てのパッケージを再ビルドします。通常は不要ですが、クリーンなビルドが欲しい時に使います。
-race(競合検出)
go build -race
並行処理での競合状態(データの競合)を検出する機能を有効にします。マルチスレッドプログラムのデバッグに便利です。
-ldflags(リンカフラグ)
go build -ldflags="-s -w"
リンカー(プログラムを結合するツール)に指定を渡せます。
よく使うフラグ:
-s:シンボルテーブルを削除(デバッグ情報を除去)-w:DWARF情報を削除(さらにデバッグ情報を除去)- これらでファイルサイズを削減できます
バージョン情報を埋め込む例:
go build -ldflags="-X main.version=1.0.0"
プログラム内の変数に値を設定できます。
-tags(ビルドタグ)
go build -tags=production
条件付きコンパイルができます。環境によってコードを切り替えたい時に便利です。
コード例:
//go:build production
package config
const Debug = false
-trimpath(パス情報削除)
go build -trimpath
ビルドしたマシンのパス情報をバイナリから削除します。セキュリティやプライバシーのために使います。
クロスコンパイルをマスターしよう
Goの最大の魅力の1つが、クロスコンパイルです。
クロスコンパイルとは
自分のパソコンで、別のOS・アーキテクチャ向けのバイナリを作ることです。
例えば:
- Macで、Windows用のexeファイルを作る
- Windowsで、Linux用のバイナリを作る
- Intel CPUのマシンで、ARM用のバイナリを作る
通常、他の言語では難しい作業ですが、Goなら超簡単なんです。
環境変数の設定
クロスコンパイルは、GOOSとGOARCHという環境変数で制御します。
GOOS:ターゲットのOS
windowslinuxdarwin(macOS)freebsd- など
GOARCH:ターゲットのCPUアーキテクチャ
amd64(64ビットIntel/AMD)386(32ビットIntel)arm(ARM 32ビット)arm64(ARM 64ビット)- など
実践例:様々なプラットフォーム向けビルド
Mac/Linuxから、Windows 64ビット向け:
GOOS=windows GOARCH=amd64 go build -o app.exe
Windowsから、Linux 64ビット向け:
set GOOS=linux
set GOARCH=amd64
go build -o app
PowerShellの場合:
$env:GOOS="linux"
$env:GOARCH="amd64"
go build -o app
Mac Intel向け:
GOOS=darwin GOARCH=amd64 go build -o app
Mac Apple Silicon(M1/M2)向け:
GOOS=darwin GOARCH=arm64 go build -o app
Raspberry Pi向け:
GOOS=linux GOARCH=arm GOARM=7 go build -o app
複数プラットフォーム向けに一括ビルド
シェルスクリプトで自動化できます:
build-all.sh
#!/bin/bash
APP_NAME="myapp"
VERSION="1.0.0"
# Windows 64bit
GOOS=windows GOARCH=amd64 go build -o dist/${APP_NAME}-${VERSION}-windows-amd64.exe
# Linux 64bit
GOOS=linux GOARCH=amd64 go build -o dist/${APP_NAME}-${VERSION}-linux-amd64
# macOS Intel
GOOS=darwin GOARCH=amd64 go build -o dist/${APP_NAME}-${VERSION}-darwin-amd64
# macOS Apple Silicon
GOOS=darwin GOARCH=arm64 go build -o dist/${APP_NAME}-${VERSION}-darwin-arm64
echo "Build complete!"
実行:
chmod +x build-all.sh
./build-all.sh
一気に4つのプラットフォーム向けバイナリが作られます。
ビルドの最適化テクニック
より小さく、速いバイナリを作るテクニックをご紹介します。
ファイルサイズの削減
基本的な最適化:
go build -ldflags="-s -w" -o app
-sと-wでデバッグ情報を削除し、ファイルサイズを削減します。
さらに圧縮(UPX使用):
go build -ldflags="-s -w" -o app
upx --best --lzma app
UPX(Ultimate Packer for eXecutables)というツールで、さらに50〜70%ほど圧縮できます。
サイズ比較例:
- 通常ビルド:10MB
-s -w付き:7MB- UPX圧縮後:3MB
ビルド時間の短縮
並列ビルドの最大化:
go build -p 8
-pオプションで並列実行数を指定できます。CPUコア数に合わせて調整しましょう。
キャッシュの活用:
Goは自動的にビルド結果をキャッシュしますが、意図的にクリアしたい場合:
go clean -cache
静的リンク
外部ライブラリへの依存を減らし、完全に自己完結したバイナリを作ります:
CGO_ENABLED=0 go build -a -installsuffix cgo
特にDockerコンテナで動かす時に便利です。
ビルド情報の埋め込み
バージョン、ビルド日時、Gitコミットハッシュなどを埋め込む方法:
main.go
package main
import "fmt"
var (
version = "dev"
buildTime = "unknown"
gitCommit = "unknown"
)
func main() {
fmt.Printf("Version: %s\n", version)
fmt.Printf("Built: %s\n", buildTime)
fmt.Printf("Commit: %s\n", gitCommit)
}
ビルド:
go build -ldflags="-X main.version=1.0.0 -X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ) -X main.gitCommit=$(git rev-parse HEAD)"
実行すると、ビルド時の情報が表示されます。
実践的なビルドパターン
実際のプロジェクトで使える、実践的なパターンをご紹介します。
パターン1:開発用と本番用の切り替え
config.go
//go:build !production
package config
const (
Debug = true
APIBaseURL = "http://localhost:8080"
)
config_prod.go
//go:build production
package config
const (
Debug = false
APIBaseURL = "https://api.production.com"
)
開発用ビルド:
go build -o app-dev
本番用ビルド:
go build -tags=production -o app-prod
パターン2:Makefileで自動化
Makefile
APP_NAME=myapp
VERSION=1.0.0
BUILD_TIME=$(shell date -u +%Y-%m-%dT%H:%M:%SZ)
GIT_COMMIT=$(shell git rev-parse HEAD)
LDFLAGS=-ldflags "-s -w -X main.version=$(VERSION) -X main.buildTime=$(BUILD_TIME)"
.PHONY: build clean test
build:
go build $(LDFLAGS) -o bin/$(APP_NAME)
build-all:
GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o dist/$(APP_NAME)-windows.exe
GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o dist/$(APP_NAME)-linux
GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o dist/$(APP_NAME)-darwin
clean:
rm -rf bin dist
go clean
test:
go test -v ./...
release: clean build-all
cd dist && sha256sum * > checksums.txt
使い方:
make build # 現在のOS用にビルド
make build-all # 全プラットフォーム向けビルド
make test # テスト実行
make release # リリース用パッケージ作成
パターン3:Dockerでビルド
マルチステージビルドで、最小限のDockerイメージを作ります:
Dockerfile
# ビルドステージ
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags="-s -w" -o myapp
# 実行ステージ
FROM scratch
COPY --from=builder /app/myapp /myapp
ENTRYPOINT ["/myapp"]
ビルドと実行:
docker build -t myapp:latest .
docker run myapp:latest
scratchイメージを使うことで、5MB以下の超軽量イメージになります。
パターン4:CIでの自動ビルド
GitHub Actionsでの自動ビルド例:
.github/workflows/build.yml
name: Build
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Build
run: |
go build -v -ldflags="-s -w" -o myapp
- name: Test
run: go test -v ./...
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: myapp
path: myapp
よくある問題と解決法
go buildを使っていると遭遇する、典型的な問題と対処法です。
問題1:「package xxx is not in GOROOT」
エラー:
package github.com/user/repo is not in GOROOT
原因:
依存パッケージがダウンロードされていない。
解決法:
go mod download
go build
または、モジュールを初期化:
go mod init myapp
go mod tidy
go build
問題2:CGOが原因でクロスコンパイルできない
エラー:
cgo: C compiler "gcc" not found
原因:
CGO(C言語との連携)を使うパッケージがある場合、クロスコンパイルが複雑になります。
解決法:
CGOを無効化:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
ただし、一部のパッケージ(データベースドライバなど)は動作しなくなる可能性があります。
問題3:ビルドサイズが大きすぎる
症状:
Hello Worldレベルのプログラムなのに、10MBを超える。
原因:
デバッグ情報が含まれている。
解決法:
go build -ldflags="-s -w" -o app
さらに:
go build -ldflags="-s -w" -trimpath -o app
upx --best app
問題4:「cannot execute binary file」
症状:
LinuxでビルドしたファイルをWindowsで実行しようとしてエラー。
原因:
OSが違うバイナリを実行しようとしている。
解決法:
正しいOS向けにビルドし直す:
GOOS=windows GOARCH=amd64 go build -o app.exe
問題5:ビルドが遅い
原因:
- 大量の依存パッケージ
- キャッシュが無効化されている
- 並列実行数が少ない
解決法:
並列ビルドを増やす:
go build -p 8
不要なリビルドを避ける:
# -aオプションを外す
go build
モジュールキャッシュを確認:
go env GOMODCACHE
ビルドタグの活用
条件付きコンパイルで、環境に応じたビルドができます。
基本的な使い方
logger_dev.go
//go:build dev
package main
import "log"
func setupLogger() {
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.Println("Development logger initialized")
}
logger_prod.go
//go:build prod
package main
import "log"
func setupLogger() {
log.SetFlags(0)
}
main.go
package main
func main() {
setupLogger()
// アプリケーションのコード
}
ビルド:
# 開発版
go build -tags=dev -o app-dev
# 本番版
go build -tags=prod -o app-prod
OS別のコード
file_unix.go
//go:build linux || darwin
package main
import "syscall"
func getSystemInfo() string {
return "UNIX system"
}
file_windows.go
//go:build windows
package main
func getSystemInfo() string {
return "Windows system"
}
ビルドすると、自動的に適切なファイルが選ばれます。
まとめ:go buildを使いこなそう
go buildは、シンプルながら強力なビルドツールです。
この記事のポイントをおさらい:
- go buildはソースコードを実行可能ファイルに変換するコマンド
-oオプションで出力ファイル名を指定できる- クロスコンパイルが超簡単(GOOSとGOARCHを指定するだけ)
-ldflags="-s -w"でファイルサイズを削減- ビルドタグで条件付きコンパイルが可能
- Makefileやスクリプトで自動化できる
- Docker、CI/CDとの連携も簡単
- 静的リンクで依存関係のないバイナリを作成
- バージョン情報などをビルド時に埋め込める
Goの魅力の1つは、クロスコンパイルの簡単さです。1つのマシンで、Windows、Linux、Mac、さらにはRaspberry Pi向けのバイナリまで作れるのは本当に便利ですよね。
最初はgo buildだけで十分ですが、慣れてきたら様々なオプションを試して、最適なビルド方法を見つけてください。この記事が、あなたのGo開発の助けになれば嬉しいです!

コメント