[インデックス 12543] ファイルの概要
このコミットは、Go言語のビルドシステムにおける CGO_ENABLED
環境変数の管理方法に関する重要な変更を導入しています。具体的には、CGO_ENABLED
の設定ロジックを、Goの配布版ビルドツール (cmd/dist
) から、一般的なGoコマンド (cmd/go
) の環境変数表示機能 (go env
) へと移行しています。これにより、特定のOS/アーキテクチャの組み合わせがcgoをサポートしているかどうかの知識の重複を排除し、Goの環境設定の一元化を図っています。また、Goのテストスクリプト (src/run.bash
および src/sudo.bash
) も、この変更に合わせて go tool dist env
の代わりに go env
を使用するように更新されています。
コミット
commit 6d4da06d3647607081819e444be60259225d0efe
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Sat Mar 10 03:42:23 2012 +0800
cmd/dist, cmd/go: move CGO_ENABLED from 'go tool dist env' to 'go env'
So that we don't duplicate knowledge about which OS/ARCH combination
supports cgo.
Also updated src/run.bash and src/sudo.bash to use 'go env'.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5792055
---
src/cmd/dist/build.c | 18 ------------------
src/cmd/go/env.go | 6 ++++++
src/run.bash | 2 +--
src/sudo.bash | 2 +--
4 files changed, 8 insertions(+), 20 deletions(-)
diff --git a/src/cmd/dist/build.c b/src/cmd/dist/build.c
index d5fcfbedb3..acd7347aa8 100644
--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -52,19 +52,6 @@ static char *okgoos[] = {
"windows",
};
-// The known cgo-enabled combinations.
-// This list is also known to ../../pkg/go/build/build.go.
-static char *okcgo[] = {
- "darwin/386",
- "darwin/amd64",
- "linux/386",
- "linux/amd64",
- "freebsd/386",
- "freebsd/amd64",
- "windows/386",
- "windows/amd64",
-};
-
static void rmworkdir(void);
// find reports the first index of p in l[0:n], or else -1.
@@ -1321,11 +1308,6 @@ cmdenv(int argc, char **argv)
xprintf(format, "GOTOOLDIR", tooldir);
xprintf(format, "GOCHAR", gochar);
-\tif(find(bprintf(&b, "%s/%s", goos, goarch), okcgo, nelem(okcgo)) >= 0)
-\t\txprintf(format, "CGO_ENABLED", "1");
-\telse
-\t\txprintf(format, "CGO_ENABLED", "0");
-\
if(pflag) {
sep = ":";
if(streq(gohostos, "windows"))
diff --git a/src/cmd/go/env.go b/src/cmd/go/env.go
index 804dc8e63f..d5b0348096 100644
--- a/src/cmd/go/env.go
+++ b/src/cmd/go/env.go
@@ -45,6 +45,12 @@ func mkEnv() []envVar {\n \t\t{"GOGCCFLAGS", strings.Join(b.gccCmd(".")[3:], " ")},\n \t}\n \n+\tif buildContext.CgoEnabled {\n+\t\tenv = append(env, envVar{"CGO_ENABLED", "1"})\n+\t} else {\n+\t\tenv = append(env, envVar{"CGO_ENABLED", "0"})\n+\t}\n+\n \treturn env\n }\n \ndiff --git a/src/run.bash b/src/run.bash
index 0e4600b0ad..430ee76dba 100755
--- a/src/run.bash
+++ b/src/run.bash
@@ -5,7 +5,7 @@
set -e
-eval $(go tool dist env)
+eval $(go env)
unset CDPATH # in case user has it set
diff --git a/src/sudo.bash b/src/sudo.bash
index 78cdb0b8a7..cccebd3427 100755
--- a/src/sudo.bash
+++ b/src/sudo.bash
@@ -17,7 +17,7 @@ if [[ ! -d /usr/local/bin ]]; then
exit 2
fi
-eval $(go tool dist env)
+eval $(go env)
cd $(dirname $0)
for i in prof cov
do
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/6d4da06d3647607081819e444be60259225d0efe
元コミット内容
このコミットの目的は、CGO_ENABLED
環境変数の設定ロジックを go tool dist env
から go env
へと移動することです。これにより、どのOS/アーキテクチャの組み合わせがcgoをサポートしているかという知識の重複を排除します。また、src/run.bash
と src/sudo.bash
も go env
を使用するように更新されます。
変更の背景
Go言語のビルドシステムでは、C言語のコードをGoプログラムから呼び出すためのツールであるcgoの有効/無効を制御する CGO_ENABLED
という環境変数があります。この変数の値は、Goのビルドプロセスにおいて非常に重要です。
このコミット以前は、CGO_ENABLED
のデフォルト値(特定のOS/アーキテクチャの組み合わせでcgoが有効になるかどうか)に関する知識が、Goの配布版をビルドするためのツールである cmd/dist
と、Goのビルドシステムの中核をなす go/build
パッケージの両方に存在していました。これは「知識の重複」を意味し、将来的にcgoのサポート状況が変更された場合、複数の場所を更新する必要があるという保守性の問題を引き起こします。
この変更の主な目的は、この知識の重複を解消し、CGO_ENABLED
の決定ロジックを一元化することにあります。go env
コマンドは、ユーザーがGoの環境設定を確認するための主要なインターフェースであり、Goのビルドシステムが内部的に使用する環境変数を正確に反映するべきです。したがって、CGO_ENABLED
の決定ロジックを go env
の内部に移動することで、この変数の真のソースを一つに集約し、システム全体の整合性と保守性を向上させることができます。
また、Goのテストスクリプト (src/run.bash
と src/sudo.bash
) が go tool dist env
を使用して環境変数を設定していたことも、この変更の動機の一つです。go tool dist env
はGoの配布版ビルドに特化したツールであり、一般的なGo開発やテストのシナリオでは go env
を使用する方が適切です。この変更により、テストスクリプトもより一般的な go env
を利用するようになり、Goの環境設定に関するベストプラクティスに沿う形になります。
前提知識の解説
Goのビルドシステム
Go言語は、ソースコードをコンパイルして実行可能なバイナリを生成するための強力なビルドシステムを内蔵しています。このシステムは、依存関係の解決、クロスコンパイル、テストの実行など、様々なタスクを自動化します。Goのビルドシステムは、GOOS
(オペレーティングシステム)、GOARCH
(アーキテクチャ)、GOROOT
(Goのインストールディレクトリ)、GOPATH
(Goのワークスペースディレクトリ) など、様々な環境変数に依存して動作します。
go tool dist
go tool dist
は、Go言語の配布版(ディストリビューション)をビルド、テスト、インストールするための低レベルなツールです。これは主にGoの開発者や、GoのソースコードからGo自体をビルドする際に使用されます。go tool dist env
サブコマンドは、Goツールチェーンのビルドシステムが使用する環境変数を表示するために設計されています。これは、Goの内部ビルドプロセスに関する詳細な情報を提供しますが、一般的なGoアプリケーションの開発者が日常的に使用するものではありません。
go env
go env
は、Go言語の環境変数を表示するためのコマンドです。これは、Goプログラムのビルドや実行に影響を与える様々な設定(GOOS
, GOARCH
, GOROOT
, GOPATH
など)をユーザーが簡単に確認できるようにするために提供されています。go env
は、Goのビルドコマンド (go build
, go run
など) がどのように動作するかを理解する上で非常に役立ちます。このコマンドは、Go開発者にとって日常的に使用される重要なツールです。
CGO_ENABLED
CGO_ENABLED
は、GoプログラムがC言語のコードを呼び出すためのツールである cgo を有効にするかどうかを制御する環境変数です。
CGO_ENABLED=1
: cgoが有効になります。これにより、GoコードはCライブラリと連携できるようになります。cgoが有効な場合、Goプログラムは通常、Cライブラリに対して動的リンクを使用するため、生成されるバイナリは小さくなりますが、ターゲットシステムに共有ライブラリファイルが存在する必要があります。CGO_ENABLED=0
: cgoが無効になります。GoコードはC関数を呼び出すことができません。cgoを無効にすると、Goプログラムは完全に自己完結型の静的リンクされたバイナリを生成しやすくなります。これは、配布が容易で、ターゲットシステムに特定のライブラリがインストールされている必要がないという利点があります。
デフォルトでは、CGO_ENABLED
は一般的なプラットフォーム(Windows、macOS、Linux)の標準アーキテクチャ(amd64、386、armなど)では 1
に設定されています。しかし、クロスコンパイルを行う場合、Cのクロスコンパイル環境のセットアップが複雑になるため、デフォルトで無効になることがあります。
eval $(...)
eval $(...)
は、シェルスクリプトでコマンドの出力を評価し、その結果を現在のシェルのコマンドとして実行するための一般的なパターンです。このコミットの文脈では、go tool dist env
や go env
の出力が VAR=VALUE
の形式で環境変数の定義を含んでいるため、eval $(go env)
とすることで、これらの環境変数を現在のシェルセッションに設定することができます。
技術的詳細
このコミットの技術的詳細は、主に以下の3つの側面から構成されています。
-
src/cmd/dist/build.c
からのCGO_ENABLED
決定ロジックの削除:- 以前は、Goの配布版をビルドする際に使用される
cmd/dist
ツールの一部であるbuild.c
ファイル内に、特定のOS/アーキテクチャの組み合わせ (darwin/386
,linux/amd64
など) に対してCGO_ENABLED
を1
に設定するかどうかを決定するロジックが存在していました。 - このロジックは、
okcgo
という静的配列にcgoが有効な組み合わせのリストを持ち、現在のgoos/goarch
がそのリストに含まれるかどうかをfind
関数でチェックしていました。 - このコミットでは、この
okcgo
配列と、それに基づいてCGO_ENABLED
をxprintf
で出力するコードブロックが完全に削除されました。これにより、cmd/dist
はCGO_ENABLED
のデフォルト値を決定する責任を持たなくなりました。
- 以前は、Goの配布版をビルドする際に使用される
-
src/cmd/go/env.go
へのCGO_ENABLED
決定ロジックの移動:CGO_ENABLED
の決定ロジックは、Goの主要コマンドであるgo
コマンドの環境変数表示機能 (go env
) を実装するsrc/cmd/go/env.go
ファイルに移動されました。- 具体的には、
mkEnv()
関数内で、buildContext.CgoEnabled
の値に基づいてCGO_ENABLED
環境変数を1
または0
に設定し、env
スライスに追加するようになりました。 buildContext.CgoEnabled
は、Goのビルドシステムが内部的にcgoの有効/無効を判断する際に使用する真のソースです。この変更により、go env
が常にGoのビルドシステムが認識している正確なCGO_ENABLED
の状態を報告するようになります。
-
src/run.bash
およびsrc/sudo.bash
の更新:- Goのテストスイートを実行するためのシェルスクリプトである
src/run.bash
と、特権昇格を伴うテストを実行するためのsrc/sudo.bash
は、以前はeval $(go tool dist env)
を使用してGoの環境変数を設定していました。 - このコミットでは、これらのスクリプトが
eval $(go env)
を使用するように変更されました。 - この変更は、
CGO_ENABLED
の決定ロジックがgo env
に移動されたことと整合性を保つだけでなく、一般的なGo開発の文脈でより適切なgo env
コマンドを使用するというベストプラクティスにも従っています。
- Goのテストスイートを実行するためのシェルスクリプトである
この変更が「知識の重複を避ける」という目的を達成しているのは、CGO_ENABLED
のデフォルト値に関する情報が、cmd/dist
のビルドロジックと go/build
パッケージの両方に散在していた状態から、go/build
パッケージ(buildContext.CgoEnabled
を通じて)がその真のソースとなり、go env
がその情報を公開する唯一のインターフェースとなるためです。これにより、cgoのサポート状況に関する変更があった場合でも、更新すべき場所が明確になり、システム全体の整合性が保たれます。
go tool dist env
と go env
の違いは、前者がGoの配布版ビルドという特定の目的のための低レベルな環境情報を提供するのに対し、後者は一般的なGo開発環境の環境情報を提供するという点にあります。このコミットは、CGO_ENABLED
のような一般的なビルド設定に関する情報を、より広範なGo開発者コミュニティにとって関連性の高い go env
に集約することで、Goのツールエコシステムをより直感的で一貫性のあるものにしています。
コアとなるコードの変更箇所
src/cmd/dist/build.c
// 削除されたコードブロック
// The known cgo-enabled combinations.
// This list is also known to ../../pkg/go/build/build.go.
static char *okcgo[] = {
"darwin/386",
"darwin/amd64",
"linux/386",
"linux/amd64",
"freebsd/386",
"freebsd/amd64",
"windows/386",
"windows/amd64",
};
// ...
// 削除されたCGO_ENABLEDの設定ロジック
-\tif(find(bprintf(&b, "%s/%s", goos, goarch), okcgo, nelem(okcgo)) >= 0)
-\t\txprintf(format, "CGO_ENABLED", "1");
-\telse
-\t\txprintf(format, "CGO_ENABLED", "0");
src/cmd/go/env.go
// 追加されたCGO_ENABLEDの設定ロジック
+\tif buildContext.CgoEnabled {\n+\t\tenv = append(env, envVar{"CGO_ENABLED", "1"})\n+\t} else {\n+\t\tenv = append(env, envVar{"CGO_ENABLED", "0"})\n+\t}\n+\
src/run.bash
-eval $(go tool dist env)
+eval $(go env)
src/sudo.bash
-eval $(go tool dist env)
+eval $(go env)
コアとなるコードの解説
src/cmd/dist/build.c
の変更
このファイルから okcgo
という静的配列と、それを用いて CGO_ENABLED
の値を決定し出力するロジックが削除されました。これは、cmd/dist
がcgoのサポート状況に関する知識を持つ必要がなくなり、その責任がGoのビルドシステムの中核部分に委譲されたことを意味します。これにより、cgoのサポートに関する情報が複数の場所に分散している状態が解消され、保守性が向上します。
src/cmd/go/env.go
の変更
mkEnv()
関数内に、buildContext.CgoEnabled
の値に基づいて CGO_ENABLED
環境変数を設定するロジックが追加されました。buildContext.CgoEnabled
は、Goのビルドシステムが現在の環境でcgoが有効であると判断しているかどうかを示すブール値です。この変更により、go env
コマンドは、Goのビルドシステムが実際に使用する CGO_ENABLED
の値を正確に反映するようになります。これは、Goの環境設定に関する情報の一貫性を保つ上で非常に重要です。
src/run.bash
および src/sudo.bash
の変更
これらのシェルスクリプトでは、環境変数を設定するために go tool dist env
の代わりに go env
を使用するように変更されました。これは、CGO_ENABLED
の決定ロジックが go env
に移動されたことと直接関連しています。テストスクリプトが go env
を使用することで、Goのビルドシステムが認識している最新かつ正確な環境設定を確実に取得できるようになります。また、これはGoの一般的な開発ワークフローにおいて go env
が推奨されるツールであるという点にも合致しています。
関連リンク
- Go言語公式ドキュメント
- cgo コマンドのドキュメント
- Go Modules と環境変数 (Go Modulesは後のバージョンで導入されましたが、環境変数の理解に役立ちます)
参考にした情報源リンク
- alexedwards.net - Go: Environment Variables
- medium.com - Understanding Go Environment Variables
- go.dev -
go tool dist
- go.dev -
go env
- medium.com - CGO_ENABLED
- go.dev - Cross-compilation with cgo
- stackoverflow.com - What is CGO_ENABLED in Go?
- github.com - Go issue regarding CGO_ENABLED and cross-compilation (これは一般的な例であり、特定のイシューではありません)