Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 14589] ファイルの概要

このコミットは、Go言語のコマンドラインツール goversion サブコマンドの出力に、現在のビルドが対象としているオペレーティングシステム(GOOS)とアーキテクチャ(GOARCH)の情報を追加する変更です。これにより、Goのバージョン情報がより詳細になり、特にクロスコンパイル環境や異なるプラットフォームでのデバッグ時に役立ちます。

コミット

commit 033e91548150e6e813b8af74873d2c067fbd7383
Author: Dave Cheney <dave@cheney.net>
Date:   Mon Dec 10 07:05:17 2012 +1100

    cmd/go: add GOOS/GOARCH to go version output
    
    Fixes #4492.
    
    % go version
    go version devel +6b602ab487d6 Sat Dec 08 14:43:00 2012 +0100 linux/amd64
    
    R=golang-dev, rsc
    CC=golang-dev
    https://golang.org/cl/6906058

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/033e91548150e6e813b8af74873d2c067fbd7383

元コミット内容

cmd/go: add GOOS/GOARCH to go version output

Fixes #4492.

% go version
go version devel +6b602ab487d6 Sat Dec 08 14:43:00 2012 +0100 linux/amd64

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6906058

変更の背景

この変更の背景には、Goプログラムが実行される環境や、Goツールチェインがターゲットとする環境をより明確に識別したいというニーズがありました。従来の go version コマンドの出力はGoのバージョン情報のみを提供していましたが、Goはクロスコンパイルを強力にサポートしているため、特定のGoバイナリがどのOS/アーキテクチャ向けにビルドされたのか、あるいは現在のGoツールチェインがどのOS/アーキテクチャ上で動作しているのかを知ることは、開発者にとって非常に重要です。

特に、以下のようなシナリオでこの情報が不可欠となります。

  1. デバッグとトラブルシューティング: 異なるOSやアーキテクチャで問題が発生した場合、go version の出力を見るだけで、そのGoバイナリが意図したターゲット向けにビルドされているかを確認できます。
  2. クロスコンパイルの確認: 開発者がWindows上でLinux/ARM向けにビルドしたバイナリを配布する際、ユーザーが go version を実行することで、それがLinux/ARM向けであることが一目で分かります。
  3. 環境の識別: CI/CDパイプラインや自動化スクリプトにおいて、Goのバージョンだけでなく、実行環境のOSとアーキテクチャをプログラム的に取得する必要がある場合に、この出力が利用できます。

この変更は、GoのIssue #4492(cmd/go: go version should print GOOS/GOARCH)に対応するものであり、コミュニティからの要望に応える形で実装されました。

前提知識の解説

go version コマンド

go version コマンドは、現在インストールされているGoツールチェインのバージョン情報を表示するために使用されます。これには、Goのリリースバージョン、コミットハッシュ、ビルド日時などが含まれます。この情報は、Goの環境設定や問題報告の際に非常に役立ちます。

GOOSGOARCH 環境変数

Goのビルドシステムは、GOOSGOARCH という2つの環境変数に大きく依存しています。これらはGoのクロスコンパイル機能の根幹をなすものです。

  • GOOS (Go Operating System): Goプログラムが実行されるターゲットのオペレーティングシステムを指定します。例えば、linuxwindowsdarwin (macOS)、freebsd などがあります。
  • GOARCH (Go Architecture): Goプログラムが実行されるターゲットのCPUアーキテクチャを指定します。例えば、amd64 (x86-64)、armarm64 (AArch64)、386 (x86) などがあります。

これらの環境変数を設定することで、開発者は現在のOS/アーキテクチャとは異なるOS/アーキテクチャ向けのバイナリを簡単にビルドできます。例えば、Linux上でWindows向けの実行ファイルをビルドするには、GOOS=windows GOARCH=amd64 go build のようにコマンドを実行します。

runtime パッケージ

Goの標準ライブラリには、プログラムの実行環境に関する情報を提供する runtime パッケージが含まれています。このパッケージは、Goプログラムが動作しているOS、アーキテクチャ、Goのバージョン、CPUの論理コア数など、様々なランタイム情報へのアクセスを提供します。

このコミットで特に使用されているのは以下の関数です。

  • runtime.Version(): 現在のGoのバージョン文字列を返します。例えば、go1.0.3devel +abcdef1234 のような形式です。
  • runtime.GOOS: 現在のGoプログラムがコンパイルされたターゲットのオペレーティングシステム名(文字列)を返します。これは GOOS 環境変数の値に対応します。
  • runtime.GOARCH: 現在のGoプログラムがコンパイルされたターゲットのCPUアーキテクチャ名(文字列)を返します。これは GOARCH 環境変数の値に対応します。

これらの関数は、Goプログラムが自身の実行環境を動的に知るために利用されます。

技術的詳細

この変更は、src/cmd/go/version.go ファイル内の runVersion 関数に小さな修正を加えることで実現されています。

go version コマンドが実行されると、cmd/go パッケージ内の runVersion 関数が呼び出されます。この関数は、Goのバージョン情報を取得し、標準出力に整形して表示する役割を担っています。

変更前は、fmt.Printf("go version %s\\n", runtime.Version()) という行で、runtime.Version() が返すGoのバージョン文字列のみが出力されていました。

変更後は、fmt.Printf("go version %s %s/%s\\n", runtime.Version(), runtime.GOOS, runtime.GOARCH) となり、runtime.GOOSruntime.GOARCH の値が追加で出力されるようになりました。これにより、出力フォーマットが go version <Goバージョン> <GOOS>/<GOARCH> の形式に拡張されました。

この修正は、Goのビルド時に runtime.GOOSruntime.GOARCH が埋め込まれる仕組みを利用しています。これらの値は、GoコンパイラがターゲットとするOSとアーキテクチャに基づいて決定され、コンパイルされたバイナリに静的にリンクされます。したがって、go version コマンド自体もGoで書かれたプログラムであるため、自身のビルドターゲット情報を runtime パッケージを通じて取得し、表示することが可能になります。

この変更は、Goのツールチェインの自己記述性を高め、開発者がより簡単に環境を理解し、デバッグできるようにするための、シンプルながらも効果的な改善です。

コアとなるコードの変更箇所

--- a/src/cmd/go/version.go
+++ b/src/cmd/go/version.go
@@ -21,5 +21,5 @@ func runVersion(cmd *Command, args []string) {
 		cmd.Usage()\n 	}\n 
-\tfmt.Printf("go version %s\\n", runtime.Version())\n+\tfmt.Printf("go version %s %s/%s\\n", runtime.Version(), runtime.GOOS, runtime.GOARCH)\n }\n

コアとなるコードの解説

変更は src/cmd/go/version.go ファイルの runVersion 関数内の一行に集約されています。

元のコード:

	fmt.Printf("go version %s\\n", runtime.Version())

この行は、runtime.Version() 関数が返すGoのバージョン文字列のみを %s のプレースホルダーに挿入し、go version <バージョン> の形式で出力していました。

変更後のコード:

	fmt.Printf("go version %s %s/%s\\n", runtime.Version(), runtime.GOOS, runtime.GOARCH)

この変更では、fmt.Printf のフォーマット文字列に新たに %s/%s が追加され、対応する引数として runtime.GOOSruntime.GOARCH が渡されています。

  • runtime.GOOS: 現在のGoツールチェインが動作している、またはターゲットとしているオペレーティングシステム(例: linux, windows, darwin)の文字列を返します。
  • runtime.GOARCH: 現在のGoツールチェインが動作している、またはターゲットとしているCPUアーキテクチャ(例: amd64, arm, arm64)の文字列を返します。

これにより、go version の出力は go version <Goバージョン> <GOOS>/<GOARCH> の形式に拡張され、例えば go version devel +6b602ab487d6 Sat Dec 08 14:43:00 2012 +0100 linux/amd64 のような、より詳細な情報を含むようになりました。

この修正は、Goの標準ライブラリが提供する runtime パッケージの情報を活用することで、最小限のコード変更で最大限の情報を追加するという、Goらしい簡潔なアプローチを示しています。

関連リンク

  • Go Issue #4492: cmd/go: go version should print GOOS/GOARCH
  • Gerrit Change-Id: https://golang.org/cl/6906058
    • GoプロジェクトのコードレビューシステムであるGerritにおけるこの変更のリンクです。

参考にした情報源リンク

  • Go言語公式ドキュメント - runtime パッケージ:
  • Go言語公式ドキュメント - go コマンド:
  • Go言語におけるクロスコンパイル:
    • GOOSGOARCH 環境変数の利用方法について解説している記事やドキュメント。
    • (一般的なGoのクロスコンパイルに関する情報源を指します。特定のURLは提供しませんが、Goの公式ブログやチュートリアルで多く言及されています。)