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: build: add -buildmode=nolink flag #31710

Open
kevinburke opened this issue Apr 27, 2019 · 10 comments
Open

cmd/go: build: add -buildmode=nolink flag #31710

kevinburke opened this issue Apr 27, 2019 · 10 comments
Labels
FeatureRequest GoCommand cmd/go NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Proposal
Milestone

Comments

@kevinburke
Copy link
Contributor

kevinburke commented Apr 27, 2019

My understanding of the "go build" process is it does something like this:

  • Figure out all of the dependencies of the package.
  • For each dependency, determine whether it has changed since the last time it was built, by checking the .a file or equivalent in $GOPATH/pkg.
  • Compile them, in parallel if possible
  • Generate the new artifact (a .a file or similar) we checked in net: LookupHost is returning odd values and crashing net tests #2 that is now out of date.
  • Link them all into a single binary.

I use vim to edit Go files. The most popular plugin, vim-go, recommends checking compilation by running :GoBuild. I do this frequently to ensure I have syntax correct, imports correct, a working Go program.

:GoBuild changes directory to the directory containing the file you are editing, then runs

go build -tags '' . errors

It builds the "errors" package because vim-go desperately does not want to build any final artifacts, and attempting to build multiple packages turns off the binary building behavior.

However, I notice that this never takes advantage of build caching. That is, if I run :GoBuild and then run :GoBuild again immediately without making changes, it takes 4 seconds on the package I am compiling. If I run go build . to compile an artifact, it is much faster, about 600ms on the second run.

Is there a way to make "go build" take advantage of whatever intermediate build steps exist - the .a files from above, or their equivalents - even if it does not produce a final binary?

Alternatively, can you work with the vim-go maintainers to recommend a different tool for checking a package (and/or test package) contains valid Go syntax and identifiers?

@kevinburke
Copy link
Contributor Author

See also fatih/vim-go#2245.

@kevinburke
Copy link
Contributor Author

Another update, the slowness only reproduces when compiling a main package, otherwise it's fast.

@rsc
Copy link
Contributor

rsc commented Apr 30, 2019

This is taking advantage of build caching.
But the cache does not cache executables, so the link is happening (for package main), and that's what must be taking the time.
I feel like there's another open issue for a 'build without link' flag but I am not sure exactly where it is, so I retitled this one.
That's really what's needed here.

@rsc rsc added this to the Go1.14 milestone Apr 30, 2019
@rsc rsc changed the title cmd/go: can "go build" take advantage of build caching, even if it does not produce an artifact? cmd/go: build: add -buildmode=nolink flag Apr 30, 2019
@kevinburke
Copy link
Contributor Author

Ah, thanks Russ!

@bcmills bcmills added FeatureRequest NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels May 28, 2019
@rsc rsc modified the milestones: Go1.14, Backlog Oct 9, 2019
@qingyunha
Copy link
Contributor

Hi, Is this possibly be accepted, I am making a patch to implement this.

@zikaeroh
Copy link
Contributor

zikaeroh commented Jul 9, 2021

I'm not sure that this is really relevant anymore thanks to the proliferation of gopls; you don't need to manually compile your code anymore to know if it compiles if gopls is checking that, and can run :GoBuild when you actually want the binary.

@qingyunha
Copy link
Contributor

I'm not sure that this is really relevant anymore thanks to the proliferation of gopls; you don't need to manually compile your code anymore to know if it compiles if gopls is checking that, and can run :GoBuild when you actually want the binary.

Thank you @zikaeroh . I'm cursor how gopls do that,does it invoke go tool compile directly ?

@zikaeroh
Copy link
Contributor

zikaeroh commented Jul 9, 2021

It uses x/tools/go/packages (https://pkg.go.dev/golang.org/x/tools/go/packages), which internally calls the Go toolchain for info (without actually "building" binaries or anything).

@qingyunha
Copy link
Contributor

Seems x/tools/go/packages can't find compile errors.

@cherrymui
Copy link
Member

cherrymui commented Sep 12, 2023

I propose we allow -buildmode=archive for main packages.

  • For non-main packages (the default) -buildmode=archive already means "to compile the package".
  • For non-main packages it generates the .a and then throw it away (the default) or optionally keep it (with the -o flag).

We can just extend that to main packages as well, to mean "compile but not link", and optionally generate the .a file.

As a compiler/linker developer, from time to time I want the main.a file. Currently I have to do go build -x -work and dig it out from the work directory. It would be nice if I can just do go build -buildmode=archive -o main.a.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FeatureRequest GoCommand cmd/go NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Proposal
Projects
Status: Incoming
Development

No branches or pull requests

6 participants