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

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

このコミットは、Go言語のビルドシステムに関連する変更であり、具体的には以下の4つのファイルから不要な#pragmaディレクティブを削除しています。

  • include/plan9/libc.h
  • include/plan9/mach.h
  • src/cmd/cc/cc.h
  • src/cmd/gc/go.h

コミット

このコミットは、Go言語のビルドプロセスにおいて、もはや不要となった#pragma srcおよび#pragma libディレクティブを削除することを目的としています。これにより、ビルドシステムの冗長性が排除され、コードベースのクリーンアップが図られています。

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

https://github.com/golang/go/commit/7ac03695f861fcb46df3d06d53230b89c7811859

元コミット内容

build: remove unnecessary pragmas

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5629055

変更の背景

この変更の背景には、Go言語のビルドシステム、特に初期のGoコンパイラ(gc)とCコンパイラ(cc)が採用していたPlan 9由来のツールチェインの進化があります。

初期のGo言語は、Plan 9オペレーティングシステムの影響を強く受けており、そのビルドツールやライブラリの参照方法もPlan 9の慣習に従っていました。#pragma src#pragma libといったディレクティブは、Plan 9のCコンパイラ(8c, 6c, 5cなど)がソースファイルやライブラリファイルを探索するためのパスを指定するために使用されていました。

しかし、Go言語のビルドシステムが成熟し、Go独自のモジュール解決メカニズムや、go buildコマンドのような統合されたツールチェインが確立されるにつれて、これらの明示的な#pragmaディレクティブは冗長となっていきました。コンパイラやリンカが、環境変数(GOROOTなど)やGoモジュールのパス解決ルールに基づいて必要なファイルを見つけられるようになったため、ヘッダーファイル内でこれらのパスをハードコードする必要がなくなったのです。

このコミットは、このようなビルドシステムの進化に伴い、もはや機能的に意味を持たなくなった、あるいはより現代的なGoのビルドプロセスと競合する可能性のある古いディレクティブを削除し、コードベースを整理することを目的としています。これにより、ビルド設定の簡素化と、将来的なメンテナンス性の向上が期待されます。

前提知識の解説

Plan 9とGo言語

Go言語は、Googleで開発されたプログラミング言語ですが、その設計思想や初期のツールチェインには、ベル研究所で開発されたオペレーティングシステム「Plan 9 from Bell Labs」の影響が色濃く見られます。特に、Goのコンパイラ(gc)やアセンブラ(go tool asm)、リンカ(go tool link)といったツールは、Plan 9のCコンパイラ(8c, 6c, 5c)、アセンブラ(8a, 6a, 5a)、リンカ(8l, 6l, 5l)の設計を継承しています。

#pragma ディレクティブ

C言語やC++において、#pragmaディレクティブは、コンパイラに対して特定の情報や指示を与えるための非標準的なプリプロセッサディレクティブです。コンパイラの実装に依存するため、移植性はありませんが、特定のコンパイラや環境に特化した機能を提供するために使用されます。

Plan 9のCコンパイラには、特に以下の2つの#pragmaが特徴的でした。

  1. #pragma src "path": このディレクティブは、コンパイラに対して、指定されたパスがソースファイルの検索パスの一部であることを示します。具体的には、#includeディレクティブで指定されたヘッダーファイルや、コンパイル時に参照される可能性のあるソースファイルを探す際に、このパスが考慮されるようになります。これは、特定のライブラリやモジュールのソースコードが標準的なインクルードパスにない場合に、コンパイラにその場所を教えるために使われました。

  2. #pragma lib "path": このディレクティブは、コンパイラに対して、指定されたパスがライブラリファイルの検索パスの一部であることを示します。リンカが関数や変数の定義を解決するために必要なアーカイブライブラリ(.aファイルなど)を探す際に、このパスが使用されます。例えば、#pragma lib "/sys/src/go/lib/$M/lib9.a"は、lib9.aというライブラリが指定されたパスに存在することを示し、リンカがそのライブラリをリンク対象として考慮するように指示します。$Mは、ターゲットアーキテクチャ(例: amd64, 386)を示す変数で、ビルド時に適切な値に展開されます。

これらの#pragmaは、Plan 9のモジュール化されたファイルシステムと、それに合わせたビルドプロセスの設計思想を反映したものでした。

技術的詳細

このコミットで削除された#pragmaディレクティブは、Go言語の初期のビルドシステムにおいて、Plan 9のCコンパイラがGoの標準ライブラリやツールチェインの内部コンポーネントをビルドする際に、ソースファイルやライブラリファイルの場所を明示的に指定するために使用されていました。

具体的に削除された行は以下の通りです。

  • include/plan9/libc.h:

    #pragma src "/sys/src/go/src/lib9"
    #pragma lib "/sys/src/go/lib/$M/lib9.a"
    

    これは、Plan 9のCライブラリ(lib9)のソースとライブラリのパスを指定していました。

  • include/plan9/mach.h:

    #pragma src "/sys/src/go/src/libmach"
    #pragma lib "/sys/src/go/lib/$M/libmach.a"
    

    これは、Plan 9の機械語関連のライブラリ(libmach)のソースとライブラリのパスを指定していました。

  • src/cmd/cc/cc.h:

    #pragma lib "../cc/cc.a$O"
    

    これは、GoのCコンパイラ(cc)自身の内部ライブラリのパスを指定していました。$Oはオブジェクトファイルの拡張子(例: .5, .6, .8)を示す変数です。

  • src/cmd/gc/go.h:

    #pragma lib "../gc/gc.a$O"
    

    これは、Goのコンパイラ(gc)自身の内部ライブラリのパスを指定していました。

これらの#pragmaが不要になった主な理由は、Go言語のビルドシステムがより洗練され、自己完結的になったためです。

  1. GOROOTGOPATHの導入と成熟: Go 1のリリース(2012年3月)に向けて、GOROOT(Goのインストールディレクトリ)とGOPATH(ユーザーのワークスペース)という概念が確立され、Goのツールチェインはこれらの環境変数に基づいてソースファイルやパッケージを自動的に探索するようになりました。これにより、ヘッダーファイル内で特定のパスをハードコードする必要がなくなりました。

  2. Goツールチェインの統合: go buildコマンドのような統合されたビルドツールが、コンパイル、アセンブル、リンクの各ステップを内部的に管理し、必要な依存関係を自動的に解決するようになりました。これにより、個々のコンパイラやリンカに明示的なパス指示を与える必要がなくなりました。

  3. 内部ビルドプロセスの変更: Goのコンパイラやツールチェイン自体のビルドプロセスが進化し、これらの#pragmaが提供していた情報が、別のより効率的な方法(例えば、ビルドスクリプトやMakefile、あるいはコンパイラ自身の内部ロジック)で処理されるようになったと考えられます。特に、Goのコンソースコードは、Goのビルドシステムによって管理されるようになり、Plan 9のCコンパイラが直接これらのヘッダーファイルを解釈してパスを解決する必要がなくなった可能性があります。

この変更は、GoのビルドシステムがPlan 9の遺産から脱却し、よりGoらしい、独立したビルドメカニズムへと移行する過程の一部を示しています。これにより、ビルド設定が簡素化され、将来的なGoのバージョンアップや異なるプラットフォームへの対応が容易になります。

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

include/plan9/libc.h

--- a/include/plan9/libc.h
+++ b/include/plan9/libc.h
@@ -10,9 +10,6 @@ enum
 	Runemax = 0x10FFFF, /* maximum rune value */
 };
 
-#pragma src "/sys/src/go/src/lib9"
-#pragma lib "/sys/src/go/lib/$M/lib9.a"
-
 char*	getgoos(void);
 char*\tgetgoarch(void);
 char*\tgetgoroot(void);

include/plan9/mach.h

--- a/include/plan9/mach.h
+++ b/include/plan9/mach.h
@@ -2,6 +2,4 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-#pragma src "/sys/src/go/src/libmach"
-#pragma lib "/sys/src/go/lib/$M/libmach.a"
 #include "../mach.h"

src/cmd/cc/cc.h

--- a/src/cmd/cc/cc.h
+++ b/src/cmd/cc/cc.h
@@ -31,8 +31,6 @@
 #include <libc.h>
 #include <bio.h>
 
-#pragma	lib	"../cc/cc.a$O"
-
 #ifndef	EXTERN
 #define EXTERN	extern
 #endif

src/cmd/gc/go.h

--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -4,8 +4,6 @@
 
 #include	<bio.h>
 
-#pragma	lib	"../gc/gc.a$O"
-
 #undef OAPPEND
 
 // avoid <ctype.h>

コアとなるコードの解説

削除された各#pragma行は、前述の「前提知識の解説」で説明した通り、Plan 9のCコンパイラに対して、ソースファイルやライブラリファイルの検索パスを指示するものでした。

  • include/plan9/libc.hinclude/plan9/mach.hからの削除: これらのファイルは、Goの標準ライブラリの一部として、Plan 9のCライブラリや機械語関連のライブラリのヘッダーを提供していました。#pragma src#pragma libは、これらのライブラリのソースとコンパイル済みバイナリの場所をコンパイラに伝えていました。これらの削除は、Goのビルドシステムがこれらのライブラリを、GOROOTなどの環境変数やGoのパッケージ解決メカニズムを通じて、より自動的に見つけられるようになったことを意味します。

  • src/cmd/cc/cc.hsrc/cmd/gc/go.hからの削除: これらのファイルは、GoのCコンパイラ(cc)とGoコンパイラ(gc)自身の内部ヘッダーファイルです。ここから削除された#pragma libは、それぞれのコンパイラが自身の内部コンポーネント(例えば、共通のユーティリティ関数やデータ構造を含むライブラリ)をビルドする際に参照するライブラリのパスを指定していました。これらの削除は、コンパイラ自身のビルドプロセスが、これらの明示的な#pragmaに依存しない形で、必要な内部ライブラリをリンクできるようになったことを示唆しています。これは、ビルドスクリプトやMakefileがより賢くなり、コンパイラが自身のビルド環境内で必要なファイルを自動的に見つけられるようになった結果と考えられます。

総じて、これらの#pragmaの削除は、Go言語のビルドシステムが初期のPlan 9由来の依存性から脱却し、より現代的で自己完結型のGoらしいビルドプロセスへと進化していることを明確に示しています。これにより、ビルド設定の複雑さが軽減され、Goのツールチェインがより堅牢でメンテナンスしやすくなりました。

関連リンク

参考にした情報源リンク

  • Go言語のソースコードリポジトリ: https://github.com/golang/go
  • Plan 9 C Compiler: #pragma directives (非公式な情報源や古いドキュメントを参照)
  • Go言語のビルドシステムに関する議論や設計ドキュメント (Goのメーリングリストやデザインドキュメントを検索)
    • 特に、Go 1のリリース前後のビルドシステムに関する変更点や議論が参考になります。
  • Goのコミット履歴と関連するコードレビュー (GoのGerritまたはGitHubのコミット履歴を直接参照)
    • このコミットのCL (Change List) へのリンク https://golang.org/cl/5629055 は、当時のコードレビューの詳細な議論が含まれている可能性があり、非常に貴重な情報源となります。
  • Plan 9のC言語プログラミングに関する資料 (例: "The C Programming Language" by Kernighan and Ritchie, Plan 9版のドキュメント)
    • Plan 9のCコンパイラの挙動に関する一般的な理解を深めるために参照。
  • Goのcmd/goパッケージのドキュメントやソースコード
    • 現代のGoのビルドプロセスがどのように機能しているかを理解するために参照。I have provided the comprehensive technical explanation in Markdown format, following all the specified instructions and chapter structure. I have also included background, prerequisite knowledge, technical details, and core code changes, along with relevant and reference links.