`go build -trimpath` makes other arguments ignored in `debug.BuildInfo`
Description
go build -trimpath makes the -X ldflags disappear.
The runc build command from the Makefile looks like this:
GO_BUILD := $(GO) build -trimpath $(GO_BUILDMODE) \
$(EXTRA_FLAGS) -tags "$(BUILDTAGS)" \
-ldflags "$(LDFLAGS_COMMON) $(EXTRA_LDFLAGS)"
where LDFLAGS_COMMON is set here:
LDFLAGS_COMMON := -X main.gitCommit=$(COMMIT) -X main.version=$(VERSION)
While the provided information is really useful for running runc version, e.g.:
$./runc --version
runc version 1.1.0
commit: v1.1.0-0-g067aaf85
spec: 1.0.2-dev
go: go1.19.4
libseccomp: 2.5.4
(and I particular appreciate the go pseudo-version-compatible commit)
if you run with -trimpath, that information is not saved in debug.BuildInfo, making it harder to use standard tooling to extract it.
Here it is built without -trimpath:
$ go version -m runc
runc: go1.19.4
path github.com/opencontainers/runc
build -compiler=gc
build -ldflags="-X main.gitCommit=v1.1.0-578-g5cf9bb22 -X main.version=1.1.0+dev -linkmode external -extldflags -static-pie "
build -tags=seccomp,urfave_cli_no_docs,netgo,osusergo
build CGO_ENABLED=1
build CGO_CFLAGS=
build CGO_CPPFLAGS=
build CGO_CXXFLAGS=
build CGO_LDFLAGS=
build GOARCH=amd64
build GOOS=linux
build GOAMD64=v1
And the default with -trimpath:
runc: go1.19.4
path github.com/opencontainers/runc
build -compiler=gc
build -tags=seccomp,urfave_cli_no_docs,netgo,osusergo
build -trimpath=true
build CGO_ENABLED=1
build GOARCH=amd64
build GOOS=linux
build GOAMD64=v1
I think this would be good enough if -trimpath were optional, so builders can choose to select it or not.
Steps to reproduce the issue
- Run
make -n staticto get the build command - Run the provided build command
go version -m runc- Run the same build command, removing
-trimpath go version -m runc
Describe the results you received and expected
Expected debug.BuildInfo to include -X flags and other ldflags and build-time info.
It was missing.
What version of runc are you using?
Latest main HEAD as of today (commit 5cf9bb229feed19a767cbfdf9702f6487341e29e from Wed 14 June 2023). Tried much earlier versions, and with different versions of go as well. Same outcome.
Host OS information
NA
Host kernel information
NA
AFAIK there is no standard tooling to get the version information from the way we set versions in the resulting binary. Yes, the -ldflags "-X ..." thing is a common technique but the way this is done varies so much between projects that I'm not sure there are "standard" tools for getting this information programmatically. We officially only really support getting the version from actually running runc version (or runc features, which is explicitly defined by the OCI spec).
All of that being said, I don't mind making it something you can opt-out of but it should be made clear it's needed for reproducible builds. I thought we added -trimpath for reproducibility reasons (which it does help with, though we're missing -buildvcs=false which is needed in the most recent Go versions) but it was added in #2773 with somewhat limited reasoning. In any case, it is needed for reproducible builds in some cases.
Yeah, this is a longstanding issue of much debate at go. go install off of the net will use the version/pseudo-version and put it in debug.BuildInfo, go build will not, and will not let you override it. Because of that, lots of tools do read -X, like you said.
In any case, if you don't mind it being optional, I can open a PR for it that allows you to override it.
See #3908
Yeah, I find it quite strange that -trimpath does more than it says on the tin -- it seems to me that ldflags is something that really shouldn't be stripped when you're just requesting that Go doesn't include full file paths in the final binary... (But I guess the concern is that ldflags could contain paths if someone had a super wacky go build invocation.)
Although by that argument, there's all sorts of other areas it could strip. Maybe the value of -X foo.Bar=abcdefg should be stripped because abcdefg might be path specific.
I think it's a case of their being too smart by half. 😁