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

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

このコミットは、Go言語のビルドシステムにおいて、goapiquietgcccgogotypeebnflint といった内部ツール群を $GOROOT/bin/go-tool ディレクトリ配下に移動させる変更です。これにより、Goのツール群の管理と利用方法が整理され、ビルドプロセスの整合性が向上します。

コミット

commit 9a15c2186c59544d4587487f075ccee385373823
Author: Russ Cox <rsc@golang.org>
Date:   Tue Jan 31 10:38:07 2012 -0500

    build: move goapi, quietgcc, cgo, gotype, ebnflint into go-tool
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/5552054

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

https://github.com/golang/go/commit/9a15c2186c59544d4587487f075ccee385373823

元コミット内容

build: move goapi, quietgcc, cgo, gotype, ebnflint into go-tool

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5552054

変更の背景

Go言語のビルドシステムは、その開発初期から進化を続けています。このコミットが行われた2012年当時、Goのツールチェインはまだ成熟の途上にあり、様々な内部ツールがGoのソースツリー内の異なる場所に散在していました。これらのツールは、Goプログラムのビルド、テスト、解析など、Go開発の基盤を支える重要な役割を担っています。

この変更の主な背景には、以下の点が挙げられます。

  1. ツールの一元管理と発見可能性の向上: 複数のツールが異なるディレクトリに配置されていると、それらの管理が煩雑になり、開発者がどのツールがどこにあるのかを把握しにくくなります。go-tool ディレクトリに集約することで、Goの内部ツール群が論理的に一箇所にまとめられ、発見しやすくなります。
  2. ビルドプロセスの整合性: Goのビルドシステムは、GOROOTGOBIN といった環境変数に依存して動作します。これらのツールが $GOROOT/bin/go-tool という特定のパスに配置されることで、ビルドスクリプトや他のツールがこれらのツールをより確実に、かつ一貫した方法で参照できるようになります。これは、クロスコンパイルや異なる環境でのビルドの安定性にも寄与します。
  3. 将来的な拡張性: ツール群を特定のディレクトリにまとめることで、将来的に新しい内部ツールを追加したり、既存のツールを更新したりする際の構造が明確になります。これにより、ビルドシステムのメンテナンス性と拡張性が向上します。
  4. goapi のリネーム: goapi ツールは、GoパッケージのエクスポートされたAPIを計算する役割を担っていますが、その名称が go コマンドのサブコマンドと紛らわしい可能性がありました。src/cmd/api へのリネームは、その役割をより明確にし、命名規則の整合性を図る目的があります。

これらの背景から、Goのビルドシステムをより堅牢で、管理しやすく、そして将来にわたって持続可能なものにするための重要な一歩として、このコミットが実施されました。

前提知識の解説

このコミットを理解するためには、以下のGo言語のビルドシステムと関連ツールの基本的な概念を理解しておく必要があります。

  • GOROOT: Goのインストールディレクトリのルートパスを示す環境変数です。Goの標準ライブラリ、ツールチェイン、ソースコードなどがこのディレクトリ配下に配置されます。
  • GOBIN: Goの実行可能バイナリがインストールされるディレクトリを示す環境変数です。通常、go install コマンドでビルドされたプログラムがここに配置されます。
  • Goのビルドプロセス: Goのプログラムは、go buildgo install といったコマンドによってビルドされます。これらのコマンドは、内部的にコンパイラ、リンカ、アセンブラなどのツールチェインを呼び出して実行可能ファイルを生成します。
  • go-tool ディレクトリ: $GOROOT/bin/go-tool は、Goの内部ツールや補助的な実行可能ファイルが配置される特別なディレクトリです。これらのツールは、Goのビルドシステムや開発プロセスをサポートするために使用されます。
  • Make.inc: Goのビルドシステムで使用されるMakefileのインクルードファイルの一つです。ビルドに関する共通の設定や変数が定義されています。
  • make.bash: GoのソースコードからGoのツールチェイン全体をビルドするためのシェルスクリプトです。Goの初期のビルドプロセスにおいて重要な役割を担っていました。
  • autogen.sh: Goのランタイムパッケージ (src/pkg/runtime) で使用される自動生成スクリプトです。C言語のソースコードを生成したり、バージョン情報を埋め込んだりする際に利用されます。

このコミットで移動される主要なツールは以下の通りです。

  • goapi (リネーム後 api): GoパッケージのエクスポートされたAPI(関数、型、変数など)を抽出・計算するためのツールです。APIの互換性チェックなどに利用されます。
  • quietgcc: GCCコンパイラをラップし、特定の警告や出力を抑制するためのスクリプトまたはツールです。Goのビルドプロセスにおいて、CgoなどC言語との連携部分で利用されることがあります。
  • cgo: GoとC言語のコードを相互に呼び出すためのメカニズムを提供するツールです。Cgoを使用すると、Goプログラムから既存のCライブラリを呼び出したり、CのコードをGoプログラムに組み込んだりすることができます。
  • gotype: Goのソースコードの型チェックを行うツールです。コンパイル前にコードの構文や型の一貫性を検証するのに役立ちます。
  • ebnflint: EBNF (Extended Backus-Naur Form) 形式の文法定義を解析し、構文エラーなどをチェックするツールです。Goのパーサーや言語仕様に関連する部分で利用される可能性があります。

これらのツールは、Go言語のコンパイラやランタイムの内部的な開発、テスト、およびメンテナンスにおいて不可欠な要素です。

技術的詳細

このコミットの技術的な詳細は、主にGoのビルドシステムにおけるツールのパス解決と、それらのツールがGoの標準的なツールチェインの一部として認識されるようにするための変更に集約されます。

  1. goapi のリネームと移動:

    • src/cmd/goapi ディレクトリが src/cmd/api にリネームされました。これは、ツールの役割をより明確にし、go コマンドのサブコマンドとの混同を避けるためです。
    • 同時に、このツールは $GOROOT/bin/go-tool/api としてインストールされるようになります。
  2. quietgcc のパス変更:

    • src/Make.inc において、HOST_CCHOST_LD の定義が quietgcc から $(QUOTED_GOROOT)/bin/go-tool/quietgcc に変更されました。これは、ビルド時に使用されるCコンパイラとリンカのラッパーである quietgcc が、go-tool ディレクトリから参照されるようにするためです。
    • src/make.bash では、quietgcc スクリプトの生成パスが $GOBIN/quietgcc から $GOROOT/bin/go-tool/quietgcc に変更されました。これにより、quietgcc$GOROOT/bin/go-tool 配下に配置され、ビルドシステム全体で一貫して参照されるようになります。
  3. src/cmd/go/pkg.goisGoTool マップの更新:

    • src/cmd/go/pkg.go ファイル内の isGoTool マップは、go コマンドが内部的に認識する $GOROOT/bin/go-tool にインストールされるGoプログラムのリストを定義しています。
    • このコミットでは、cmd/api (旧 cmd/goapi)、cmd/cgoexp/gotypeexp/ebnflint がこのマップに追加されました。これにより、go コマンドはこれらのツールをGoの公式ツールとして認識し、適切なパス解決を行うことができるようになります。
  4. src/pkg/runtime/autogen.sh のパス変更:

    • src/pkg/runtime/autogen.sh スクリプト内で、goc2cmkversion のビルド時に quietgcc を呼び出す箇所が、単なる quietgcc から "$GOROOT"/bin/go-tool/quietgcc に変更されました。これは、ランタイムの自動生成プロセスにおいても、go-tool ディレクトリに配置された quietgcc を明示的に使用するようにするためです。

これらの変更は、Goのビルドシステムが内部ツールをどのように発見し、実行するかというメカニズムに直接影響を与えます。ツールのパスをハードコードするのではなく、GOROOT を基準とした相対パスで参照することで、ビルド環境の柔軟性と移植性が向上します。また、isGoTool マップの更新は、go コマンドがこれらのツールを「公式」なものとして扱い、必要に応じて適切な処理を行うための内部的なフックを提供します。

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

このコミットにおける主要なコード変更は以下のファイルに集中しています。

  1. src/Make.inc:

    --- a/src/Make.inc
    +++ b/src/Make.inc
    @@ -105,8 +105,8 @@ LD=$(QUOTED_GOROOT)/bin/go-tool/$(O)l
     OS=568vq
     CFLAGS=-FVw
     
    -HOST_CC=quietgcc
    -HOST_LD=quietgcc
    +HOST_CC=$(QUOTED_GOROOT)/bin/go-tool/quietgcc
    +HOST_LD=$(QUOTED_GOROOT)/bin/go-tool/quietgcc
     HOST_O=o
     HOST_YFLAGS=-d
     HOST_AR?=ar
    

    HOST_CCHOST_LDquietgcc から $GOROOT/bin/go-tool/quietgcc を指すように変更されました。

  2. src/cmd/{goapi => api}/goapi.go (リネーム):

    --- a/src/cmd/goapi/goapi.go
    +++ b/src/cmd/api/goapi.go
    @@ -2,7 +2,7 @@
     // Use of this source code is governed by a BSD-style
     // license that can be found in the LICENSE file.\n
     
    -// Goapi computes the exported API of a set of Go packages.\n
    +// Api computes the exported API of a set of Go packages.\n
     package main
     
     import (
    

    ファイル名が goapi.go から api.go に変更され、内部のコメントも Goapi から Api に修正されました。

  3. src/cmd/go/pkg.go:

    --- a/src/cmd/go/pkg.go
    +++ b/src/cmd/go/pkg.go
    @@ -229,9 +229,13 @@ Loop:\n
     // isGoTool is the list of directories for Go programs that are installed in
     // $GOROOT/bin/go-tool.\n
     var isGoTool = map[string]bool{\n
    -\t\"cmd/fix\":  true,\n
    -\t\"cmd/vet\":  true,\n
    -\t\"cmd/yacc\": true,\n
    +\t\"cmd/api\":      true,\n
    +\t\"cmd/cgo\":      true,\n
    +\t\"cmd/fix\":      true,\n
    +\t\"cmd/vet\":      true,\n
    +\t\"cmd/yacc\":     true,\n
    +\t\"exp/gotype\":   true,\n
    +\t\"exp/ebnflint\": true,\n
     }\n
     
     func scanPackage(ctxt *build.Context, t *build.Tree, arg, importPath, dir string, stk *importStack) *Package {
    

    isGoTool マップに cmd/apicmd/cgoexp/gotypeexp/ebnflint が追加されました。

  4. src/make.bash:

    --- a/src/make.bash
    +++ b/src/make.bash
    @@ -44,10 +44,11 @@ export MAKEFLAGS
     unset CDPATH\t# in case user has it set
     
     rm -f "$GOBIN"/quietgcc
    +rm -f "$GOROOT/bin/go-tool/quietgcc"
     CC=${CC:-gcc}
     export CC
    -sed -e "s|@CC@|$CC|" < "$GOROOT"/src/quietgcc.bash > "$GOBIN"/quietgcc
    -chmod +x "$GOBIN"/quietgcc
    +sed -e "s|@CC@|$CC|" < "$GOROOT"/src/quietgcc.bash > "$GOROOT"/bin/go-tool/quietgcc
    +chmod +x "$GOROOT"/bin/go-tool/quietgcc
     
     export GOMAKE="$GOROOT"/bin/go-tool/make
     rm -f "$GOBIN"/gomake
    

    quietgcc の生成パスが $GOBIN から $GOROOT/bin/go-tool に変更されました。

  5. src/pkg/runtime/autogen.sh:

    --- a/src/pkg/runtime/autogen.sh
    +++ b/src/pkg/runtime/autogen.sh
    @@ -27,7 +27,7 @@ if [ "$GOROOT" = "" ]; then
     fi
     
     # Use goc2c to translate .goc files into arch-specific .c files.
    -quietgcc -o goc2c -I "$GOROOT/include" goc2c.c "$GOROOT/lib/lib9.a"
    +"$GOROOT"/bin/go-tool/quietgcc -o goc2c -I "$GOROOT/include" goc2c.c "$GOROOT/lib/lib9.a"
     for file in *.goc
     do
     	for arch in $GOARCHES
    @@ -39,7 +39,7 @@ do
     done
     
     # Version constants.
    -quietgcc -o mkversion -I "$GOROOT/include" mkversion.c "$GOROOT/lib/lib9.a"
    +"$GOROOT"/bin/go-tool/quietgcc -o mkversion -I "$GOROOT/include" mkversion.c "$GOROOT/lib/lib9.a"
     GOROOT="$GOROOT_FINAL" ./mkversion >z.tmp
     mv z.tmp zversion.go
     
    

    autogen.sh 内で quietgcc を呼び出す際に、明示的に $GOROOT/bin/go-tool/quietgcc のパスを使用するように変更されました。

コアとなるコードの解説

これらの変更は、Goのビルドシステムにおけるツールの配置と参照方法を標準化し、一貫性を持たせることを目的としています。

  • src/Make.inc の変更:

    • Make.inc はGoのビルドプロセス全体で利用される共通のMakefile設定です。ここで HOST_CCHOST_LD のパスを $GOROOT/bin/go-tool/quietgcc に変更することで、GoのビルドシステムがCコンパイラとリンカのラッパーとして quietgcc を使用する際に、そのツールが $GOROOT/bin/go-tool ディレクトリに存在することを期待するようになります。これにより、ビルドの依存関係が明確になり、quietgcc がどこに配置されていても正しく参照されるようになります。
  • src/cmd/{goapi => api}/goapi.go のリネーム:

    • goapi はGoのAPIを解析する重要なツールですが、その名前が go コマンドのサブコマンドと紛らわしいという問題がありました。api へのリネームは、ツールの目的をより簡潔かつ明確に表現し、Goのツールチェイン全体の命名規則との整合性を高めます。これにより、開発者がツールの役割を直感的に理解しやすくなります。
  • src/cmd/go/pkg.goisGoTool マップの更新:

    • isGoTool マップは、go コマンドが内部的に管理する「公式な」Goツールの一覧です。このマップに cmd/apicmd/cgoexp/gotypeexp/ebnflint を追加することで、go コマンドはこれらのツールを特別なものとして扱い、例えば go install でビルドする際に $GOROOT/bin/go-tool に配置されるべきであると認識します。これは、Goのツールチェインの自己ホスティング能力と、内部ツールの管理を強化する上で重要です。
  • src/make.bash の変更:

    • make.bash はGoのソースからGo全体をビルドするスクリプトであり、quietgcc のような補助ツールを生成します。quietgcc の出力先を $GOBIN から $GOROOT/bin/go-tool に変更することで、quietgcc がGoの内部ツールとして正式に $GOROOT/bin/go-tool ディレクトリに配置されるようになります。これにより、ビルドプロセス全体で quietgcc のパスが統一され、他のビルドスクリプトやMakefileから一貫して参照できるようになります。
  • src/pkg/runtime/autogen.sh の変更:

    • autogen.sh はGoのランタイムパッケージのビルド時に、C言語のコード生成やバージョン情報の埋め込みを行うスクリプトです。このスクリプト内で quietgcc を呼び出す際に、明示的に $GOROOT/bin/go-tool/quietgcc のフルパスを使用するように変更することで、ビルド環境に依存せず、常に正しい quietgcc が実行されることが保証されます。これは、ビルドの信頼性と再現性を高める上で重要です。

これらの変更は、Goのビルドシステムがより堅牢で、自己完結的で、そして将来の拡張に対応できるような基盤を構築するための重要なステップでした。ツールの配置を標準化し、パス解決を統一することで、Goの開発者はより安定した環境で作業できるようになります。

関連リンク

参考にした情報源リンク