-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/go, cmd/distpack: build and run tools that are not necessary for builds as needed and don't include in binary distribution #71867
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
Comments
I agree with the overall goal of this issue, but I wanted to note that currently
Perhaps it is enough to rewrite the |
Does it need to change to |
@seankhliao if the path gets changed to point to a cached binary I guess that would also be fine, but that would be a pretty long and random path, and it wouldn't work if the cache isn't warm - for example if it gets cleaned up manually or after a few days. I would personally prefer the shorter form; it will reproduce the build faithfully as long as none of the inputs like the source code is changed. I don't have a strong opinion here, but @matloob personally, out of all the tools you list, I've only ever run
Could you clarify whether the source for these tools would still be shipped? That is, that the first invocation of e.g. If that's the case, wouldn't changing a tool's source code cause |
@mvdan The |
@mvdan Yes, to preserve the ability to run scripts produced by go build -x, we should list
Yes, the source for the tools would still be shipped in GOROOT. The invocation of the tool wouldn't download anything.
If we default to running a tool that's present in |
This proposal has been added to the active column of the proposals project |
Maybe I'm misunderstanding this, but isn't this true today, too? If I change the source to cmd/compile and run |
How much would this save in the download size (in particular, after compression)? At a glance, it looks like a fair amount, but it would be good to have some hard numbers. |
Looking at pkg/tool, it looks like there are a few more things we could leave out: covdata, dist, distpack. There are a few things that are involved in the build, but aren't required to build themselves: cgo, preprofile. And vet is only needed if you're running tests. |
Yes, it's the current behavior, but the behavior when the tool isn't installed is that we will build from source. So users might get surprised by the change in behavior between when a tool is installed in pkg/tool and when it isn't.
I measured a ~15M difference in the module zips that we use to download and run newer toolchains on darwin/arm64. I think I remember adding doc and zip increases the savings to ~17M, but I'd have to re-check that. |
Dist and distpack should already be removed from the distribution: https://cs.opensource.google/go/go/+/master:src/cmd/distpack/pack.go;l=172;drc=fc5073bc155545dde4856cccdfcbb31880d1eb66 I wasn't sure if we could include covdata because I think we cache its output together with the test output and I think it's a bit more tricky to make guarantees on it. On the other hand, we don't seem to include its toolid as part of the build so maybe I'm misreading it? We do include cgo's and preprofile's toolids (and also vet's) as part of the cache keys so if we want to run |
I can think of a use case that potentially can be impacted by this. Suppose some developer downloads a Go distribution, just wants to build binaries to ship to somewhere else, but doesn't run them locally. Previously they only needs to run downloaded binaries. Now with this proposal, if they also wants to, say, investigate some binary using objdump, they'd need to run a binary that is locally built. I can imagine in some environment (e.g. a corporate profile) it only allows binaries downloaded from trusted sources (e.g. our macOS release binaries are signed) but not locally built binaries, or makes it difficult to do so. So they won't be able to easily run Would this be a problem? This is sort of a weird use case. Do people actually do this? |
That's fair. My sense is that this is fairly advanced usage, so maybe it doesn't matter much?
For reference: go1.24.2.darwin-arm64.tar.gz is 73MB, so this is roughly a 20% savings.
👍
Could we make this conditional on whether cgo is used/a PGO profile is present? IIUC, we don't use these tools otherwise. These sorts of details certainly don't have to hold up the proposal. |
Yeah, I think it's unlikely a user will
Currently the toolid is only included in the action id for an action that uses the tool (for example the preprofile tool id is included in the pgoActionID but not for every action), so it is conditional on whether cgo is used or a pgo profile is present. |
Based on the discussion above, this proposal seems like a likely accept. This proposal is to stop including tools that are not needed for builds in the binary distribution, with the goal of reducing the Go binary distribution size. Instead the tools would be built and run as needed by The install target for main packages in cmd will not change, so If a tool binary is present in that location, it will be run from there, but if not, the go command will fall back to building (if the tool binary isn't cached) and running the tool, similarly to how This is expected to reduce Go binary distribution size by ~20%. |
No change in consensus, so accepted. 🎉 This proposal is to stop including tools that are not needed for builds in the binary distribution, with the goal of reducing the Go binary distribution size. Instead the tools would be built and run as needed by The install target for main packages in cmd will not change, so If a tool binary is present in that location, it will be run from there, but if not, the go command will fall back to building (if the tool binary isn't cached) and running the tool, similarly to how This is expected to reduce Go binary distribution size by ~20%. |
Change https://go.dev/cl/666476 mentions this issue: |
Proposal Details
This proposal is to stop including tools that are not needed for builds in the binary distribution. Instead the tools would be built and run as needed by
go tool
using a similar mechanism to that used to build and run tools declared with atool
directive ingo.mod
. The goal of this proposal is to reduce the go binary distribution size.In cmd/distpack, we should be able to discard the following tools before packaging the binary distribution:
addr2line
,buildid
,nm
,objdump
,pprof
,test2json
, andtrace
. These tools do not seem to be invoked by the go command. We could go a little further and also removedoc
andfix
too because they are only invoked bygo doc
andgo fix
respectively.The install target for main packages in cmd will not change, so
go install
will continue to install binaries to$GOROOT/pkg/tool/$GOOS_$GOARCH
.If a tool binary is present in that location, it will be run from there, but if not, the go command will fall back to building (if the tool binary isn't cached) and running the tool, similarly to how
go tool
builds and runs tools declared with thetool
directive.Potential issues we should watch out for and which I would be interested in hearing feedback about:
go tool
to run it may be surprised that the tool that's run doesn't include their changes. So we may want to think a little more about what to do in that case.go test
andgo run
wouldn't work on either.cc @dmitshur
The text was updated successfully, but these errors were encountered: