[インデックス 16450] ファイルの概要
このコミットは、Go言語のcmd/goツールにC++ファイルのサポートを追加するものです。これにより、Goパッケージ内でC++ソースファイル(.cc, .cpp, .cxx)を直接含め、cgoを通じてコンパイル・リンクできるようになります。また、C++ヘッダーファイル(.hh, .hpp, .hxx)の認識も強化され、cgoディレクティブにCPPFLAGSとCXXFLAGSが導入されました。
コミット
commit 84485361f94e2ea9eff9697105d71c9f53e44852
Author: Alberto García Hierro <alberto@garciahierro.com>
Date: Fri May 31 11:33:36 2013 -0700
cmd/go: Add support for including C++ files in packages
* Add a CXXFiles field to Package, which includes .cc, .cpp and .cxx files.
* CXXFiles are compiled using g++, which can be overridden using the CXX environment variable.
* Include .hh, .hpp and .hxx files in HFiles.
* Add support for CPPFLAGS (used for both C and C++) and CXXFLAGS (used only for C++) in cgo directive.
* Changed pkg-config cgo directive to modify CPPFLAGS rather than CFLAGS, so both C and C++ files get any flag returned by pkg-config --cflags.
Fixes #1476.
R=iant, r
CC=bradfitz, gobot, golang-dev, iant, minux.ma, remyoudompheng, seb.binet
https://golang.org/cl/8248043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/84485361f94e2ea9eff9697105d71c9f53e44852
元コミット内容
cmd/go: Add support for including C++ files in packages
* Add a CXXFiles field to Package, which includes .cc, .cpp and .cxx files.
* CXXFiles are compiled using g++, which can be overridden using the CXX environment variable.
* Include .hh, .hpp and .hxx files in HFiles.
* Add support for CPPFLAGS (used for both C and C++) and CXXFLAGS (used only for C++) in cgo directive.
* Changed pkg-config cgo directive to modify CPPFLAGS rather than CFLAGS, so both C and C++ files get any flag returned by pkg-config --cflags.
Fixes #1476.
変更の背景
Go言語は、C言語との相互運用を可能にするcgoツールを提供していますが、これまではC++ファイルの直接的なサポートが限定的でした。Goプログラムから既存のC++ライブラリを利用したり、パフォーマンスが重要な部分をC++で記述したりするニーズは存在します。
このコミット以前は、GoプロジェクトでC++コードを使用する場合、C++コードをC言語のインターフェースでラップし、そのCインターフェースをcgo経由でGoから呼び出すという間接的な方法が一般的でした。この方法は手間がかかり、C++の機能を直接活用しにくいという課題がありました。
この変更は、GoのビルドシステムがC++ファイルをよりネイティブに扱えるようにすることで、C++との連携を簡素化し、開発者の利便性を向上させることを目的としています。特に、#cgoディレクティブにおけるC++固有のコンパイラフラグのサポートや、pkg-configからのC++関連フラグの取得改善は、C++ライブラリとの連携をよりスムーズにするために不可欠でした。
前提知識の解説
Goのビルドプロセスとcgo
Go言語のビルドプロセスは、Goソースコードをコンパイルし、実行可能なバイナリを生成します。このプロセスにおいて、cgoはGoプログラムがC言語のコードと相互運用するための重要なツールです。
import "C": Goのソースファイル内でimport "C"と記述することで、そのファイルがcgoを使用することを示します。この宣言の直前のコメントブロックには、C言語のコード(プリアンブル)を記述できます。cgoの役割:go buildコマンドがimport "C"を含むGoファイルを見つけると、cgoツールが起動されます。cgoは、GoとCの間の呼び出しを仲介するスタブコードを生成し、Cコードをコンパイルするためにシステム上のCコンパイラ(通常はGCCやClang)を呼び出します。- コンパイルとリンク:
cgoによって生成されたCのオブジェクトファイルは、Goのオブジェクトファイルと共にリンクされ、最終的な実行可能バイナリが作成されます。
C/C++コンパイラと関連フラグ
C/C++コードをコンパイルする際には、様々なフラグ(オプション)をコンパイラに渡すことで、コンパイルの挙動を制御します。
gccとg++:gcc: 主にC言語のコンパイルに使用されるGNU Compiler Collectionのコンポーネントです。g++: 主にC++言語のコンパイルに使用されるGNU Compiler Collectionのコンポーネントです。C++固有の機能(クラス、テンプレートなど)をサポートします。
CPPFLAGS(C PreProcessor Flags): Cプリプロセッサに渡されるフラグです。主にヘッダーファイルの検索パス(-I)やマクロ定義(-D)などに使用されます。CとC++の両方のソースファイルに適用されます。CFLAGS(C Compiler Flags): Cコンパイラに渡されるフラグです。C言語のソースファイルにのみ適用されます。最適化レベル(-O2)、警告オプション(-Wall)などが含まれます。CXXFLAGS(C++ Compiler Flags): C++コンパイラに渡されるフラグです。C++言語のソースファイルにのみ適用されます。C++の標準バージョン指定(-std=c++11)などが含まれます。LDFLAGS(Linker Flags): リンカに渡されるフラグです。ライブラリの検索パス(-L)やリンクするライブラリ(-l)などを指定します。
pkg-config
pkg-configは、ソフトウェアライブラリのコンパイルおよびリンクに必要な情報を取得するためのコマンドラインツールです。ライブラリは.pcという拡張子のファイル(パッケージ設定ファイル)を提供し、これにはライブラリのバージョン、必要なインクルードパス、リンカフラグなどの情報が含まれています。
cgoは、#cgo pkg-config: <package_name>というディレクティブを使用することで、pkg-configから自動的にCFLAGSやLDFLAGSを取得し、ビルドプロセスに適用できます。これにより、手動でコンパイラやリンカのフラグを指定する手間が省け、ビルド設定のポータビリティが向上します。
Goのパッケージ構造とファイルの種類
Goのパッケージは、Goソースファイルだけでなく、C、C++、アセンブリなどの様々な種類のソースファイルを含むことができます。
.goファイル: Go言語のソースファイル。.cファイル: C言語のソースファイル。.sファイル: アセンブリ言語のソースファイル。.hファイル: C言語のヘッダーファイル。.sysoファイル: システムオブジェクトファイル。事前にコンパイルされたオブジェクトファイルで、Goのビルド時にリンクされます。SWIG関連ファイル:SWIG(Simplified Wrapper and Interface Generator) を使用する場合のファイル。
このコミットでは、Goのビルドシステムが認識するファイルの種類にC++関連のものが追加されます。
技術的詳細
このコミットの主要な目的は、GoのビルドシステムがC++ファイルをネイティブに扱い、cgoを通じてC++コードをコンパイル・リンクできるようにすることです。具体的な変更点は以下の通りです。
-
Package構造体へのCXXFilesフィールドの追加:cmd/go/pkg.goおよびsrc/pkg/go/build/build.go内のPackage構造体に、.cc,.cpp,.cxxといったC++ソースファイルを格納するためのCXXFilesフィールドが追加されました。これにより、GoのビルドツールはC++ファイルをGoパッケージの一部として認識し、管理できるようになります。 -
C++ファイルのコンパイルに
g++を使用:cmd/go/build.goにおいて、CXXFilesにリストされたC++ファイルはg++コンパイラを使用してコンパイルされるようになりました。g++のパスは、環境変数CXXでオーバーライド可能です。これにより、Goのビルドプロセス内でC++コードが適切に処理されます。 -
C++ヘッダーファイル(.hh, .hpp, .hxx)の認識:
HFilesフィールドが、従来の.hファイルに加えて、.hh,.hpp,.hxxといったC++のヘッダーファイルも含むように拡張されました。これにより、C++プロジェクトで一般的に使用されるヘッダーファイルがGoのビルドシステムによって適切に認識され、処理されるようになります。cmd/godoc/index.goでは、これらの新しい拡張子がホワイトリストに追加され、godocがこれらのファイルをインデックス化できるようになりました。 -
#cgoディレクティブにおけるCPPFLAGSとCXXFLAGSのサポート:src/cmd/cgo/doc.goのドキュメントが更新され、#cgoディレクティブでCPPFLAGSとCXXFLAGSが使用できるようになったことが明記されました。CPPFLAGS: Cプリプロセッサに渡されるフラグで、CとC++の両方のファイルに適用されます。CXXFLAGS: C++コンパイラにのみ渡されるフラグです。 これにより、Goパッケージ内でC/C++コードをビルドする際に、より細かくコンパイラオプションを制御できるようになります。対応する環境変数CGO_CPPFLAGSとCGO_CXXFLAGSも追加されました。
-
pkg-configディレクティブの変更:#cgo pkg-config:ディレクティブが返す--cflagsが、従来のCFLAGSではなくCPPFLAGSを修正するように変更されました。これは、pkg-configが返すフラグがCとC++の両方のファイルに適用されるべきであるという意図に基づいています。これにより、CとC++のソースファイルがpkg-configによって提供される共通のコンパイラフラグを確実に受け取れるようになります。 -
ビルド時のC++ファイル存在チェック:
cmd/go/build.goのbuild関数に、C++ファイルが存在するにもかかわらずcgoまたはSWIGを使用していないパッケージに対するエラーチェックが追加されました。これは、C++ファイルはcgoまたはSWIGを介してのみ処理できるため、それらを使用しない場合はビルドが失敗することを防ぐためのものです。
これらの変更により、GoのビルドシステムはC++コードをよりシームレスに統合できるようになり、GoとC++のハイブリッドプロジェクトの開発が容易になります。
コアとなるコードの変更箇所
このコミットにおける主要なコード変更は以下のファイルに集中しています。
src/cmd/cgo/doc.go:cgoディレクティブのドキュメント更新。src/cmd/go/build.go: ビルドロジックの変更、C++ファイルのコンパイル処理、新しいヘルパー関数の追加。src/cmd/go/doc.go:go docコマンドで表示されるパッケージ情報の構造体定義の更新。src/cmd/go/list.go:go listコマンドで表示されるパッケージ情報の構造体定義の更新。src/cmd/go/pkg.go:Package構造体の定義変更、C++ファイル関連フィールドの追加。src/cmd/godoc/index.go:godocが認識するファイル拡張子のホワイトリスト更新。src/pkg/go/build/build.go:go/buildパッケージのPackage構造体定義変更、ファイル認識ロジックの更新。
具体的な変更点と行数は以下の通りです。
src/cmd/cgo/doc.go:CFLAGSとLDFLAGSに加えて、CPPFLAGS,CXXFLAGSが#cgoディレクティブで利用可能になったことを明記。pkg-configがCFLAGSではなくCPPFLAGSを修正するように変更されたことを明記。- 環境変数
CGO_CPPFLAGS,CGO_CXXFLAGSの追加を明記。
src/cmd/go/build.go:fileExtSplitヘルパー関数の追加: ファイル名と拡張子を分離する。build関数内で、C++ファイルが存在するがcgoもSWIGも使用していない場合にエラーを返すロジックを追加。cgo呼び出し時にa.p.CXXFilesを渡すように変更。HFilesの処理において、ファイル名と拡張子を分離して処理するように変更。gc関数で、textFilesの計算にlen(p.CXXFiles)を追加。gcc関数をccompileを呼び出すように変更。gxx関数の追加:g++を使用してC++ファイルをコンパイルする。ccompile関数の追加: CまたはC++コンパイラを実行する汎用関数。gccld関数で、C++ファイルが存在する場合はgxxCmdを使用するように変更。gxxCmd関数の追加:g++コマンドラインプレフィックスを返す。ccompilerCmd関数の追加: 環境変数とデフォルトコマンドに基づいてコンパイラコマンドラインプレフィックスを返す汎用関数。cgo関数内で、CGO_CPPFLAGS,CGO_CXXFLAGS環境変数を考慮するように変更。pkg-configの出力がcgoCFLAGSではなくcgoCPPFLAGSに追加されるように変更。cgoCFLAGSではなくcgoCPPFLAGSが-Iオプションに追加されるように変更。cgoコマンド呼び出し時にcgoCPPFLAGSを渡すように変更。- Cファイルのコンパイル時に
cgoCFLAGSではなくcflags(cgoCPPFLAGSとcgoCFLAGSを結合したもの)を使用するように変更。 - C++ファイルのコンパイルロジックを追加し、
gxx関数とcxxflags(cgoCPPFLAGSとcgoCXXFLAGSを結合したもの)を使用。
src/cmd/go/doc.go:Package構造体にCXXFilesフィールドを追加。HFilesフィールドのコメントを更新し、.hh,.hpp,.hxxを含むことを明記。CgoCPPFLAGS,CgoCXXFLAGSフィールドをCgo directivesセクションに追加。
src/cmd/go/list.go:Package構造体にCXXFilesフィールドを追加。HFilesフィールドのコメントを更新し、.hh,.hpp,.hxxを含むことを明記。CgoCPPFLAGS,CgoCXXFLAGSフィールドをCgo directivesセクションに追加。
src/cmd/go/pkg.go:Package構造体にCXXFilesフィールドを追加。HFilesフィールドのコメントを更新し、.hh,.hpp,.hxxを含むことを明記。CgoCPPFLAGS,CgoCXXFLAGSフィールドをCgo directivesセクションに追加。copyBuild関数で、CXXFiles,CgoCPPFLAGS,CgoCXXFLAGSをコピーするように変更。load関数で、CXXFilesをロードするように変更。usesCgoヘルパー関数の追加。isStale関数で、srcsのリストにp.CXXFilesを追加。
src/cmd/godoc/index.go:whitelistedマップに.cc,.cpp,.cxx,.hh,.hpp,.hxxを追加し、godocがこれらのファイルを認識するように変更。
src/pkg/go/build/build.go:Package構造体にCXXFilesフィールドを追加。HFilesフィールドのコメントを更新し、.hh,.hpp,.hxxを含むことを明記。CgoCPPFLAGS,CgoCXXFLAGSフィールドをCgo directivesセクションに追加。readDir関数で、.cc,.cpp,.cxx,.hh,.hpp,.hxxを認識するように変更。saveCgo関数で、CPPFLAGSとCXXFLAGSディレクティブを処理するように変更。
コアとなるコードの解説
src/cmd/go/build.go
このファイルはGoのビルドロジックの核心であり、C++サポートの大部分がここに実装されています。
-
func fileExtSplit(file string) (name, ext string): この新しいヘルパー関数は、ファイル名から拡張子を安全に分離するために導入されました。これにより、HFilesの処理など、ファイル名から拡張子を除いた部分を操作する際に、より堅牢な処理が可能になります。 -
C++ファイル存在チェック (
build関数内):if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() { return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG", a.p.ImportPath, strings.Join(a.p.CXXFiles, ",")) }このコードは、GoパッケージにC++ファイルが含まれているにもかかわらず、
cgoもSWIGも使用していない場合にビルドエラーを発生させます。これは、Goの標準ビルドツールがC++ファイルを直接コンパイルする機能を持たず、cgoまたはSWIGを介して外部のC++コンパイラ(g++など)に処理を委ねる必要があるためです。このチェックにより、誤った設定でのビルドを防ぎ、ユーザーに適切なガイダンスを提供します。 -
cgo呼び出しの変更:outGo, outObj, err := b.cgo(a.p, cgoExe, obj, gccfiles, a.p.CXXFiles)b.cgo関数(cgoツールを実行するGoの内部関数)の呼び出しに、新しく認識されたa.p.CXXFiles(C++ファイルのリスト)が追加されました。これにより、cgoはCファイルだけでなくC++ファイルも処理対象として認識し、適切なコンパイラに渡すことができるようになります。 -
HFilesの処理の変更:name, ext := fileExtSplit(file) // ... targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + extHFiles(ヘッダーファイル)のコピー処理において、ファイル名から拡張子を分離するfileExtSplitが使用されるようになりました。これにより、.hだけでなく、.hh,.hpp,.hxxといったC++ヘッダーファイルも、OSやアーキテクチャ固有の命名規則に従って適切にコピーされるようになります。 -
C/C++コンパイラの抽象化と
gxxの導入:func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error { return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir)) } func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error { return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir)) } func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error { file = mkAbs(p.Dir, file) return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file) }Cファイルのコンパイルを担当していた
gcc関数が、汎用的なccompile関数を呼び出すように変更されました。そして、C++ファイルをコンパイルするための新しいgxx関数が追加され、これもccompileを呼び出します。ccompileは、渡されたcompilerコマンド(gccまたはg++)を使用して、指定されたソースファイルをオブジェクトファイルにコンパイルします。これにより、CとC++のコンパイルロジックが共通化され、コードの重複が削減されました。 -
リンカの選択ロジックの変更 (
gccld関数内):if len(p.CXXFiles) > 0 { cmd = b.gxxCmd(p.Dir) } else { cmd = b.gccCmd(p.Dir) }リンカを実行する
gccld関数において、パッケージにC++ファイル(p.CXXFiles)が含まれている場合、リンカとしてg++(b.gxxCmd)を使用するように変更されました。C++ファイルが存在しない場合は、引き続きgcc(b.gccCmd)が使用されます。これは、C++コードを含むプロジェクトでは、C++標準ライブラリなどC++固有のライブラリをリンクするためにg++リンカが必要となるためです。 -
コンパイラコマンドの取得 (
ccompilerCmdの導入):func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string { compiler := strings.Fields(os.Getenv(envvar)) if len(compiler) == 0 { compiler = append(compiler, defcmd) } a := []string{compiler[0], "-I", objdir, "-g", "-O2"} a = append(a, compiler[1:]...) return a }gccCmdとgxxCmdが、共通のccompilerCmd関数を呼び出すように変更されました。この関数は、指定された環境変数(例:CCやCXX)からコンパイラコマンドを取得し、設定されていない場合はデフォルトのコマンド(gccやg++)を使用します。また、-I(インクルードパス)、-g(デバッグ情報)、-O2(最適化レベル)といった共通のフラグを自動的に追加します。 -
cgo関数におけるフラグ処理の強化:cgoCPPFLAGS := stringList(envList("CGO_CPPFLAGS"), p.CgoCPPFLAGS) cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.CgoCFLAGS) cgoCXXFLAGS := stringList(envList("CGO_CXXFLAGS"), p.CgoCXXFLAGS)cgo関数内で、CGO_CPPFLAGSとCGO_CXXFLAGSという新しい環境変数が考慮されるようになりました。これらの環境変数や#cgoディレクティブで指定されたフラグが、それぞれのコンパイラフラグリストに結合されます。if len(out) > 0 { cgoCPPFLAGS = append(cgoCPPFLAGS, strings.Fields(string(out))...) } // ... cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)pkg-configからの出力(--cflags)がcgoCFLAGSではなくcgoCPPFLAGSに追加されるように変更されました。また、_cgo_export.hなどの生成されたヘッダーファイルへのパス(-I obj)もcgoCPPFLAGSに追加されるようになりました。これにより、CとC++の両方のソースファイルが、pkg-configやcgoが生成するヘッダーファイルへのパスを適切に受け取れるようになります。cflags := stringList(cgoCPPFLAGS, cgoCFLAGS) // ... cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)Cファイルのコンパイルには
cgoCPPFLAGSとcgoCFLAGSを結合したcflagsが、C++ファイルのコンパイルにはcgoCPPFLAGSとcgoCXXFLAGSを結合したcxxflagsが使用されるようになりました。これにより、CとC++で共通のプリプロセッサフラグと、それぞれの言語固有のコンパイラフラグを適切に適用できます。for _, file := range gxxfiles { // ... if err := b.gxx(p, ofile, cxxflags, file); err != nil { return nil, nil, err } // ... }gxxfiles(C++ソースファイル)のリストをループ処理し、それぞれのファイルをgxx関数とcxxflagsを使用してコンパイルするロジックが追加されました。これにより、Goのビルドプロセス内でC++ファイルが実際にコンパイルされ、オブジェクトファイルが生成されるようになります。
src/cmd/go/pkg.go
このファイルはGoのパッケージ情報を定義するPackage構造体を含んでいます。
-
Package構造体へのCXXFilesフィールドの追加:type Package struct { // ... CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files // ... CgoCPPFLAGS []string `json:",omitempty"` // cgo: flags for C preprocessor CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler CgoCXXFLAGS []string `json:",omitempty"` // cgo: flags for C++ compiler CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names // ... }Package構造体にCXXFiles、CgoCPPFLAGS、CgoCXXFLAGSといった新しいフィールドが追加されました。これにより、GoのビルドシステムはC++ソースファイルやC++関連のコンパイラフラグをパッケージのメタデータとして保持し、管理できるようになります。HFilesのコメントも更新され、C++ヘッダーファイルも含まれることが明記されました。 -
usesCgo()関数の追加:func (p *Package) usesCgo() bool { return len(p.CgoFiles) > 0 }このヘルパー関数は、パッケージが
cgoを使用しているかどうかを簡潔に判断するために追加されました。これはcmd/go/build.goのC++ファイル存在チェックで使用されています。
src/pkg/go/build/build.go
このファイルはGoのビルドパッケージの低レベルな機能を提供します。
-
Package構造体へのフィールド追加:src/cmd/go/pkg.goと同様に、go/buildパッケージのPackage構造体にもCXXFiles、CgoCPPFLAGS、CgoCXXFLAGSフィールドが追加されました。これにより、Goのビルドシステム全体でC++関連の情報を一貫して扱えるようになります。 -
ファイル認識ロジックの更新:
switch ext { case ".go", ".c", ".cc", ".cxx", ".cpp", ".s", ".h", ".hh", ".hpp", ".hxx", ".S", ".swig", ".swigcxx": // tentatively okay - read to make sure // ... case ".cc", ".cpp", ".cxx": p.CXXFiles = append(p.CXXFiles, name) continue case ".h", ".hh", ".hpp", ".hxx": p.HFiles = append(p.HFiles, name) continuereadDir関数内のファイル拡張子認識ロジックが更新され、.cc,.cpp,.cxxがC++ソースファイルとして、.hh,.hpp,.hxxがヘッダーファイルとしてそれぞれCXXFilesおよびHFilesに分類されるようになりました。これにより、Goのビルドシステムはこれらのファイルを自動的に検出し、適切な処理を行うことができます。 -
saveCgo関数におけるCPPFLAGSとCXXFLAGSの処理:case "CPPFLAGS": di.CgoCPPFLAGS = append(di.CgoCPPFLAGS, args...) case "CXXFLAGS": di.CgoCXXFLAGS = append(di.CgoCXXFLAGS, args...)saveCgo関数は、Goソースファイルのプリアンブルにある#cgoディレクティブを解析し、対応するフラグをPackage構造体に保存します。この変更により、#cgo CPPFLAGS:と#cgo CXXFLAGS:ディレクティブが認識され、それぞれのフラグがCgoCPPFLAGSとCgoCXXFLAGSフィールドに格納されるようになりました。
これらの変更は、GoのビルドシステムがC++ファイルをGoパッケージの一部として認識し、適切なコンパイラとフラグを使用してコンパイル・リンクするための基盤を確立します。これにより、GoとC++の連携がよりシームレスになり、開発者は既存のC++コードベースをGoプロジェクトに統合しやすくなります。
関連リンク
- Go Command Documentation: https://go.dev/cmd/go/
- Go cgo Documentation: https://go.dev/cmd/cgo/
- Go build package documentation: https://go.dev/pkg/go/build/
- Original Go issue: https://github.com/golang/go/issues/1476 (このコミットが修正したIssue)
参考にした情報源リンク
- Go's
cgotool provides support for interoperability with C and, indirectly, with C++: https://reinkrul.nl/ - How Go supports C++ through
cgo: https://www.geeksforgeeks.org/go-cgo-cpp-support/ extern "C"linkage specification: https://stackoverflow.com/questions/1041866/what-is-the-effect-of-extern-c-in-ccgoand the Go build process: https://go.dev/blog/cgocgoandpkg-config: https://go.dev/blog/cgo-and-pkg-configCPPFLAGS,CFLAGS,CXXFLAGS,LDFLAGSincgo: https://github.io/golang/go/wiki/cgo- Go
CXXFiles: https://go.dev/src/cmd/go/pkg.go - Go
HFiles(CGO context): https://stackoverflow.com/questions/24800000/what-are-hfiles-in-go CGO_ENABLEDenvironment variable: https://go.dev/doc/install/source#environment