[インデックス 12527] ファイルの概要
このコミットは、Go言語のコマンドラインツールである gc
(コンパイラ)、ld
(リンカ)、nm
(シンボル表示ツール) のドキュメントに対する様々な更新と改善を目的としています。特に、コマンドの利用方法の記述を go tool xxx
形式で統一し、ld
コマンドのドキュメントを再フォーマットし、-H
フラグの適用可能性や -d
フラグのWindowsでの制限、そして -Hwindowsgui
フラグに関する詳細な説明を追加しています。これにより、Goツールのドキュメントの一貫性と正確性が向上し、ユーザーがこれらのツールをより効果的に利用できるようになります。
コミット
- コミットハッシュ:
736ff448ded5b2b4aefffb91390bc554593613da
- 作者: Shenghou Ma minux.ma@gmail.com
- コミット日時: 2012年3月9日 金曜日 01:31:09 +0800
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/736ff448ded5b2b4aefffb91390bc554593613da
元コミット内容
doc: various update to command documents
1. consistent usage section (go tool xxx)
2. reformat cmd/ld document with minor correction
document which -H flags are valid on which ld
document -d flag can't be used on Windows.
document -Hwindowsgui
R=golang-dev, r, rsc
CC=golang-dev
https://golang.org/cl/5782043
変更の背景
このコミットが行われた2012年当時、Go言語はまだ比較的新しい言語であり、そのツールチェインも活発に開発・改善されていました。初期のドキュメントは、機能の追加や変更に追いつく形で記述されており、必ずしも一貫性や網羅性が高いとは限りませんでした。
このコミットの背景には、以下の点が挙げられます。
- ドキュメントの一貫性の欠如:
go tool
コマンドの利用方法に関する記述が、各ツールのドキュメント間で統一されていなかった可能性があります。例えば、あるドキュメントでは6g [flags] file...
のように直接コマンド名を記述し、別のドキュメントではgo tool 6g [flags] file...
のようにgo tool
プレフィックスを付けて記述するといった不整合があったと考えられます。これをgo tool xxx
形式に統一することで、ユーザーがGoツールを呼び出す際の標準的な方法を明確にする狙いがあります。 - リンカ (
ld
) ドキュメントの不正確性・不完全性: リンカは、コンパイルされたオブジェクトファイルを結合して実行可能ファイルを生成する重要なツールです。特に、異なるオペレーティングシステムやアーキテクチャに対応するために、多くのオプション(フラグ)を持っています。ld
のドキュメントには、以下のような課題があったと推測されます。-H
フラグの適用範囲の不明確さ:-H
フラグは、出力するバイナリの形式(ELF, Mach-O, PEなど)を指定するために使用されますが、どのリンカ(5l
,6l
,8l
など)でどの-H
フラグが有効なのかが明確でなかった可能性があります。-d
フラグのプラットフォーム依存性:-d
フラグは動的リンクヘッダを省略し、静的リンクを行うためのものですが、Windows環境では特定の制約があるにもかかわらず、それが明記されていなかった可能性があります。- Windows GUIバイナリのサポート: Windows環境でGUIアプリケーションを開発する際に必要となる
-Hwindowsgui
フラグに関するドキュメントが不足していたか、存在しなかった可能性があります。
- ユーザーエクスペリエンスの向上: ドキュメントの品質は、ツールの使いやすさに直結します。正確で一貫性のあるドキュメントは、ユーザーがGoツールを学習し、問題を解決する上で不可欠です。これらのドキュメント改善は、Go開発者の生産性向上に寄与することを目的としています。
これらの背景から、Goツールチェインのドキュメントをより正確で、一貫性があり、網羅的なものにするためのメンテナンス作業の一環として、このコミットが実施されました。
前提知識の解説
このコミットの変更内容を理解するためには、以下の前提知識が必要です。
-
Go言語のツールチェイン: Go言語は、ソースコードのコンパイル、リンク、テスト、フォーマットなどを行うための統合されたツールチェインを提供します。主要なツールには以下のようなものがあります。
go
コマンド: Go言語のビルドシステムの中核となるコマンドです。go build
,go run
,go test
などのサブコマンドを持ち、Goプログラムのライフサイクルを管理します。go tool
コマンド:go
コマンドのサブコマンドの一つで、Goツールチェインに含まれる低レベルなツール(コンパイラ、リンカ、アセンブラなど)を直接呼び出すために使用されます。例えば、go tool 6g
は64ビットアーキテクチャ向けのGoコンパイラを、go tool 6l
は64ビットアーキテクチャ向けのGoリンカを呼び出します。gc
(Go Compiler): Go言語のソースコードをオブジェクトファイル(.5
,.6
,.8
など、アーキテクチャに依存)にコンパイルするツールです。例えば、6g
はAMD64 (x86-64) アーキテクチャ向けのコンパイラを指します。ld
(Go Linker): コンパイラによって生成されたオブジェクトファイルやライブラリを結合し、実行可能なバイナリファイルを生成するツールです。Plan 9リンカをベースにGo用に改良されています。例えば、6l
はAMD64 (x86-64) アーキテクチャ向けのリンカを指します。nm
(Symbol Table Display Utility): オブジェクトファイルや実行可能ファイル内のシンボル(関数名、変数名など)を表示するツールです。Unix系のnm
コマンドに似ています。
-
バイナリファイルフォーマット: 実行可能ファイルは、オペレーティングシステムが理解できる特定のフォーマットで構成されています。このコミットで言及されている主なフォーマットは以下の通りです。
- ELF (Executable and Linkable Format): Linux、FreeBSD、NetBSD、OpenBSDなどのUnix系システムで広く使用されている標準的な実行可能ファイル、オブジェクトファイル、共有ライブラリのフォーマットです。
- Mach-O (Mach Object): AppleのmacOS (旧OS X) やiOSで使用されている実行可能ファイル、オブジェクトファイル、共有ライブラリのフォーマットです。
- PE (Portable Executable): Microsoft Windowsで使用されている実行可能ファイル、オブジェクトファイル、DLL (Dynamic Link Library) のフォーマットです。PE32+ は64ビットWindowsアプリケーション向けのPEフォーマットを指します。
-
動的リンクと静的リンク:
- 動的リンク (Dynamic Linking): 実行可能ファイルが、実行時に必要なライブラリ(共有ライブラリ、DLLなど)をロードして使用する方式です。これにより、実行可能ファイルのサイズを小さく保ち、複数のプログラムで同じライブラリを共有できます。
- 静的リンク (Static Linking): 実行可能ファイルが、必要なライブラリのコードをすべて自身の内部に含める方式です。これにより、実行可能ファイルは自己完結型となり、ライブラリがシステムにインストールされているかどうかに依存しなくなりますが、ファイルサイズは大きくなります。
-
Plan 9: ベル研究所で開発された分散オペレーティングシステムです。Go言語の設計思想やツールチェイン(特にコンパイラやリンカ)は、Plan 9のそれらに大きな影響を受けています。Goのリンカ
ld
は、Plan 9のリンカをベースにしています。
技術的詳細
このコミットは、Goツールチェインのドキュメント、特に src/cmd/gc/doc.go
、src/cmd/ld/doc.go
、src/cmd/nm/doc.go
の3つのファイルにわたる変更を含んでいます。
1. go tool xxx
形式への統一
以前のドキュメントでは、Goのコンパイラ (6g
, 8g
, 5g
) やリンカ (6l
, 8l
, 5l
) を直接呼び出す形式 (6g [flags] file...
) で使用法が記述されていました。しかし、Goの公式な推奨は、これらの低レベルツールを go tool
コマンドを介して呼び出すことです (go tool 6g [flags] file...
)。この変更は、ドキュメント全体でこの推奨される呼び出し形式に統一することで、ユーザーがGoツールをより一貫した方法で利用できるようにすることを目的としています。これは、Goツールチェインの設計思想と利用ガイドラインをドキュメントに反映させる重要なステップです。
2. cmd/ld
ドキュメントの再フォーマットと詳細化
ld
(リンカ) のドキュメント (src/cmd/ld/doc.go
) は、最も広範な変更を受けています。
- PEバイナリのサポート明記: 以前は「ELFとMach-Oバイナリのサポート」とだけ記述されていましたが、Windows向けの「PEバイナリ」のサポートも明記されました。これは、GoがWindows環境も公式にサポートしていることを反映した重要な更新です。
- 出力ファイル名のWindows特有の挙動:
$GOOS
がwindows
の場合、デフォルトの出力ファイル名(例:6.out
)に.exe
拡張子が自動的に付加されることが明記されました。これはWindowsユーザーにとって非常に実用的な情報です。 -d
フラグの詳細化とWindowsでの制限:-d
フラグは、動的リンクヘッダを省略し、バイナリを静的にリンクするためのオプションです。これにより、生成される実行可能ファイルは外部の動的リンカに依存しなくなります。- 重要な変更点として、**「このフラグは
$GOOS
がwindows
の場合には使用できません」**という制約が明記されました。WindowsのPEフォーマットや動的リンクの仕組みはUnix系システムとは異なり、GoのリンカがWindows上で完全に静的なバイナリを生成する際に特定の課題があるため、この制約が設けられていると考えられます。これは、ユーザーがWindowsで-d
フラグを使用しようとした際の混乱を防ぐための重要な情報です。
-H
フラグの適用リンカの明記:-H
フラグは、出力バイナリのOS固有のフォーマットを指定します(例:-Hdarwin
はMach-O、-Hlinux
はELF)。- このコミットでは、各
-H
フラグがどのリンカ(6l
/8l
のみ、または全リンカ)で有効であるかが明記されました。例えば、-Hdarwin
,-Hfreebsd
,-Hnetbsd
,-Hopenbsd
,-Hwindows
,-Hwindowsgui
は「(only in 6l/8l)」と追記されています。これは、これらのフラグが主に64ビットおよび32ビットのIntel/AMDアーキテクチャ(6l
はAMD64、8l
は386)で関連性が高いためと考えられます。これにより、ユーザーは特定のアーキテクチャのリンカを使用する際に、どの-H
フラグが利用可能かを正確に把握できます。
-Hwindowsgui
フラグの追加:- 新たに
-Hwindowsgui
フラグがドキュメントに追加されました。このフラグは、Windows上でGUIアプリケーションをビルドする際に使用され、生成されるPEバイナリがコンソールウィンドウを持たないGUIアプリケーションとして振る舞うように設定します。これは、GoでWindowsデスクトップアプリケーションを開発する際の重要なオプションであり、その存在が明記されたことで、開発者はより簡単にGUIアプリケーションをビルドできるようになります。
- 新たに
-L
フラグのデフォルトパスの更新: ライブラリ検索パスを指定する-L
フラグのデフォルトパスが$GOROOT/pkg/$GOOS_amd64
から$GOROOT/pkg/$GOOS_$GOARCH
に変更されました。これは、より汎用的なアーキテクチャ名 ($GOARCH
) を使用することで、異なるアーキテクチャ(例: ARM)にも対応できるようにするための改善です。
3. cmd/nm
ドキュメントの利用方法の統一
nm
(シンボル表示ツール) のドキュメント (src/cmd/nm/doc.go
) も、go tool nm [-aghnsTu] file
という形式で利用方法が統一されました。これにより、nm
コマンドの呼び出し方も他のGoツールと同様に go tool
プレフィックスを使用することが明確になります。
これらの変更は、Goツールチェインのドキュメントの品質を全体的に向上させ、特にリンカの挙動に関する重要な詳細を明確にすることで、Go開発者が直面する可能性のある問題を未然に防ぎ、よりスムーズな開発体験を提供することを目的としています。
コアとなるコードの変更箇所
このコミットは、Goツールチェインのドキュメントファイルのみを変更しており、実際のコンパイラやリンカのコード自体には変更を加えていません。変更されたファイルは以下の通りです。
-
src/cmd/gc/doc.go
:--- a/src/cmd/gc/doc.go +++ b/src/cmd/gc/doc.go @@ -26,7 +26,7 @@ package P to read the files of P's dependencies, only the compiled output of P. Usage: - 6g [flags] file... + go tool 6g [flags] file... The specified files must be Go source files and all part of the same package. Substitute 6g with 8g or 5g where appropriate.
-
src/cmd/ld/doc.go
:--- a/src/cmd/ld/doc.go +++ b/src/cmd/ld/doc.go @@ -9,45 +9,52 @@ Ld is the portable code for a modified version of the Plan 9 linker. The origin http://plan9.bell-labs.com/magic/man2html/1/2l It reads object files (.5, .6, or .8 files) and writes a binary named for the -architecture (5.out, 6.out, 8.out) by default. +architecture (5.out, 6.out, 8.out) by default (if $GOOS is windows, a .exe suffix +will be appended). Major changes include: - - support for ELF and Mach-O binary files + - support for ELF, Mach-O and PE binary files - support for segmented stacks (this feature is implemented here, not in the compilers). Original options are listed on the manual page linked above. -Options new in this version: +Usage: + go tool 6l [flags] mainObj +Substitute 6l with 8l or 5l as appropriate. --d - Elide the dynamic linking header. With this option, the binary - is statically linked and does not refer to dynld. Without this option - (the default), the binary's contents are identical but it is loaded with dynld. --Hdarwin - Write Apple Mach-O binaries (default when $GOOS is darwin) --Hlinux - Write Linux ELF binaries (default when $GOOS is linux) --Hfreebsd - Write FreeBSD ELF binaries (default when $GOOS is freebsd) --Hnetbsd - Write NetBSD ELF binaries (default when $GOOS is netbsd) --Hopenbsd - Write OpenBSD ELF binaries (default when $GOOS is openbsd) --Hwindows - Write Windows PE32+ binaries (default when $GOOS is windows) --I interpreter - Set the ELF dynamic linker to use. --L dir1 -L dir2 - Search for libraries (package files) in dir1, dir2, etc. - The default is the single location $GOROOT/pkg/$GOOS_amd64. --r dir1:dir2:... - Set the dynamic linker search path when using ELF. --V - Print the linker version. --X symbol value - Set the value of an otherwise uninitialized string variable. - The symbol name should be of the form importpath.name, - as displayed in the symbol table printed by "go tool nm". +Options new in this version: + -d + Elide the dynamic linking header. With this option, the binary + is statically linked and does not refer to a dynamic linker. Without this option + (the default), the binary's contents are identical but it is loaded with a dynamic + linker. This flag cannot be used when $GOOS is windows. + -Hdarwin (only in 6l/8l) + Write Apple Mach-O binaries (default when $GOOS is darwin) + -Hlinux + Write Linux ELF binaries (default when $GOOS is linux) + -Hfreebsd (only in 6l/8l) + Write FreeBSD ELF binaries (default when $GOOS is freebsd) + -Hnetbsd (only in 6l/8l) + Write NetBSD ELF binaries (default when $GOOS is netbsd) + -Hopenbsd (only in 6l/8l) + Write OpenBSD ELF binaries (default when $GOOS is openbsd) + -Hwindows (only in 6l/8l) + Write Windows PE32+ Console binaries (default when $GOOS is windows) + -Hwindowsgui (only in 6l/8l) + Write Windows PE32+ GUI binaries + -I interpreter + Set the ELF dynamic linker to use. + -L dir1 -L dir2 + Search for libraries (package files) in dir1, dir2, etc. + The default is the single location $GOROOT/pkg/$GOOS_$GOARCH. + -r dir1:dir2:... + Set the dynamic linker search path when using ELF. + -V + Print the linker version. + -X symbol value + Set the value of an otherwise uninitialized string variable. + The symbol name should be of the form importpath.name, + as displayed in the symbol table printed by "go tool nm".
-
src/cmd/nm/doc.go
:--- a/src/cmd/nm/doc.go +++ b/src/cmd/nm/doc.go @@ -14,7 +14,8 @@ Plan 9 C compiler. This implementation adds the flag -S, which prints each symbol's size in decimal after its address. -It is installed as go tool nm and is architecture-independent. +Usage: + go tool nm [-aghnsTu] file */ package documentation
コアとなるコードの解説
このコミットは、Goツールチェインのドキュメントを改善するためのものです。各ファイルの変更は、以下の目的を持っています。
src/cmd/gc/doc.go
の変更
Usage:
セクションの統一: 以前は6g [flags] file...
と記述されていたGoコンパイラ (gc
) の使用例が、go tool 6g [flags] file...
に変更されました。これは、Goツールチェインの標準的な呼び出し方法であるgo tool
プレフィックスを使用する形式に統一するためのものです。これにより、ユーザーはGoの低レベルツールを呼び出す際に、常にgo tool
を介するという一貫したパターンを学ぶことができます。
src/cmd/ld/doc.go
の変更
このファイルは最も多くの変更があり、Goリンカ (ld
) のドキュメントの正確性と網羅性を大幅に向上させています。
-
出力ファイル名のWindows特有の挙動の明記:
- 変更前:
writes a binary named for the architecture (5.out, 6.out, 8.out) by default.
- 変更後:
writes a binary named for the architecture (5.out, 6.out, 8.out) by default (if $GOOS is windows, a .exe suffix will be appended).
- この変更により、Windows環境でGoリンカを使用した場合に、実行可能ファイルに自動的に
.exe
拡張子が追加されるという挙動が明確に記述されました。これはWindowsユーザーにとって非常に重要な情報であり、生成されるファイル名に関する混乱を防ぎます。
- 変更前:
-
PEバイナリフォーマットのサポート明記:
- 変更前:
- support for ELF and Mach-O binary files
- 変更後:
- support for ELF, Mach-O and PE binary files
- GoリンカがWindowsのPE (Portable Executable) バイナリフォーマットもサポートしていることが明示されました。これにより、Goがクロスプラットフォーム開発においてWindowsを完全にサポートしていることが強調されます。
- 変更前:
-
Usage:
セクションの統一:gc
と同様に、リンカの使用例もgo tool 6l [flags] mainObj
の形式に統一されました。
-
-d
フラグの詳細化とWindowsでの制限の追加:- 変更前は、
-d
フラグが動的リンクヘッダを省略し、静的リンクを行うことを説明していました。 - 変更後、この説明がより明確になり、さらに「
This flag cannot be used when $GOOS is windows.
」という重要な制約が追加されました。これは、WindowsのPEバイナリの特性上、Goリンカが完全に動的リンクヘッダを省略した静的バイナリを生成することが難しい、あるいは特定の条件下で問題を引き起こす可能性があるためと考えられます。この制約を明記することで、Windowsユーザーがこのフラグを使用しようとした際の予期せぬエラーや挙動を回避できます。
- 変更前は、
-
-H
フラグの適用リンカの明記:-Hdarwin
,-Hfreebsd
,-Hnetbsd
,-Hopenbsd
,-Hwindows
,-Hwindowsgui
の各フラグの説明に「(only in 6l/8l)
」という注釈が追加されました。これは、これらのOS固有のバイナリフォーマットを生成するフラグが、主に64ビット (6l
) および32ビット (8l
) のIntel/AMDアーキテクチャ向けのリンカでのみ有効であることを示しています。これにより、ユーザーは使用しているリンカとターゲットOSの組み合わせにおいて、どの-H
フラグが適切であるかを正確に判断できるようになります。
-
-Hwindowsgui
フラグの追加:- 新たに
-Hwindowsgui
フラグがドキュメントに追加されました。このフラグは、Windows上でGUIアプリケーションをビルドする際に使用され、生成されるPEバイナリがコンソールウィンドウを持たないGUIアプリケーションとして動作するように設定します。これは、GoでWindowsデスクトップアプリケーションを開発する際に不可欠なオプションであり、その存在が明記されたことで、開発者はより簡単にGUIアプリケーションをビルドできるようになります。
- 新たに
-
-L
フラグのデフォルトパスの更新:- 変更前:
The default is the single location $GOROOT/pkg/$GOOS_amd64.
- 変更後:
The default is the single location $GOROOT/pkg/$GOOS_$GOARCH.
- ライブラリ検索パスのデフォルトが
$GOOS_amd64
から$GOOS_$GOARCH
に変更されました。これは、amd64
という特定のアーキテクチャ名ではなく、Goの環境変数$GOARCH
を使用することで、より汎用的に様々なアーキテクチャ(例:arm
,arm64
など)に対応できるようにするための改善です。
- 変更前:
src/cmd/nm/doc.go
の変更
Usage:
セクションの統一:nm
コマンドの使用例もgo tool nm [-aghnsTu] file
の形式に統一されました。これにより、nm
コマンドの呼び出し方も他のGoツールと同様にgo tool
プレフィックスを使用することが明確になります。
これらの変更は、Goツールチェインのドキュメントの品質を全体的に向上させ、特にリンカの挙動に関する重要な詳細を明確にすることで、Go開発者が直面する可能性のある問題を未然に防ぎ、よりスムーズな開発体験を提供することを目的としています。
関連リンク
- Go言語公式サイト: https://go.dev/
- Goコマンドドキュメント: https://go.dev/cmd/go/
- Goツールチェインの概要 (Go 1.4 ドキュメントより、当時の状況を推測): https://go.dev/doc/go1.4#toolchain (より古いバージョンを探す必要があるかもしれません)
- Plan 9 リンカのドキュメント (参照元): http://plan9.bell-labs.com/magic/man2html/1/2l
参考にした情報源リンク
- Go言語の公式ドキュメント (現在のバージョン): https://go.dev/doc/
- ELF (Executable and Linkable Format) - Wikipedia: https://ja.wikipedia.org/wiki/Executable_and_Linkable_Format
- Mach-O - Wikipedia: https://ja.wikipedia.org/wiki/Mach-O
- Portable Executable - Wikipedia: https://ja.wikipedia.org/wiki/Portable_Executable
- Goのビルドプロセスとリンカに関する議論 (当時のフォーラムやメーリングリストのアーカイブなどがあればより適切ですが、一般的な情報源として):
- "Go linker flags"
- "Go build process"
- "Go static vs dynamic linking"
- "Go windows gui build"
(注: 2012年当時の正確な情報源を見つけるのは困難な場合があります。上記の参考リンクは、現在のGoドキュメントや一般的な技術解説に基づいています。)