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

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

このコミットは、Go言語のツールチェインにおけるMakefileの変更に関するものです。具体的には、bisonコマンドの実行時に-dオプションを追加することで、y.tab.hファイルの生成を確実にする修正が行われています。この変更は、src/cmd/5a/Makefilesrc/cmd/6a/Makefilesrc/cmd/8a/Makefilesrc/cmd/cc/Makefileの4つのファイルにわたって適用されています。

コミット

commit 30537789651be3e523bbdb4503f48a3b5b6ac48f
Author: Adam Langley <agl@golang.org>
Date:   Tue Feb 21 10:50:58 2012 -0500

    cmd/*: add -d option to bison.
    
    Without -d, bison doesn't generate y.tab.h.
    
    R=rsc
    CC=golang-dev
    https://golang.org/cl/5685065

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

https://github.com/golang/go/commit/30537789651be3e523bbdb4503f48a3b5b6ac48f

元コミット内容

cmd/*: add -d option to bison. Without -d, bison doesn't generate y.tab.h.

このコミットメッセージは、cmdディレクトリ以下の各ツール(アセンブラやコンパイラなど)のビルドプロセスにおいて、bisonコマンドに-dオプションを追加したことを示しています。その理由として、-dオプションがないとy.tab.hファイルが生成されないため、と明記されています。

変更の背景

この変更の背景には、Go言語のツールチェインのビルドプロセスにおける依存関係の問題があります。Go言語のコンパイラやアセンブラなどのツールは、字句解析器(lexer)や構文解析器(parser)を生成するためにlex(またはflex)やyacc(またはbison)といったツールを使用しています。

bisonは、文法定義ファイル(通常.y拡張子を持つ)からC言語の構文解析器を生成するツールです。この構文解析器は、通常y.tab.c(またはy.tab.cpp)というファイルに生成されます。しかし、構文解析器が使用するトークン定義や外部から参照される関数プロトタイプなどは、ヘッダーファイルに定義される必要があります。このヘッダーファイルがy.tab.hです。

コミットメッセージにある「Without -d, bison doesn't generate y.tab.h.」という記述から、当時のbisonのバージョンや設定において、デフォルトではy.tab.hが生成されなかったことが示唆されます。y.tab.hが生成されないと、そのヘッダーファイルをインクルードしている他のソースコードがコンパイルエラーになるため、ビルドプロセスが中断してしまいます。

このコミットは、ビルドの安定性と正確性を確保するために、明示的にy.tab.hを生成させる必要があったという背景があります。

前提知識の解説

Bison (GNU Bison)

Bisonは、GNUプロジェクトによって開発されたパーサジェネレータ(構文解析器生成器)です。Yacc(Yet Another Compiler Compiler)と互換性があり、文法規則を記述したファイル(通常.yまたは.yy拡張子)を読み込み、その文法に従って入力ストリームを解析するC、C++、Javaなどのプログラムコードを生成します。コンパイラやインタプリタの構文解析部分を自動生成する際に広く利用されます。

y.tab.h

y.tab.hは、Bisonが生成するヘッダーファイルです。このファイルには、主に以下の情報が含まれます。

  • トークン定義: Bisonの文法定義ファイルで定義された各トークン(終端記号)に対応する整数値のマクロ定義(例: #define IDENTIFIER 257)。これらの定義は、字句解析器(lexflexで生成される)が構文解析器にトークンを渡す際に使用されます。
  • 外部宣言: 構文解析器が使用する外部関数(例: yyparse(), yylex(), yyerror()) や外部変数(例: yylval)のプロトタイプ宣言やextern宣言。
  • 型定義: Bisonのセマンティックアクションで使用される共用体(YYSTYPE)の定義など。

このヘッダーファイルは、通常、字句解析器のソースファイルや、構文解析器の生成されたコードを使用する他のソースファイルによってインクルードされます。

bison -d オプション

bisonコマンドの-dオプションは、--definesの短縮形です。このオプションを指定すると、Bisonは生成されたパーサのソースファイル(例: y.tab.c)に加えて、対応するヘッダーファイル(デフォルトではy.tab.h)を生成します。このヘッダーファイルには、前述のトークン定義や外部宣言などが含まれます。

-dオプションがない場合、Bisonは通常、パーサのソースファイルのみを生成し、ヘッダーファイルは生成しません。これは、パーサが単独でコンパイルされる場合や、トークン定義などが別の方法で提供される場合には問題ありませんが、Go言語のツールチェインのように、複数のコンポーネントが連携して動作し、トークン定義を共有する必要がある場合には必須となります。

Makefile

Makefileは、makeユーティリティがプログラムのコンパイルやビルドプロセスを自動化するために使用するファイルです。依存関係とそれらを解決するためのコマンドを記述します。このコミットでは、Makefile内のbisonコマンドの呼び出し部分が修正されています。

技術的詳細

このコミットの技術的な詳細は、bisonのビルドプロセスにおけるヘッダーファイルの依存関係に集約されます。

Go言語のツールチェインでは、アセンブラ(5a, 6a, 8a)やCコンパイラ(cc)のフロントエンドが、それぞれ独自の文法定義ファイル(例: a.ycc.y)を持っています。これらの.yファイルはbisonによって処理され、構文解析器のCソースファイルとヘッダーファイルが生成されます。

変更前のMakefileでは、bisonコマンドはLANG=C LANGUAGE=en_US.UTF8 bison -v -y a.yのように実行されていました。ここで、

  • LANG=C LANGUAGE=en_US.UTF8: bisonの実行環境のロケールを設定しています。これは、bisonが生成するコードやメッセージの言語に影響を与えます。
  • -v: 詳細な情報を出力します。
  • -y: y.tab.cy.tab.hというデフォルトのファイル名を使用するように指定します(これは古いyaccの挙動に合わせるためのオプションで、現代のbisonでは通常不要ですが、互換性のために残されていることがあります)。
  • a.yまたはcc.y: 入力となる文法定義ファイルです。

このコマンドラインには-dオプションが含まれていませんでした。その結果、bisony.tab.c(またはcc.tab.c)は生成するものの、対応するy.tab.h(またはcc.tab.h)を生成していませんでした。

しかし、Makefileのターゲット定義を見ると、install: y.tab.hという行があります。これは、installターゲットがy.tab.hに依存していることを示しています。つまり、y.tab.hが存在しないとinstallターゲットが実行できないか、あるいはy.tab.hの生成ルールが正しく機能しない場合にビルドが失敗する可能性がありました。

このコミットでは、bisonコマンドに-dオプションを追加することで、この問題を解決しています。LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.yのように変更することで、bisonは明示的にy.tab.hファイルを生成するようになります。これにより、ビルドプロセスがy.tab.hを必要とする他のステップに進むことができるようになり、ビルドの整合性が保たれます。

この修正は、Go言語のツールチェインがクロスコンパイル環境や異なるOS環境でビルドされる際に、bisonのバージョンやデフォルト設定の違いによって発生する可能性のあるビルドエラーを防ぐ上で重要です。

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

変更は、Go言語のツールチェインを構成するアセンブラ(5a, 6a, 8a)とCコンパイラ(cc)のMakefileファイルに集中しています。具体的には、y.tab.hを生成するルール内のbisonコマンドの呼び出し部分です。

diff --git a/src/cmd/5a/Makefile b/src/cmd/5a/Makefile
index 538ffb1a76..27290ddd71 100644
--- a/src/cmd/5a/Makefile
+++ b/src/cmd/5a/Makefile
@@ -7,4 +7,4 @@ include ../../Make.dist
 install: y.tab.h
 
 y.tab.h: a.y
-	LANG=C LANGUAGE=en_US.UTF8 bison -v -y a.y
+	LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
diff --git a/src/cmd/6a/Makefile b/src/cmd/6a/Makefile
index 538ffb1a76..27290ddd71 100644
--- a/src/cmd/6a/Makefile
+++ b/src/cmd/6a/Makefile
@@ -7,4 +7,4 @@ include ../../Make.dist
 install: y.tab.h
 
 y.tab.h: a.y
-	LANG=C LANGUAGE=en_US.UTF8 bison -v -y a.y
+	LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
diff --git a/src/cmd/8a/Makefile b/src/cmd/8a/Makefile
index 538ffb1a76..27290ddd71 100644
--- a/src/cmd/8a/Makefile
+++ b/src/cmd/8a/Makefile
@@ -7,4 +7,4 @@ include ../../Make.dist
 install: y.tab.h
 
 y.tab.h: a.y
-	LANG=C LANGUAGE=en_US.UTF8 bison -v -y a.y
+	LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
diff --git a/src/cmd/cc/Makefile b/src/cmd/cc/Makefile
index 8cfd64cd66..109578297b 100644
--- a/src/cmd/cc/Makefile
+++ b/src/cmd/cc/Makefile
@@ -7,4 +7,4 @@ include ../../Make.dist
 install: y.tab.h
 
 y.tab.h: cc.y
-	LANG=C LANGUAGE=en_US.UTF8 bison -v -y a.y
+	LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y

Makefileにおいて、y.tab.h(またはcc.yの場合はcc.tab.hに相当)を生成するルール内で、bisonコマンドの引数に-dが追加されています。

コアとなるコードの解説

Makefileの変更は非常にシンプルで、bisonコマンドの呼び出しに-dオプションを追加するだけです。

例えば、src/cmd/5a/Makefileの該当箇所は以下のようになっています。

変更前:

y.tab.h: a.y
	LANG=C LANGUAGE=en_US.UTF8 bison -v -y a.y

変更後:

y.tab.h: a.y
	LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y

この変更により、makey.tab.hターゲットをビルドする際に、bisonコマンドが実行され、a.y(またはcc.y)から構文解析器のソースファイル(y.tab.cなど)だけでなく、対応するヘッダーファイルy.tab.hも確実に生成されるようになります。

この修正は、Go言語のビルドシステムがbisonによって生成されるヘッダーファイルに依存していることを明確にし、その依存関係を正しく満たすためのものです。これにより、ビルドの信頼性が向上し、異なる環境でのビルド失敗のリスクが低減されます。

関連リンク

  • Go言語の公式リポジトリ: https://github.com/golang/go
  • このコミットのChange-ID: https://golang.org/cl/5685065 (GoのコードレビューシステムGerritのリンク)

参考にした情報源リンク