Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: -ldflags -X does not cause binary to be rebuilt #18369

Closed
james-lawrence opened this issue Dec 18, 2016 · 7 comments
Closed

cmd/go: -ldflags -X does not cause binary to be rebuilt #18369

james-lawrence opened this issue Dec 18, 2016 · 7 comments
Milestone

Comments

@james-lawrence
Copy link
Contributor

james-lawrence commented Dec 18, 2016

basically go install doesn't properly apply ldflags="-X ..." if nothing within the code has changed. I expected it to properly apply the -X values regardless.

This was very unexpected for me and caused a bit of confusion given if I had a previously built binary without flags and then tried with flags nothing happened.

related to #18246

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

go version go1.7.3 linux/amd64

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

go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/user/.golang/lib"
GORACE=""
GOROOT="/home/user/.golang/go"
GOTOOLDIR="/home/user/.golang/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build177725611=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"

What did you do?

go get bitbucket.org/jatone/gilo
cd $GOPATH/src/bitbucket.org/jatone/gilo
git checkout 0.2.3
mkdir bin
export GOBIN=$PWD/bin

What did you expect to see?

go install bitbucket.org/jatone/gilo/commands/...; ./bin/gilo --version
development
go install -ldflags="-X bitbucket.org/jatone/gilo.Version=$(git describe --tags)" bitbucket.org/jatone/gilo/commands/...; ./bin/gilo --version
0.2.3

What did you see instead?

go install bitbucket.org/jatone/gilo/commands/...; ./bin/gilo --version
development
go install -ldflags="-X bitbucket.org/jatone/gilo.Version=$(git describe --tags)" bitbucket.org/jatone/gilo/commands/...; ./bin/gilo --version
development

Work around

rm bin/*; go install bitbucket.org/jatone/gilo/commands/...; ./bin/gilo --version
development
rm bin/*; go install -ldflags="-X bitbucket.org/jatone/gilo.Version=$(git describe --tags)" bitbucket.org/jatone/gilo/commands/...; ./bin/gilo --version
0.2.3

output from go tool nm:

go tool nm bin/gilo | grep Version
744860 D bitbucket.org/jatone/gilo.Version
@josharian josharian changed the title inconsistant behaviour for cmd/go install and -ldflags cmd/go: -ldflags -X does not cause binary to be rebuilt Dec 19, 2016
@minux
Copy link
Member

minux commented Dec 19, 2016 via email

@ianlancetaylor
Copy link
Contributor

@minux Honest question: why are you concerned about excessive rebuilds? Do you think that people often build with different -gcflags and/or -ldflags and do not expect the specified programs to be rebuilt?

I think this would be easy enough to fix by adding -gcflags and -ldflags to the build ID, but, of course, we should make sure that is the right thing to do.

@gopherbot
Copy link

CL https://golang.org/cl/37384 mentions this issue.

@gopherbot
Copy link

CL https://golang.org/cl/37385 mentions this issue.

gopherbot pushed a commit that referenced this issue Feb 23, 2017
When set to false, the -dolinkobj flag instructs the compiler
not to generate or emit linker information.

This is handy when you need the compiler's export data,
e.g. for use with go/importer,
but you want to avoid the cost of full compilation.

This must be used with care, since the resulting
files are unusable for linking.

This CL interacts with #18369,
where adding gcflags and ldflags to buildid has been mooted.
On the one hand, adding gcflags would make safe use of this
flag easier, since if the full object files were needed,
a simple 'go install' would fix it.
On the other hand, this would mean that
'go install -gcflags=-dolinkobj=false' would rebuild the object files,
although any existing object files would probably suffice.

Change-Id: I8dc75ab5a40095c785c1a4d2260aeb63c4d10f73
Reviewed-on: https://go-review.googlesource.com/37384
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
gopherbot pushed a commit that referenced this issue Feb 23, 2017
When running on the host platform,
the standard library has almost certainly already been built.
However, all other platforms will probably need building.
Use the new -dolinkobj=false flag to cmd/compile
to only build the export data instead of doing a full compile.

Having partial object files could be confusing for people
doing subsequent cross-compiles, depending on what happens with #18369.
However, cmd/vet/all will mainly be run by builders
and core developers, who are probably fairly well-placed
to handle any such confusion.

This reduces the time on my machine for a cold run of
'go run main.go -all' by almost half:

benchmark           old ns/op        new ns/op        delta
BenchmarkVetAll     240670814551     130784517074     -45.66%

Change-Id: Ieb866ffb2cb714b361b0a6104077652f8eacd166
Reviewed-on: https://go-review.googlesource.com/37385
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@rsc
Copy link
Contributor

rsc commented Jun 22, 2017

Work on better caching will fix this. I have a prototype. Not for Go 1.9 but probably for Go 1.10.

@rsc rsc modified the milestones: Go1.10, Go1.9 Jun 22, 2017
@buchanae
Copy link
Contributor

I ran into this while adding versions to a cli tool. The best workaround I found was to run touch version/version.go && go install -ldflags etc..., which resulted in a ~2-3 second build time, as opposed to using go install -a which was ~12-15 seconds.

Looking forward to removing that workaround in Go 1.10 though.

One solution I previously tried was to put the version details in a version package with no imports/dependencies and run:

go install -a github.com/org/proj/version
go install github.com/org/proj

I thought the first go install would cache the result of the version package, and the second go install. It didn't seem to have that effect. Most likely I just don't understand how Go's build caching works.

@gopherbot
Copy link

Change https://golang.org/cl/73212 mentions this issue: cmd/go: switch to entirely content-based staleness determination

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants