Skip to content

Compiling with modules and -trimpath records temp path in binary #28008

@fd0

Description

@fd0

What version of Go are you using (go version)?

go version go1.11.1 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/fd0/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/fd0/shared/work/go"
GOPROXY=""
GORACE=""
GOROOT="/home/fd0/sdk/go1.11.1"
GOTMPDIR=""
GOTOOLDIR="/home/fd0/sdk/go1.11.1/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build079176254=/tmp/go-build -gno-record-gcc-switches"

What did you do?

For restic we're trying hard to provide reproducible builds. Among others, we strip the path to the directory with the source code using -trimpath, this worked great for Go 1.10. Unfortunately, building restic with Go 1.11 with Modules leaves a rather strange temporary path to _gomod_.go (which seems to record the build versions) in the binary. I did not find a way to strip or remove this path, resulting in different binaries for most builds. The temporary path is also cached in the build cache, I'm not sure if that's a good or bad thing, as consecutive builds without changing the code embeds the same temporary path.

This issue is related to #16860

Minimal example:

unset GOPATH
export GO111MODULE=on

cd $(mktemp -d /tmp/go-temp-path-XXXXXX)

cat <<EOF >main.go
package main

import "fmt"

func main() {
       fmt.Println("example")
}
EOF

go mod init example

The resulting binary example contains the path to the source code, and there's a reference to _gomod_.go but without a path:

go build

strings example | egrep '(/tmp|_gomod_)'
_gomod_.go
/tmp/go-temp-path-yN4rfF/main.go

What did you expect to see?

Using -trimpath should remove the path to the code and not embed any new temporary paths:

go build -gcflags -trimpath=$PWD

strings example | grep /tmp

What did you see instead?

Using -trimpath removes the path to the code, but now the _gomod_.go is referenced with a temporary path:

go build -gcflags -trimpath=$PWD

strings example | grep /tmp
/tmp/go-build222692051/b001/_gomod_.go

Additional remarks

It does not matter which path is removed via -trimpath, the temporary path to _gomod_.go is embedded as soon as -trimpath is used, e.g.:

go build -gcflags -trimpath=/x

strings example | grep /tmp
/tmp/go-build425085084/b001/_gomod_.go

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.modules

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions