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

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

このコミットは、Go言語のコンパイラツールチェーンの一部である cc (Cコンパイラ) と gc (Goコンパイラ) のビルドプロセスにおいて、構文解析器ジェネレータを yacc から bison へと明示的に切り替える変更を加えています。これにより、特定の環境下でのビルド問題を回避し、より安定したビルドを保証することを目的としています。

コミット

commit 859ba57bbb58e685da1e82b91935c55f26dc85de
Author: Russ Cox <rsc@golang.org>
Date:   Tue Jan 6 09:53:30 2009 -0800

    make acid build with bison.
    ask for bison explicitly in cc, gc to try to
    avoid problems with other yaccs that
    might be installed.
    
    R=r
    DELTA=29  (10 added, 2 deleted, 17 changed)
    OCL=22110
    CL=22113

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

https://github.com/golang/go/commit/859ba57bbb58e685da1e82b91935c55f26dc85de

元コミット内容

make acid build with bison.
ask for bison explicitly in cc, gc to try to
avoid problems with other yaccs that
might be installed.

変更の背景

このコミットの背景には、Go言語の初期開発段階におけるビルド環境の多様性と、それに伴う依存ツールの互換性の問題があります。yacc (Yet Another Compiler Compiler) は、BNF (Backus-Naur Form) 形式の文法定義からC言語の構文解析器(パーサ)を生成するツールとして広く使われていました。しかし、yaccには様々な実装(例えば、AT&T yacc、Berkeley yacc、GNU Bisonなど)が存在し、それぞれに微妙な違いや拡張機能がありました。

Go言語のコンパイラ(ccgc)は、その構文解析部分でyaccによって生成されたコードを利用していました。しかし、ユーザーのシステムにインストールされているyaccの実装によっては、ビルドが失敗したり、予期せぬ動作を引き起こしたりする可能性がありました。特に、acidという特定のビルド環境や設定において、この問題が顕在化したと考えられます。

この問題を解決するため、開発チームは、より標準的で機能豊富なbison(GNU Project Parser Generator)を明示的に使用するようにビルドスクリプトを変更することを決定しました。bisonyaccと互換性がありながらも、より多くの機能と改善を提供しており、広く利用されています。bisonを明示的に指定することで、システムにインストールされている他のyacc実装による潜在的な問題を回避し、ビルドの安定性と再現性を向上させることが狙いです。

前提知識の解説

構文解析器ジェネレータ (Parser Generator)

構文解析器ジェネレータは、プログラミング言語のコンパイラやインタプリタを開発する際に非常に重要なツールです。これらは、言語の文法規則(通常はBNFやEBNF形式で記述される)を入力として受け取り、その文法に従って入力されたソースコードを解析するためのプログラム(構文解析器、またはパーサ)を自動的に生成します。

Yacc (Yet Another Compiler Compiler)

yaccは、Unix系システムで広く使われてきた構文解析器ジェネレータの古典的なツールです。LALR(1)パーサを生成し、文法規則とそれに対応するアクション(通常はC言語のコード)を記述したファイル(.y拡張子を持つ)を処理して、C言語のソースファイル(y.tab.c)とヘッダファイル(y.tab.h)を出力します。生成されたパーサは、字句解析器(通常はlexまたはflexで生成される)と連携して動作し、入力ストリームをトークンに分割し、そのトークン列が文法規則に合致するかどうかを検証します。

Bison (GNU Project Parser Generator)

bisonは、GNUプロジェクトによって開発されたyaccのフリーな実装であり、上位互換性を持っています。yaccの機能をすべて含みつつ、エラー回復機能の改善、より強力な文法定義機能、国際化対応など、多くの拡張と改善が加えられています。bisonも同様に、文法定義ファイルからC、C++、Javaなどの言語で書かれたパーサを生成できます。bison -yオプションは、yaccとの互換性モードで動作させ、y.tab.cy.tab.hといったyaccが生成するファイル名で出力するように指示します。

Makefile

Makefileは、ソフトウェアプロジェクトのビルドプロセスを自動化するためのスクリプトファイルです。makeユーティリティによって解釈され、ソースコードのコンパイル、リンク、テスト、インストールなどのタスクを定義します。Makefileは、ファイルの依存関係を記述することで、変更されたファイルのみを再ビルドするなど、効率的なビルドを実現します。このコミットでは、Makefile内のyaccコマンドの呼び出しをbisonコマンドに置き換えることで、構文解析器の生成方法を変更しています。

技術的詳細

このコミットの主要な変更は、Goコンパイラ(gc)とCコンパイラ(cc)のビルドプロセスを定義するMakefileにあります。具体的には、y.tab.hy.tab.cという構文解析器関連のファイルを生成するルールが変更されています。

変更前は、これらのファイルは汎用的なyaccコマンドを使用して生成されていました。

y.tab.h: $(YFILES)
	yacc $(YFLAGS) $(YFILES)

この記述では、システムにインストールされているyaccコマンドが何であるか(例えば、AT&T yacc、Berkeley yacc、またはGNU Bisonのいずれか)は明示されていません。そのため、異なる環境でビルドする際に、yaccの実装の違いによって問題が発生する可能性がありました。

このコミットでは、この行を以下のように変更しています。

y.tab.h: $(YFILES)
	bison -y $(YFLAGS) $(YFILES)

この変更により、以下の点が明確になります。

  1. bisonの明示的な使用: yaccの代わりにbisonコマンドを直接呼び出すことで、構文解析器の生成にGNU Bisonを使用することが保証されます。これにより、他のyacc実装がシステムに存在しても、それらがビルドプロセスに影響を与えることを防ぎます。
  2. -yオプション: bison-yオプションは、yaccとの互換性モードを有効にします。これにより、bisonが生成する出力ファイルの名前がy.tab.cy.tab.hとなり、既存のビルドシステムがこれらのファイル名を期待している場合に互換性を保つことができます。これは、yaccからbisonへの移行をスムーズに行うための一般的なプラクティスです。
  3. compat.hcompat.$Oの削除: src/cmd/cc/Makefileからは、compat.hcompat.$O(オブジェクトファイル)への参照が削除されています。これは、bisonを使用することで、以前のyacc実装との互換性を保つために必要だった特定の互換性レイヤーやファイルが不要になったことを示唆しています。bisonが提供する機能や生成されるコードが、Goコンパイラの要件を直接満たすようになったため、これらの互換性ファイルが冗長になったと考えられます。

これらの変更は、Goコンパイラのビルドプロセスをより堅牢にし、異なる開発環境間での一貫性を高めることに貢献しています。

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

このコミットでは、以下の2つのMakefileファイルが変更されています。

  1. src/cmd/cc/Makefile
  2. src/cmd/gc/Makefile

それぞれのファイルで、y.tab.hの生成ルールが変更されています。

src/cmd/cc/Makefile の変更

--- a/src/cmd/cc/Makefile
+++ b/src/cmd/cc/Makefile
@@ -10,7 +10,6 @@ LIB=\
 HFILES=\
 	cc.h\
 	y.tab.h\
-	compat.h\
 
 YFILES=\
 	cc.y\
@@ -28,10 +27,8 @@ OFILES=\
 	funct.$O\
 	sub.$O\
 	com64.$O\
-\tcompat.$O\
 	dpchk.$O\
 	omachcap.$O\
-\tcompat.$O\
 
 $(LIB): $(OFILES)
 	ar rsc $(LIB) $(OFILES)
@@ -39,7 +36,7 @@ $(LIB): $(OFILES)
 $(OFILES): $(HFILES)
 
 y.tab.h: $(YFILES)
-\tyacc $(YFLAGS) $(YFILES)
+\tbison -y $(YFLAGS) $(YFILES)
 
 y.tab.c: y.tab.h
 	test -f y.tab.c && touch y.tab.c

src/cmd/gc/Makefile の変更

--- a/src/cmd/gc/Makefile
+++ b/src/cmd/gc/Makefile
@@ -34,7 +34,7 @@ $(LIB): $(OFILES)
 $(OFILES): $(HFILES)
 
 y.tab.h: $(YFILES)
-\tyacc $(YFLAGS) $(YFILES)
+\tbison -y $(YFLAGS) $(YFILES)
 
 y.tab.c: y.tab.h
 	test -f y.tab.c && touch y.tab.c

コアとなるコードの解説

上記の変更箇所は、Go言語のコンパイラ(gc)とCコンパイラ(cc)のビルドシステムにおいて、構文解析器のヘッダファイル(y.tab.h)を生成するコマンドをyaccからbison -yに切り替えていることを示しています。

  • src/cmd/cc/Makefile:

    • HFILESからcompat.hが削除されました。これは、bisonの使用により、以前のyacc実装との互換性レイヤーが不要になったためと考えられます。
    • OFILESからcompat.$Oが2箇所で削除されました。これもcompat.hの削除と同様の理由で、互換性関連のオブジェクトファイルが不要になったことを示します。
    • y.tab.hの生成ルールが、yacc $(YFLAGS) $(YFILES)からbison -y $(YFLAGS) $(YFILES)に変更されました。これにより、Cコンパイラの構文解析器は明示的にbisonによって生成されるようになります。
  • src/cmd/gc/Makefile:

    • y.tab.hの生成ルールが、yacc $(YFLAGS) $(YFILES)からbison -y $(YFLAGS) $(YFILES)に変更されました。これにより、Goコンパイラの構文解析器も明示的にbisonによって生成されるようになります。

これらの変更は、Goコンパイラのビルドプロセスにおける外部ツールの依存関係をより厳密に管理し、異なる環境でのビルドの信頼性を向上させるための重要なステップです。bison-yオプションは、yaccとの互換性を保ちつつ、bisonのより優れた機能を利用するための鍵となります。

関連リンク

参考にした情報源リンク