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

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

コミット

commit 576311d72b53c6cec3f11d2fcc0dfd0d0eb76b7d
Author: Russ Cox <rsc@golang.org>
Date:   Wed Dec 14 10:24:17 2011 -0500

    go/build: make compatible with go/build
    
    The irony!
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/5482062

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

https://github.com/golang/go/commit/576311d72b53c6cec3f11d2fcc0dfd0d0eb76b7d

元コミット内容

go/build: make compatible with go/build

The irony!

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

変更の背景

このコミットは、Go言語のビルドシステムを扱う go/build パッケージに関するものです。コミットメッセージにある「The irony!」という表現が示唆するように、go/build パッケージ自体が、自身のビルドプロセスと互換性を持つように変更されたことを意味しています。

Go言語の初期段階では、ビルドプロセスやツールの進化が活発に行われていました。go/build パッケージは、Goのソースコードを解析し、パッケージの依存関係を解決し、ビルドに必要な情報を収集するための重要な役割を担っています。しかし、このパッケージが自身のビルド要件を満たしていなかった、あるいはビルドシステムが進化する中で、go/build パッケージのビルド方法が他のGoパッケージのビルド方法と異なる、または非効率的になっていた可能性があります。

具体的には、syslist.go というファイルが、以前は Makefile によって生成される一時ファイルとして扱われていたものが、このコミットによってGoのソースコードの一部として永続化されるように変更されています。これにより、go/build パッケージのビルドプロセスがより標準的なGoパッケージのビルドプロセスに統合され、自己参照的な互換性の問題が解消されたと考えられます。

前提知識の解説

  • Go言語のビルドシステム: Go言語は、go build コマンドによってソースコードをコンパイルし、実行可能ファイルを生成します。このビルドプロセスは、Goのツールチェインによって管理されており、ソースファイルの依存関係解決、パッケージのインポートパスの解決、クロスコンパイルなどが含まれます。
  • go/build パッケージ: Goの標準ライブラリの一部であり、Goのソースコードを解析し、パッケージのビルド情報を取得するための機能を提供します。例えば、特定のディレクトリにあるGoパッケージのソースファイル、依存関係、ビルドタグなどをプログラム的に取得する際に使用されます。Goのツールチェイン(go build, go get など)の内部でも利用されています。
  • Makefile: ソフトウェアのビルドプロセスを自動化するためのツールである make が使用する設定ファイルです。依存関係に基づいてコマンドを実行し、ソースコードのコンパイル、ライブラリのリンク、テストの実行などを行います。Go言語のプロジェクトでも、Goのビルドコマンドをラップしたり、追加のビルドステップ(コード生成など)を実行するために使用されることがあります。
  • CLEANFILES: Makefile において、make clean コマンドが実行された際に削除されるべきファイルやディレクトリを指定する変数です。通常、コンパイルによって生成されるオブジェクトファイルや実行可能ファイル、一時ファイルなどが含まれます。
  • goosgoarch: Go言語におけるビルドターゲットのオペレーティングシステム (OS) とアーキテクチャ (CPU) を指定するための環境変数です。例えば、GOOS=linux GOARCH=amd64 go build とすることで、Linux x86-64 用の実行可能ファイルをビルドできます。go/build パッケージは、これらの情報に基づいて、どのソースファイルを含めるか(ビルドタグなど)を決定します。

技術的詳細

このコミットの技術的な核心は、go/build パッケージが、Goのビルドシステムがサポートするオペレーティングシステム(goos)とアーキテクチャ(goarch)のリストをどのように管理するか、という点にあります。

変更前は、syslist.go というファイルが Makefile によって生成され、CLEANFILES に含まれていました。これは、syslist.go がビルド時に動的に生成される一時的なファイルであり、クリーンアップの対象となることを意味します。しかし、go/build パッケージがこれらのリストを内部的に必要とする場合、生成されたファイルに依存することは、ビルドプロセスの複雑性を増したり、自己参照的な問題を引き起こす可能性があります。

このコミットでは、以下の2つの変更が行われています。

  1. src/pkg/go/build/Makefile の変更: CLEANFILES から syslist.go が削除されました。これにより、syslist.go はもはや生成される一時ファイルではなく、Goのソースコードリポジトリに永続的に存在するファイルとして扱われるようになります。
  2. src/pkg/go/build/syslist.go の追加: syslist.go という新しいファイルが追加されました。このファイルには、Goがサポートするオペレーティングシステムのリスト (goosList) とアーキテクチャのリスト (goarchList) がGoの定数としてハードコードされています。
    // Generated automatically by make.
    package build
    
    const goosList = "darwin freebsd linux netbsd openbsd plan9 windows "
    const goarchList = "386 amd64 arm "
    
    コメントには「Generated automatically by make.」とありますが、これは以前の生成プロセスからの名残であるか、あるいは将来的にこのファイルが自動生成される可能性を示唆しているものの、このコミット時点では手動で追加されたソースファイルとして扱われることを意味します。

この変更により、go/build パッケージは、サポートされるOSとアーキテクチャのリストを、自身のソースコード内に直接持つことになります。これにより、go/build パッケージのビルドは、外部の生成プロセスに依存することなく、より自己完結的になります。これは、go/build パッケージがGoのビルドシステムの中核を担うことを考えると、非常に重要な変更です。自身のビルドに必要な情報が自身のコード内に存在することで、「go/build: make compatible with go/build」というコミットメッセージの「皮肉」が解消されたと言えます。

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

diff --git a/src/pkg/go/build/Makefile b/src/pkg/go/build/Makefile
index 349e00e801..1a18e00b88 100644
--- a/src/pkg/go/build/Makefile
+++ b/src/pkg/go/build/Makefile
@@ -11,7 +11,7 @@ GOFILES=\
 	path.go\
 	syslist.go\
 
-CLEANFILES+=syslist.go pkgtest/_obj cmdtest/_obj cgotest/_obj
+CLEANFILES+=pkgtest/_obj cmdtest/_obj cgotest/_obj
 
 include ../../../Make.pkg
 
diff --git a/src/pkg/go/build/syslist.go b/src/pkg/go/build/syslist.go
new file mode 100644
index 0000000000..0ee9821322
--- /dev/null
+++ b/src/pkg/go/build/syslist.go
@@ -0,0 +1,5 @@
+// Generated automatically by make.
+package build
+
+const goosList = "darwin freebsd linux netbsd openbsd plan9 windows "
+const goarchList = "386 amd64 arm "

コアとなるコードの解説

  1. src/pkg/go/build/Makefile の変更: CLEANFILES+=syslist.go pkgtest/_obj cmdtest/_obj cgotest/_obj の行から syslist.go が削除されました。 変更前は、syslist.go がビルド時に生成されるファイルとして扱われ、make clean 時に削除される対象でした。この変更により、syslist.go は生成物ではなく、リポジトリにコミットされる永続的なソースファイルとして扱われるようになります。これは、go/build パッケージが自身のビルドに必要な情報を、外部の生成プロセスに依存せず、自身のコードベース内に持つという設計思想への転換を示しています。

  2. src/pkg/go/build/syslist.go の新規追加: このファイルは、GoのビルドシステムがサポートするオペレーティングシステムとアーキテクチャのリストをGoの定数として定義しています。

    • package build: このファイルが build パッケージの一部であることを示します。
    • const goosList = "darwin freebsd linux netbsd openbsd plan9 windows ": GoがサポートするOSのリストをスペース区切りの文字列として定義しています。これには、macOS (darwin), FreeBSD, Linux, NetBSD, OpenBSD, Plan 9, Windows が含まれます。
    • const goarchList = "386 amd64 arm ": GoがサポートするCPUアーキテクチャのリストをスペース区切りの文字列として定義しています。これには、x86 (386), x86-64 (amd64), ARM が含まれます。

    これらの定数は、go/build パッケージの内部で、Goのソースファイルを解析する際や、特定の環境向けのビルド情報を決定する際に利用されると考えられます。例えば、go/build パッケージは、これらのリストを参照して、特定のビルドタグ(例: // +build linux)が有効かどうかを判断したり、クロスコンパイルのターゲットを検証したりするのに役立ちます。

関連リンク

  • Go言語の公式ドキュメント: https://go.dev/doc/
  • go/build パッケージのドキュメント: https://pkg.go.dev/go/build (このコミット時点ではGoのバージョンが古いため、現在のドキュメントとは異なる可能性がありますが、パッケージの基本的な役割は理解できます)

参考にした情報源リンク