Go パッケージガイドライン
32ビット – CLR – クロス – Eclipse – Electron – Free Pascal – GNOME – Go – Haskell – Java – KDE – カーネル – Lisp – MinGW – Node.js – ノンフリー – OCaml – Perl – PHP – Python – R – Ruby – Rust – VCS – ウェブ – Wine
このドキュメントでは、Go の PKGBUILD の作成に関する標準とガイドラインについて説明します。
目次
一般的なガイドライン
パッケージの命名
パッケージが 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_CFLAGS と CGO_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}\"" \
.
Flag meaning
-buildmode=pieenables PIE compilation for binary harderning.-trimpathimportant for reproducible builds so full build paths and module paths are not embedded.-mod=readonlyensure the module files are not updated in any go actions.-modcacherwis not important, but it ensures that go modules creates a write-able path. Default is read-only.
Supporting debug packages
Enabling debug packages with source listing and proper symbol look ups require a few modifications to the default buildflags.
- Removal of
-trimpathto ensure source paths are rewritten in the binary - Include
-compressdwarf=falsein-ldflagsto ensure we can parse the DWARF headers as current tooling does not support compressed headers. - Ensure
-linkmode=externalas the internal linker go uses does not embed a build-id into the binary. - Include
GOPATH="${srcdir}"so makepkg can include the source code for all modules.
The above options should produce a debug package with proper detached symbols and source listings which can then be picked up by the debugger.
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
}