Writing go Ebuilds

From Gentoo Wiki
Jump to:navigation Jump to:search

This is a short reference, intended to be read alongside Basic guide to write Gentoo Ebuilds and the go-module.eclass documentation.

go-module eclass

If the software to be packaged has a file named go.mod in its top level directory, it uses modules and the ebuild should inherit this eclass.

Packaging the dependencies

Ebuilds using the go-module eclass are different from most other ebuilds, because they have to include every go dependency. With some luck, the project will have a vendor/ directory and no special action will be needed. If it doesn't, in the short-term, the dependencies will have to be packaged manually. But longer term, try to convince upstream to generate a tarball in CI.

Previously, go-module packages often used EGO_SUM, but that is deprecated and will not be covered here. The currently favored method is creating a vendor or dependency-tarball.

Write the ebuild like normal, inherit go-module and add the upstream tarball to SRC_URI. Then unpack the package and cd to the build directory:

user $cd "$(portageq get_repo_path / <repo name>)"/app-misc/foo
user $nano foo-1.ebuild
user $ebuild foo-1.ebuild unpack
user $cd /path/to/the/unpacked/source/foo-1

Vendor tarball

This method produces far smaller tarballs, but might not include everything needed to compile the package, especially if the dependencies compile C or C++ code:

user $go mod vendor
user $cd ..
user $tar --create --auto-compress --file foo-1-vendor.tar.xz foo-1/vendor

Upload the tarball somewhere and add it to SRC_URI.

Dependency tarball

If the package won't compile because the vendor tarball has not all dependencies, a dependency tarball is needed:

user $GOMODCACHE="${PWD}"/go-mod go mod download -modcacherw -x
user $tar --create --auto-compress --file foo-1-deps.tar.xz go-mod

Upload the tarball somewhere and add it to SRC_URI.

Uploading the tarball

Gentoo developers can put the generated tarballs into their devspace, but what about others?

  • For those having access to a web or FTP server, or a file hosting service, put it there. Make sure the file can be downloaded without having to solve a captcha or having a cookie set. The easiest way to test this is by downloading it with wget.
  • For those who have access to a git forge such as GitLab, Gitea, GitHub, … create an empty repository, add a new tag for each new version (named ${P}) and upload the tarballs to these ”releases“. Make sure that the host of the forge allows this usage.
  • An alternative approach when having access to a git forge is using a CI pipeline to automatically create and publish dependency tarballs. An example for automating this with the GitLab CI can be found here: https://gitlab.fem-net.de/gentoo/fem-overlay-vendored.

Compiling and installing

Since the go-module eclass doesn't implement src_compile() and src_install(), this must be done manually:

FILE foo-1.ebuildSimple implementation of the compile and install phases
…
src_compile() {
    ego build
}

src_install() {
    dobin foo

    default
}

Unbundling C/C++ libraries

One way to detect bundled C or C++ libraries is to create a vendor tarball instead of a dependency tarball, because the former does not include the C/C++ source code. If the build fails, there is a good chance one has been found. Determine the go package that caused the failure by studying the build log and look into its source code. Go uses #cgo statements in go files to set compiler commands. With luck, the author included a define to switch from compiling the library to using the system one:

FILE foo-1-unbundle-webp.patchExample patch for unbundling libwebp
--- a/vendor/github.com/bep/gowebp/internal/libwebp/a__cgo.go
+++ b/vendor/github.com/bep/gowebp/internal/libwebp/a__cgo.go
@@ -2,5 +2,6 @@

 package libwebp

-// #cgo linux LDFLAGS: -lm
+// #cgo linux LDFLAGS: -lm -lwebp
+// #cgo CFLAGS: -DLIBWEBP_NO_SRC
 import "C"
--
2.35.1

Licenses

Since Go programs are statically linked, it is important that the ebuild's LICENSE setting includes the licenses of all statically linked dependencies. So please make sure it is accurate. Use a utility like dev-go/go-licenses to extract this information.

See also