「Go パッケージガイドライン」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
69行目: 69行目:
 
{{Warning|ビルドフラグがコンパイラに正しく渡されたことを確認するのはパッケージャーの責任です。{{ic|Makefile}} がある場合はそれを読みます。}}
 
{{Warning|ビルドフラグがコンパイラに正しく渡されたことを確認するのはパッケージャーの責任です。{{ic|Makefile}} がある場合はそれを読みます。}}
   
  +
==== デバッグパッケージのサポート ====
==== Supporting debug packages ====
 
   
  +
ソースリストと適切なシンボルルックアップを使用してデバッグパッケージを有効にするには、デフォルトのビルドフラグをいくつか変更する必要があります。
Enabling debug packages with source listing and proper symbol look ups require a few modifications to the default buildflags.
 
   
  +
* ソースパスがバイナリで確実に書き換えられるようにするため、{{ic|-trimpath}} を削除
* Removal of {{ic|-trimpath}} to ensure source paths are rewritten in the binary
 
  +
* 現在のツールは圧縮ヘッダーをサポートしていないため、DWARF ヘッダーを確実に解析できるように、{{ic|1=-compressdwarf=false}} を {{ic|-ldflags}} に含めます。
* Include {{ic|1=-compressdwarf=false}} in {{ic|-ldflags}} to ensure we can parse the DWARF headers as current tooling does not support compressed headers.
 
  +
* Go が使用する内部リンカーとして {{ic|1=-linkmode=external}} がバイナリにビルド ID を埋め込まないようにしてください。
* Ensure {{ic|1=-linkmode=external}} as the internal linker go uses does not embed a build-id into the binary.
 
* Include {{ic|1=GOPATH="${srcdir}"}} so ''makepkg'' can include the source code for all modules.
+
* {{ic|1=GOPATH="${srcdir}"}} を含めると、''makepkg'' にすべてのモジュールのソースコードを含めることができます。
   
  +
上記のオプションは、デバッガーが選択できる、適切に分離されたシンボルとソースリストを含むデバッグパッケージを生成する必要があります。
The above options should produce a debug package with proper detached symbols and source listings which can then be picked up by the debugger.
 
   
 
{{bc|1=
 
{{bc|1=

2023年6月26日 (月) 21:59時点における版

このドキュメントでは、GoPKGBUILD の作成に関する標準とガイドラインについて説明します。

一般的なガイドライン

パッケージの命名

パッケージが Go エコシステムと強く結合したプログラムを提供する場合は、go-modulename を使用します。他のアプリケーションの場合は、プログラム名のみを使用します。

ノート: パッケージ名は完全に小文字にする必要があります


ビルド

依存関係

Go 1.11 では、go modules の初期サポートが導入されました。これにより、Go のアップストリームコードで依存関係を宣言し、特定のプロジェクトバージョンに固定できるようになります。現在、私たちのパッケージ化作業では、これをベンダー依存関係に利用しています。

Go モジュールを使用しないアップストリームプロジェクト

Go モジュールを使用しないアップストリームコードの場合は、次の回避策があります。アップストリームで問題を提出することを検討してください。

PKGBUILD
url=https://github.com/upstream_user/upstream_project

prepare() {
  cd "$pkgname-$pkgver"
  go mod init "${url#https://}" # strip https:// from canonical URL
  go mod tidy
}
ノート: このようなハッキングを行うと、パッケージのビルド間でモジュールが変更されるため、パッケージが再現できなくなります。

フラグとビルドオプション

go アプリケーション用に書かれたほとんどの Makefile は、GOFLAGS を上書きしたり、ビルドシステムが提供するビルドフラグを尊重していません。このため、コンパイラのために CGO_CFLAGSCGO_LDFLAGS が設定されている必要があるので、Go バイナリが RELRO でコンパイルされません。これを Makefile にパッチするか、Makefile を省略する必要があります。

export CGO_CPPFLAGS="${CPPFLAGS}"
export CGO_CFLAGS="${CFLAGS}"
export CGO_CXXFLAGS="${CXXFLAGS}"
export CGO_LDFLAGS="${LDFLAGS}"
export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw"

# or alternatively you can define some of these flags from the CLI options
go build \
    -trimpath \
    -buildmode=pie \
    -mod=readonly \
    -modcacherw \
    -ldflags "-linkmode external -extldflags \"${LDFLAGS}\"" \
    .

フラグの意味

  • -buildmode=pie バイナリ強化のために PIE コンパイル を有効にします。
  • -trimpath 再現性のあるビルド にとって重要であるため、完全なビルドパスとモジュールパスは埋め込まれません。
  • -mod=readonly どの go アクションでもモジュールファイルが更新されていないことを確認してください。
  • -modcacherw は重要ではありませんが、これにより go モジュールが書き込み可能なパスを作成することが保証されます。デフォルトは読み取り専用です。
ヒント: パッケージソースに modules.txt を含む vendor ディレクトリが含まれている場合、-mod フラグを次のように安全に変更できます。-mod=vendor.
警告: ビルドフラグがコンパイラに正しく渡されたことを確認するのはパッケージャーの責任です。Makefile がある場合はそれを読みます。

デバッグパッケージのサポート

ソースリストと適切なシンボルルックアップを使用してデバッグパッケージを有効にするには、デフォルトのビルドフラグをいくつか変更する必要があります。

  • ソースパスがバイナリで確実に書き換えられるようにするため、-trimpath を削除
  • 現在のツールは圧縮ヘッダーをサポートしていないため、DWARF ヘッダーを確実に解析できるように、-compressdwarf=false-ldflags に含めます。
  • Go が使用する内部リンカーとして -linkmode=external がバイナリにビルド ID を埋め込まないようにしてください。
  • GOPATH="${srcdir}" を含めると、makepkg にすべてのモジュールのソースコードを含めることができます。

上記のオプションは、デバッガーが選択できる、適切に分離されたシンボルとソースリストを含むデバッグパッケージを生成する必要があります。

export CGO_CPPFLAGS="${CPPFLAGS}"
export CGO_CFLAGS="${CFLAGS}"
export CGO_CXXFLAGS="${CXXFLAGS}"
export CGO_LDFLAGS="${LDFLAGS}"
export GOPATH="${srcdir}"
export GOFLAGS="-buildmode=pie -mod=readonly -modcacherw"

go build -ldflags "-compressdwarf=false -linkmode external" .

Output directory

There are currently a few ways to build all go binaries in a project.

build(){
    cd "$pkgname-$pkgver"
    go build -o output-binary .
}

... is a shorthand for the compiler to recursively descend into the directory and find all binaries. It can be used in conjunction with a output directory to build everything.

prepare(){
    cd "$pkgname-$pkgver"
    mkdir -p build
}

build(){
    cd "$pkgname-$pkgver"
    go build -o build ./cmd/...
}

Sample PKGBUILD

pkgname=foo
pkgver=0.0.1
pkgrel=1
pkgdesc='Go PKGBUILD Example'
arch=('x86_64')
url="https://example.org/$pkgname"
license=('GPL')
makedepends=('go')
source=("$url/$pkgname-$pkgver.tar.gz")
sha256sums=('1337deadbeef')

prepare(){
  cd "$pkgname-$pkgver"
  mkdir -p build/
}

build() {
  cd "$pkgname-$pkgver"
  export CGO_CPPFLAGS="${CPPFLAGS}"
  export CGO_CFLAGS="${CFLAGS}"
  export CGO_CXXFLAGS="${CXXFLAGS}"
  export CGO_LDFLAGS="${LDFLAGS}"
  export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw"
  go build -o build ./cmd/...
}

check() {
  cd "$pkgname-$pkgver"
  go test ./...
}

package() {
  cd "$pkgname-$pkgver"
  install -Dm755 build/$pkgname "$pkgdir"/usr/bin/$pkgname
}

Example packages