To enable PIE compilation, we have relied on a patched version of the go
compiler which has been distributed as `go-pie` since around 2017. However, full
RELRO support for go binaries has been a bit back and forth the past years. With
some thing working, and other things don't.
With the release of Go 1.11 there was support for a general `GOFLAGS` variable
that lets us pass flags directly to the compiler. This email details what these
flags should be going forward.
Expected environment variables in PKGBUILDs:
export GOFLAGS="-buildmode=pie -trimpath -mod=vendor -modcacherw"
* `CGO_LDFLAGS` passes the proper `LDFLAGS` to the linker. This should enable
full RELRO when used in conjunction with `GOFLAGS`.
* `-buildmode=pie` is the proper way to enable PIE and replaces the `go-pie`
* `-trimpath` this is to achieve reproducible builds and remove PWD from the
* `-modcacherw` modules are downloaded to `$GOPATH/pkg/mod` and by default have
the permissions 444 for god knows why. If we want to run `makepkg -c` or `git
clean` we won't have the correct permissions. This is probably not a big
problem for repository packages, but it's a nice addition so they work as
Notice that `-mod=vendor` is also added to `GOFLAGS`. This will make sure we are
using the vendored dependencies in the project. If they are not present, please
ensure they are downloaded in the `prepare` function:
go mod vendor
If the project is *not* using Go 1.11 modules, missing `go.mod` and/or `go.sum`
in the project root, then disable it with `export GO111MODULE=off` and continue
with symlink hacks.
Some upstreams override these values for strange reasons in their `Makefile` and
build systems. You *need* to read over them and ensure this does not happen!
Clearly we shouldn't have to specify this in every PKGBUILD, so I have been
playing with a `pacman` patch that passes all of the variables. However I have
been struggling with debug support and figuring out that part of the flags, so
nothing have been upstreamed yet.
However this is only applicable to around 126 packages, so I guess it's fine? ¯\_(ツ)_/¯
# In conclusion...
If there are no objections to the New Way Of Doing Things™, I'll be updating the
package guidelines within the next week or two and drop the `go-pie` package
containing the patch. For the sake of compatibility, the `go` package will contain a
`replaces=('go-pie')`. I also expect people packaging go packages to follow the