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

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

このコミットは、Go言語のビルドシステムの一部である src/pkg/go/build/Makefile に変更を加え、生成される syslist.go ファイルが gofmt の規約に沿うように修正するものです。具体的には、syslist.go の内容を生成する際に、定数定義の前に空行を挿入することで、gofmt がその空行を削除しないように調整しています。

コミット

go/build: make sure syslist.go is gofmted

R=golang-dev, mikioh.mikioh
CC=golang-dev
https://golang.org/cl/5490051

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

https://github.com/golang/go/commit/8fa8ebf834d2027cc598d68f46e0855b94ad63a1

元コミット内容

commit 8fa8ebf834d2027cc598d68f46e0855b94ad63a1
Author: Alex Brainman <alex.brainman@gmail.com>
Date:   Fri Dec 16 15:52:30 2011 +1100

    go/build: make sure syslist.go is gofmted
    
    R=golang-dev, mikioh.mikioh
    CC=golang-dev
    https://golang.org/cl/5490051
---
 src/pkg/go/build/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/pkg/go/build/Makefile b/src/pkg/go/build/Makefile
index 1a18e00b88..68c731749a 100644
--- a/src/pkg/go/build/Makefile
+++ b/src/pkg/go/build/Makefile
@@ -18,5 +18,6 @@ include ../../../Make.pkg
 syslist.go: ../../../Make.inc Makefile
  	echo '// Generated automatically by make.' >$@
  	echo 'package build' >>$@
+	echo >>$@
  	echo 'const goosList = "$(GOOS_LIST)"' >>$@
  	echo 'const goarchList = "$(GOARCH_LIST)"' >>$@

変更の背景

Go言語のプロジェクトでは、コードの整形と一貫性を保つために gofmt というツールが広く利用されています。gofmt はGoのソースコードを標準的なスタイルに自動的に整形するツールであり、Goコミュニティでは gofmt によって整形されたコードが「正しい」コードと見なされることが一般的です。

このコミットの背景には、src/pkg/go/build パッケージ内で Makefile によって自動生成される syslist.go ファイルが、gofmt の整形ルールに完全に準拠していなかったという問題がありました。特に、gofmt はファイルの末尾や特定のコードブロックの後に不要な空行を削除する傾向があります。この場合、syslist.go 内で package build の宣言とそれに続く const 定義の間に空行がないと、gofmt が整形時に特定の挙動を示す可能性がありました。

このコミットは、syslist.go が生成された直後に gofmt を適用しても、意図しない変更(特に空行の削除)が発生しないように、生成プロセス自体を調整することを目的としています。これにより、ビルドプロセス全体でのコードの一貫性が保たれ、開発者が gofmt を実行した際に予期せぬ差分が発生するのを防ぎます。

前提知識の解説

このコミットを理解するためには、以下の技術的知識が役立ちます。

  • gofmt: Go言語の公式なコード整形ツールです。Goのソースコードを自動的に標準的なスタイルに整形します。インデント、スペース、改行などを統一し、コードの可読性と一貫性を高めます。gofmt は、Goのコードベース全体で一貫したスタイルを強制するために非常に重要です。特に、gofmt はファイルの末尾や特定のコードブロックの後に余分な空行を削除する傾向があります。
  • Makefile: make ユーティリティが使用するビルド自動化スクリプトです。依存関係に基づいてコマンドを実行し、ソースコードのコンパイル、ファイルの生成、テストの実行など、プロジェクトのビルドプロセスを自動化します。このコミットでは、Makefilesyslist.go ファイルを生成する役割を担っています。
  • go/build パッケージ: Go言語の標準ライブラリの一部で、Goのビルドプロセスに関する情報を提供します。例えば、GoのソースファイルがどのOSやアーキテクチャでビルドされるべきか、どのタグが有効かなどを判断するために使用されます。syslist.go はこのパッケージの一部として、サポートされているOS (GOOS) とアーキテクチャ (GOARCH) のリストを内部的に保持するために使用されます。
  • syslist.go: go/build パッケージ内で使用される、サポートされているオペレーティングシステム (GOOS) とアーキテクチャ (GOARCH) のリストを定義するGoのソースファイルです。このファイルは通常、Makefile によって自動的に生成されます。
  • GOOS_LISTGOARCH_LIST: Goのビルドシステムで使用される環境変数で、それぞれサポートされているOSとアーキテクチャのリストをカンマ区切りで保持しています。syslist.go はこれらの変数の値を使って定数を生成します。
  • シェルスクリプトの echo コマンドとリダイレクト (>>>):
    • echo 'text' > file: file を作成(または既存のものを上書き)し、text を書き込みます。
    • echo 'text' >> file: file の末尾に text を追記します。
    • echo >> file: file の末尾に空行(改行文字のみ)を追記します。

技術的詳細

このコミットの技術的な核心は、gofmt の挙動を理解し、それに対応する形で Makefile のファイル生成ロジックを調整している点にあります。

gofmt は、Goのソースコードを整形する際に、特定のコンテキストで不要と判断される空行を削除することがあります。特に、package 宣言の直後に constvar 宣言が続く場合、gofmt はその間に空行がないことを好む場合があります。しかし、このケースでは、package build の後に続く const goosListconst goarchList の間に空行がないと、gofmt が何らかの理由で整形後の出力に問題を生じさせる可能性があったと考えられます。

コミットが追加した echo >>$@ コマンドは、syslist.go ファイルを生成する際に、package build の行の直後に意図的に空行を挿入します。

syslist.go: ../../../Make.inc Makefile
 	echo '// Generated automatically by make.' >$@
 	echo 'package build' >>$@
+	echo >>$@  # ここで空行を挿入
 	echo 'const goosList = "$(GOOS_LIST)"' >>$@
 	echo 'const goarchList = "$(GOARCH_LIST)"' >>$@

この空行の挿入により、syslist.gogofmt にかけられた際に、gofmt がこの空行を「必要なもの」として認識し、削除しないようになります。結果として、syslist.gogofmt によって整形されても、その内容が安定し、ビルドプロセスの一貫性が保たれるようになります。これは、自動生成されるコードであっても、プロジェクト全体のコードスタイル規約に準拠させるための細かな調整の一例です。

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

変更は src/pkg/go/build/Makefile ファイルの1箇所のみです。

--- a/src/pkg/go/build/Makefile
+++ b/src/pkg/go/build/Makefile
@@ -18,5 +18,6 @@ include ../../../Make.pkg
 syslist.go: ../../../Make.inc Makefile
  	echo '// Generated automatically by make.' >$@
  	echo 'package build' >>$@
+	echo >>$@
  	echo 'const goosList = "$(GOOS_LIST)"' >>$@
  	echo 'const goarchList = "$(GOARCH_LIST)"' >>$@

具体的には、syslist.go を生成するターゲットのルール内で、echo 'package build' >>$@ の行の直後に echo >>$@ が追加されています。

コアとなるコードの解説

追加された echo >>$@ コマンドは、Makefile の中で syslist.go ファイルを生成する際に実行されます。

  • $@Makefile の自動変数で、現在のターゲット名、この場合は syslist.go を指します。
  • echo コマンドは、引数なしで実行されると、単に改行を出力します。
  • >> はリダイレクト演算子で、コマンドの出力を指定されたファイルの末尾に追記します。

したがって、echo >>$@ は「syslist.go ファイルの末尾に空行(改行文字のみ)を追記する」という動作をします。

この変更が適用される前の syslist.go の生成ロジックでは、package build の行の直後に const goosList の行が続いていました。

// Generated automatically by make.
package build
const goosList = "..."
const goarchList = "..."

この状態のファイルが gofmt にかけられると、gofmt の内部的な整形ルールによっては、package 宣言と const 宣言の間の改行の有無が問題となる可能性がありました。

変更後、echo >>$@ が追加されたことで、生成される syslist.go は以下のようになります。

// Generated automatically by make.
package build

const goosList = "..."
const goarchList = "..."

このように package buildconst 宣言の間に明示的に空行が挿入されることで、gofmt がこのファイルを整形する際に、この空行を「意図されたもの」として認識し、削除せずに保持するようになります。これにより、syslist.gogofmt によって整形されても、その内容が安定し、ビルドプロセスにおけるコードの一貫性が確保されます。

関連リンク

参考にした情報源リンク

  • gofmt の挙動に関する一般的な情報 (Go言語の公式ドキュメントやコミュニティの議論)
  • Makefile の基本的な構文とシェルコマンドのリダイレクトに関する情報