This page provides information on using Go in Chromium OS, including recommendations for project organization, importing and managing third party packages, and writing ebuilds.

Recommended organization of code for Go projects in Chromium OS

Projects should generally follow the official recommendation to organize their Go workspaces: golang.org/doc/code.html
These are some additional recommendations and naming conventions for organizing Go project workspaces in Chromium OS:

If the Go project is in its own git repository, it should be set up such that the root of the repository is a workspace.

It should have a single directory path "src/<project name>/" at the top level of the repository.

This way, import paths for packages in the project always begin with "<project name>/".

If the project provides useful Go library packages for other projects to import, put all such packages under "src/chromiumos/".

Bundling related packages together in a self contained group installed by a single ebuild can make project dependencies simpler.

Use common sense and judgement. Resist monolithic ebuilds that install dozens of packages from as many repositories. On the other extreme, do not write separate ebuilds to install different packages from the same repository.

Setting up ebuilds for Chromium OS Go projects

IMPORTANT: Never use "go get" from an ebuild. Instead, write ebuilds for external dependencies and let Portage make them available under "/usr/lib/gopath".

If a project is only providing common "chromiumos/" Go packages for use by other projects, its ebuild only needs to fetch and install the package files to "/usr/lib/gopath".

The seccomp package is located in "chromiumos/platform/go-seccomp" repo at "src/chromiumos/seccomp/".

This package can now be imported by other projects using

import "chromiumos/seccomp"

Note that a single ebuild can install multiple related packages inside "/usr/lib/gopath/src/chromiumos/...".

Also, multiple ebuilds can install packages inside "/usr/lib/gopath/src/chromiumos/..." as long as there's no conflict for package paths.

Use RDEPEND to add other ebuilds that provide dependencies that the packages in this ebuild import. This will ensure that those other dependencies are also made available and remain available as long as the packages from this ebuild are installed in "/usr/lib/gopath".

If the project needs to import packages from outside its own repository, list those dependencies in the DEPEND variable (but not in RDEPEND, as these are strictly build time only dependencies).

Always specify the binaries using "CROS_GO_BINARIES" variable. This will pick the correct compiler for cross-compiling, and invoke it with appropriate GOPATH and flags. (e.g. "emerge-daisy" will automatically use the arm cross-compiler, import packages from "/build/daisy/usr/lib/gopath", and build PIE binaries).

A single ebuild can install executable binaries, as well as provide Go packages for other projects to import.

For other Chromium OS Go projects, use "chromiumos-overlay/dev-go" only if it's a generic helper tool or utility for development. Otherwise, pick a more appropriate category and overlay for the project.

Useful functions and variables

Path to the Go workspace, default is "${S}". Set this variable if the workspace is not at the top of the repository. For example, if all Go packages in the repository are under "go/src/<project>", set this variable to "${S}/go".

CROS_GO_BINARIES

Go executable binaries to build and install. Package paths are relative to "${CROS_GO_WORKSPACE}/src". Each path must contain a package "main". The last component of the package path will become the name of the executable. The executable name can be overridden by appending a colon to the package path, followed by an alternate name. For example:

Go packages to install in "/usr/lib/gopath". Package paths are relative to "${CROS_GO_WORKSPACE}/src". Packages are installed in "/usr/lib/gopath" such that they can be imported later from Go code using the exact paths listed here. For example:

CROS_GO_PACKAGES=(
"github.com/golang/glog"
)

will install package files from "${CROS_GO_WORKSPACE}/src/github.com/golang/glog" to "/usr/lib/gopath/src/github.com/golang/glog" and other Go projects can use the package with

import "github.com/golang/glog"

CROS_GO_TEST

Go packages to test. Package paths are relative to "${CROS_GO_WORKSPACE}/src". Package tests are always built and run locally on host. Default is to test all packages in ${CROS_GO_WORKSPACE}.

cros_go

Wrapper function for invoking the Go tool from an ebuild. It provides the following functionality:

The correct cross-compiler is automatically detected and used. For example, when running "emerge-daisy", "armv7a-cros-linux-gnueabi-go" will be used to build Go packages and binaries.

The GOPATH variable is setup automatically. For example, when running "emerge-daisy", Go packages will be looked up in the local workspace, as well as in "/build/daisy/usr/lib/gopath".

When cross-compiling Go packages that use Cgo, the correct C/C++ cross-compilers for the target are automatically detected and used.

For most ebuilds, setting the CROS_GO_BINARIES variable should be enough to build and install Go binaries. Implementation of CROS_GO_BINARIES uses the cros_go wrapper internally.