Go パッケージガイドライン

提供: ArchWiki
2023年6月30日 (金) 03:54時点におけるKgx (トーク | 投稿記録)による版 (→‎デバッグパッケージのサポート: 翻訳を修正)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

このドキュメントでは、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" .

出力ディレクトリ

現在、プロジェクト内のすべての Go バイナリをビルドする方法はいくつかあります。

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

... は、コンパイラがディレクトリに再帰的に降りてすべてのバイナリを検索するための省略表現です。出力ディレクトリと組み合わせて使用​​し、すべてをビルドできます。

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

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

サンプル 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
}

パッケージ例