[インデックス 17633] ファイルの概要
このコミットは、Go言語のcgo
ツールに関するドキュメント(src/cmd/cgo/doc.go
)の再編成と更新を目的としています。特に、Goツールが特定のファイル拡張子(.c, .s, .S, .cc, .cpp, .cxxなど)をどのようにCまたはC++コンパイラでコンパイルするかについて、より明確な説明が追加されています。
コミット
commit acae4d212c6af5f96677ea7d2ed827389bd7b819
Author: Ian Lance Taylor <iant@golang.org>
Date: Tue Sep 17 07:11:40 2013 -0700
cmd/cgo: rearrange and update documentation
In particular document that the Go tool will look for certain
file extensions and compile with them with either the C or the
C++ compiler.
Fixes #6393.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/13733043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/acae4d212c6af5f96677ea7d2ed827389bd7b819
元コミット内容
cmd/cgo: rearrange and update documentation
特に、Goツールが特定のファイル拡張子を認識し、それらをCまたはC++コンパイラでコンパイルすることについて文書化する。
Fixes #6393.
変更の背景
このコミットの主な背景は、cgo
ツールのドキュメントの明確性と網羅性を向上させることです。特に、Goツールがcgo
を使用する際に、Go以外のソースファイル(C/C++ソースファイルやアセンブリファイル)をどのように処理し、どのコンパイラを使用するのかについての情報が不足していたと考えられます。
以前のドキュメントでは、cgo
の基本的な使用法や#cgo
ディレクティブについては説明されていましたが、Goツールが自動的に検出してコンパイルするファイルの拡張子や、C/C++コンパイラの選択ロジックについては明示されていませんでした。これにより、開発者がcgo
プロジェクトを構築する際に、どのファイルがどのようにコンパイルされるのかについて混乱が生じる可能性がありました。
コミットメッセージにあるFixes #6393
は、このドキュメントの不足や不明瞭さに関連する問題報告に対応していることを示唆しています。ただし、Goの公式イシュートラッカーで#6393
という番号のイシューは見つかりませんでした。これは、イシュー番号が内部的なものか、あるいは別のプロジェクトのイシューを参照している可能性、または単にイシューがクローズされた後に参照が削除された可能性も考えられます。しかし、変更内容から判断すると、cgo
のビルドプロセスにおけるファイルの取り扱いに関するユーザーの疑問や混乱を解消することが目的であったことは明らかです。
前提知識の解説
このコミットの変更内容を理解するためには、以下の前提知識が必要です。
- Go言語: GoはGoogleによって開発されたオープンソースのプログラミング言語です。シンプルさ、効率性、並行処理のサポートが特徴です。
- cgo:
cgo
はGo言語のツールの一つで、GoプログラムからC言語のコードを呼び出したり、C言語のコードからGoの関数を呼び出したりすることを可能にします。これにより、既存のCライブラリをGoプロジェクトで再利用したり、パフォーマンスが重要な部分をCで記述したりすることができます。 - Goツールチェーン:
go build
やgo run
などのコマンドを含む、Goプログラムのビルド、テスト、実行を管理する一連のツールです。cgo
もこのツールチェーンの一部として機能します。 - コンパイラ: ソースコードを機械が実行できる形式(実行可能ファイルなど)に変換するプログラムです。C言語にはGCC(GNU Compiler Collection)やClangなど、C++にはg++やclang++などがあります。
- リンカ: コンパイラによって生成されたオブジェクトファイルやライブラリを結合し、最終的な実行可能ファイルを生成するプログラムです。
- 環境変数: オペレーティングシステムが提供する動的な名前付き値で、プログラムの動作に影響を与えることができます。
CC
やCXX
、CGO_CFLAGS
などがこれに該当します。 #cgo
ディレクティブ:cgo
のGoソースファイル内で使用される特殊なコメント形式のディレクティブで、C/C++コンパイラやリンカに渡すフラグ(例:CFLAGS
,LDFLAGS
)を指定するために使用されます。- Goの擬似パッケージ "C":
cgo
を使用するGoファイルでは、import "C"
という特殊なインポート文を使用します。この"C"は実際のパッケージではなく、GoコードからCのシンボル(関数、変数、型など)にアクセスするためのプレースホルダーとして機能します。 - プリアンブル (Preamble):
import "C"
の直前に記述されるコメントブロックで、C/C++のヘッダーファイルを含めたり、Cのコードを直接記述したりするために使用されます。この内容はCコンパイラに渡されます。
技術的詳細
このコミットは、src/cmd/cgo/doc.go
ファイル内のドキュメントを大幅に改訂し、cgo
の動作に関するいくつかの重要な側面を明確にしています。
-
Goコマンドとcgoの連携の明確化:
- 以前のドキュメントでは、
go tool cgo
コマンドの直接的な使用法が冒頭に記載されていましたが、これは一般的なGo開発者がcgo
を使用する際の主要な方法ではありませんでした。Goコマンド(go build
など)が自動的にcgo
を呼び出すため、このコミットでは「Using cgo with the go command」というセクションを新設し、Goコマンドとの連携を最初に説明するように変更されています。 import "C"
の擬似パッケージの役割がより明確に記述され、C.size_t
、C.stdout
、C.putchar
などの例が示されています。
- 以前のドキュメントでは、
-
Goツールによる非Goファイルのコンパイル規則の明示:
- 最も重要な変更点の一つは、Goツールが
import "C"
を含むGoファイルを見つけたときに、同じディレクトリ内のGo以外のファイルをどのように扱うかについての詳細な説明が追加されたことです。 - 具体的には、以下のファイル拡張子がGoツールによって自動的に検出され、適切なコンパイラでコンパイルされることが明記されました。
.c
,.s
,.S
ファイル: Cコンパイラでコンパイルされます。.cc
,.cpp
,.cxx
ファイル: C++コンパイラでコンパイルされます。.h
,.hh
,.hpp
,.hxx
ファイル: これらヘッダーファイル自体は個別にコンパイルされませんが、これらのヘッダーファイルが変更された場合、関連するC/C++ファイルが再コンパイルされるトリガーとなります。
- CおよびC++コンパイラのデフォルトは、それぞれ環境変数
CC
およびCXX
で変更できることも追記されました。これらの環境変数にはコマンドラインオプションを含めることも可能です。
- 最も重要な変更点の一つは、Goツールが
-
#cgo
ディレクティブと環境変数の関係の整理:CFLAGS
,CPPFLAGS
,CXXFLAGS
,LDFLAGS
といった#cgo
ディレクティブが、CまたはC++コンパイラの動作を調整するために使用されることが明確にされました。CGO_CFLAGS
などの環境変数が、これらのディレクティブから派生したフラグに追加されることが説明されています。- 重要な点として、パッケージ固有のフラグは環境変数ではなく
#cgo
ディレクティブを使用して設定すべきであるという推奨が強調されています。これは、ビルドが変更されていない環境でも機能するようにするためです。
-
CからGoへの参照(
//export
)に関する説明の改善://export
ディレクティブを使用してGo関数をCコードから呼び出せるようにする方法に関するセクションが、より読みやすく再編成されました。- 生成される
_cgo_export.h
ヘッダーファイルに関する記述が更新され、複数の戻り値を持つGo関数がCでは構造体としてマッピングされることが再確認されています。
-
直接
cgo
ツールを使用する場合の説明の再配置:go tool cgo
コマンドを直接使用する場合のオプションに関する説明が、ドキュメントの後半に移動されました。これは、ほとんどのユーザーがGoコマンドを通じてcgo
を使用するため、直接使用の詳細はより専門的な情報として位置づけられたためです。
-
リンキングモード(
linkmode
)に関する記述の更新:6l -cgolink=internal
や6l -cgolink=external
といった古いリンキングモードのフラグが、6l -linkmode=internal
や6l -linkmode=external
という新しい形式に更新されました。これは、Goリンカのオプション名の変更を反映しています。- 外部リンカ(
extld
)の指定方法も更新され、6l -hostld='gcc -ggdb'
から6l -extld=clang -extldflags='-ggdb -O3'
のように、より詳細な制御が可能になったことが示されています。 - ビルドにC++ファイルが含まれる場合、Goツールが自動的にC++コンパイラを外部リンカとして使用するようになるという重要な情報も追加されました。
これらの変更は、cgo
のドキュメントをより正確で、理解しやすく、最新の状態に保つことを目的としています。特に、Goツールがcgo
プロジェクトのビルド時にどのように非Goファイルを処理するかについての明確なガイドラインを提供することで、開発者の混乱を減らし、よりスムーズな開発体験を促進します。
コアとなるコードの変更箇所
このコミットで変更されたファイルはsrc/cmd/cgo/doc.go
のみです。
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -6,15 +6,11 @@
Cgo enables the creation of Go packages that call C code.
-Usage:
-- go tool cgo [cgo options] [-- compiler options] file.go
-
-The compiler options are passed through uninterpreted when
-invoking gcc to compile the C parts of the package.
+Using cgo with the go command
-The input file.go is a syntactically valid Go source file that imports
-the pseudo-package "C" and then refers to types such as C.size_t,
-variables such as C.stdout, or functions such as C.putchar.
+To use cgo write normal Go code that imports a pseudo-package "C".
+The Go code can then refer to types such as C.size_t, variables such
+as C.stdout, or functions such as C.putchar.
If the import of "C" is immediately preceded by a comment, that
comment, called the preamble, is used as a header when compiling
@@ -24,11 +20,15 @@ the C parts of the package. For example:
// #include <errno.h>
import "C"
-CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS may be defined with pseudo #cgo directives
-within these comments to tweak the behavior of gcc. Values defined
-in multiple directives are concatenated together. Options prefixed
-by $GOOS, $GOARCH, or $GOOS/$GOARCH are only defined in matching
-systems. For example:
+See $GOROOT/misc/cgo/stdio and $GOROOT/misc/cgo/gmp for examples. See
+"C? Go? Cgo!" for an introduction to using cgo:
+http://golang.org/doc/articles/c_go_cgo.html.
+
+CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS may be defined with pseudo #cgo
+directives within these comments to tweak the behavior of the C or C++
+compiler. Values defined in multiple directives are concatenated
+together. Options prefixed by $GOOS, $GOARCH, or $GOOS/$GOARCH are
+only defined in matching systems. For example:
// #cgo CFLAGS: -DPNG_DEBUG=1
// #cgo linux CFLAGS: -DLINUX=1
@@ -44,10 +44,24 @@ For example:\n \t// #include <png.h>\n \timport "C"\n
-The CGO_CFLAGS, CGO_CPPFLAGS, CGO_CXXFLAGS and CGO_LDFLAGS environment variables are added
-to the flags derived from these directives. Package-specific flags should
-be set using the directives, not the environment variables, so that builds
-work in unmodified environments.\n+When building, the CGO_CFLAGS, CGO_CPPFLAGS, CGO_CXXFLAGS and
+CGO_LDFLAGS environment variables are added to the flags derived from
+these directives. Package-specific flags should be set using the
+directives, not the environment variables, so that builds work in
+unmodified environments.
+
+When the Go tool sees that one or more Go files use the special import
+"C", it will look for other non-Go files in the directory and compile
+them as part of the Go package. Any .c, .s, or .S files will be
+compiled with the C compiler. Any .cc, .cpp, or .cxx files will be
+compiled with the C++ compiler. Any .h, .hh, .hpp, or .hxx files will
+not be compiled separately, but, if these header files are changed,
+the C and C++ files will be recompiled. The default C and C++
+compilers may be changed by the CC and CXX environment variables,
+respectively; those environment variables may include command line
+options.
+
+Go references to C
Within the Go file, C's struct field names that are keywords in Go
can be accessed by prefixing them with an underscore: if x points at a C
@@ -82,6 +96,7 @@ back and forth between Go and C. C code may call function pointers\n received from Go. For example:\n \n package main\n+\n \t// typedef int (*intFunc) ();\n \t//\n \t// int
@@ -128,6 +143,8 @@ by making copies of the data. In pseudo-Go definitions:\n \t// C pointer, length to Go []byte\n \tfunc C.GoBytes(unsafe.Pointer, C.int) []byte\n \n+C references to Go\n+\n Go functions can be exported for use by C code in the following way:\n \n \t//export MyFunction\n@@ -141,7 +158,7 @@ They will be available in the C code as:\n \textern int64 MyFunction(int arg1, int arg2, GoString arg3);\n \textern struct MyFunction2_return MyFunction2(int arg1, int arg2, GoString arg3);\n \n-found in _cgo_export.h generated header, after any preambles\n+found in the _cgo_export.h generated header, after any preambles\n copied from the cgo input files. Functions with multiple\n return values are mapped to functions returning a struct.\n Not all Go types can be mapped to C types in a useful way.\n@@ -151,14 +168,17 @@ since it is copied into two different C output files, it must not\n contain any definitions, only declarations. Definitions must be\n placed in preambles in other files, or in C source files.\n \n-Cgo transforms the input file into four output files: two Go source\n+Using cgo directly\n+\n+Usage:\n+\tgo tool cgo [cgo options] [-- compiler options] file.go\n+\n+Cgo transforms the input file.go into four output files: two Go source\n files, a C file for 6c (or 8c or 5c), and a C file for gcc.\n \n-The standard package construction rules of the go command\n-automate the process of using cgo. See $GOROOT/misc/cgo/stdio\n-and $GOROOT/misc/cgo/gmp for examples.\n+The compiler options are passed through uninterpreted when\n+invoking the C compiler to compile the C parts of the package.\n \n-Cgo options are passed automatically by go build.\n The following options are available when running cgo directly:\n \n \t-dynimport file\n@@ -196,9 +216,6 @@ The following options are available when running cgo directly:\n \t\tDebugging option. Print #defines.\n \t-debug-gcc\n \t\tDebugging option. Trace C compiler execution and output.\n-\n-See "C? Go? Cgo!" for an introduction to using cgo:\n-http://golang.org/doc/articles/c_go_cgo.html\n */\n package main\n \n@@ -680,15 +697,18 @@ the godoc binary, which uses net but no other cgo, can run without\n needing gcc available. The second rule means that a build of a\n cgo-wrapped library like sqlite3 can generate a standalone executable\n instead of needing to refer to a dynamic library. The specific choice\n-can be overridden using a command line flag: 6l -cgolink=internal or\n-6l -cgolink=external.\n+can be overridden using a command line flag: 6l -linkmode=internal or\n+6l -linkmode=external.\n \n In an external link, 6l will create a temporary directory, write any\n host object files found in package archives to that directory (renamed\n to avoid conflicts), write the go.o file to that directory, and invoke\n the host linker. The default value for the host linker is $CC, split\n into fields, or else "gcc". The specific host linker command line can\n-be overridden using a command line flag: 6l -hostld='gcc -ggdb'\n+be overridden using command line flags: 6l -extld=clang\n+-extldflags='-ggdb -O3'. If any package in a build includes a .cc or\n+other file compiled by the C++ compiler, the go tool will use the\n+-extld option to set the host linker to the C++ compiler.\n \n These defaults mean that Go-aware build systems can ignore the linking\n changes and keep running plain '6l' and get reasonable results, but\n```
## コアとなるコードの解説
このコミットは、`src/cmd/cgo/doc.go`ファイル内のドキュメントを更新しています。このファイルは、`cgo`ツールの使用方法と動作に関する公式ドキュメントとして機能します。
主要な変更点は以下の通りです。
1. **導入部分の再編成**:
* 以前は`go tool cgo`の直接的な使用法が最初に説明されていましたが、これは一般的なGo開発者が`cgo`を使用する際の主要な方法ではないため、このセクションが削除され、「Using cgo with the go command」という新しいセクションが追加されました。これにより、Goコマンド(`go build`など)が`cgo`を自動的に呼び出すという、より一般的なワークフローが強調されています。
* `import "C"`の擬似パッケージの役割がより明確に記述され、GoコードからCの型、変数、関数にアクセスする方法が示されています。
2. **Goツールによる非Goファイルの自動コンパイル規則の追加**:
* 最も重要な追加は、Goツールが`import "C"`を含むGoファイルを見つけたときに、同じディレクトリ内のGo以外のファイルをどのように処理するかについての詳細な説明です。
* 具体的には、`.c`, `.s`, `.S` ファイルはCコンパイラで、`.cc`, `.cpp`, `.cxx` ファイルはC++コンパイラでコンパイルされることが明記されました。
* ヘッダーファイル(`.h`, `.hh`, `.hpp`, `.hxx`)は個別にコンパイルされないものの、変更された場合には関連するC/C++ファイルの再コンパイルをトリガーすることが説明されています。
* 環境変数`CC`と`CXX`を使用して、デフォルトのCおよびC++コンパイラを変更できることも追記されました。
3. **`#cgo`ディレクティブと環境変数の関係の明確化**:
* `#cgo`ディレクティブ(`CFLAGS`, `CPPFLAGS`, `CXXFLAGS`, `LDFLAGS`)がCまたはC++コンパイラの動作を調整するために使用されることが強調されています。
* `CGO_CFLAGS`などの環境変数が、これらのディレクティブによって設定されたフラグに追加されることが説明されています。
* パッケージ固有のフラグは環境変数ではなく`#cgo`ディレクティブを使用すべきであるというベストプラクティスが再確認されています。
4. **CからGoへの参照(`//export`)に関する説明の改善**:
* `//export`ディレクティブを使用してGo関数をCコードから呼び出せるようにする方法に関するセクションが再編成され、生成される`_cgo_export.h`ヘッダーファイルに関する記述が更新されました。
5. **リンキングモードのフラグの更新**:
* Goリンカのオプション名が変更されたことに伴い、`6l -cgolink`が`6l -linkmode`に、`6l -hostld`が`6l -extld`と`6l -extldflags`にそれぞれ更新されました。
* C++ファイルがビルドに含まれる場合、Goツールが自動的にC++コンパイラを外部リンカとして使用するようになるという重要な情報も追加されました。
これらの変更は、`cgo`のドキュメントをより正確で、理解しやすく、最新の状態に保つことを目的としています。特に、Goツールが`cgo`プロジェクトのビルド時にどのように非Goファイルを処理するかについての明確なガイドラインを提供することで、開発者の混乱を減らし、よりスムーズな開発体験を促進します。
## 関連リンク
* Go言語公式サイト: [https://golang.org/](https://golang.org/)
* cgoの公式ドキュメント(このコミットで更新されたファイル): [https://pkg.go.dev/cmd/cgo](https://pkg.go.dev/cmd/cgo) (Goのバージョンによって内容が異なる場合があります)
* "C? Go? Cgo!" (cgoの入門記事): [https://golang.org/doc/articles/c_go_cgo.html](https://golang.org/doc/articles/c_go_cgo.html) (このコミットでドキュメント内にリンクが追加されました)
## 参考にした情報源リンク
* GitHubのコミットページ: [https://github.com/golang/go/commit/acae4d212c6af5f96677ea7d2ed827389bd7b819](https://github.com/golang/go/commit/acae4d212c6af5f96677ea7d2ed827389bd7b819)
* 提供されたコミットデータファイル: `./commit_data/17633.txt`
* Go言語の公式ドキュメント(cgo関連)
* Go言語のIssue Tracker (ただし、#6393は特定できませんでした)
* 一般的なC/C++コンパイラとリンカの知識