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: documentation of `go build` -o flag is misleading #36784

Open
perillo opened this issue Jan 26, 2020 · 9 comments
Open

cmd/go: documentation of `go build` -o flag is misleading #36784

perillo opened this issue Jan 26, 2020 · 9 comments

Comments

@perillo
Copy link

@perillo perillo commented Jan 26, 2020

The documentation of go build says:

The -o flag forces build to write the resulting executable or object
to the named output file or directory, instead of the default behavior described
in the last two paragraphs. If the named output is a directory that exists,
then any resulting executables will be written to that directory.

However an object is generated only if the -o flag specifies a file.

To make things more confusing, when I have a non main package in the project root and a main package in a sub-directory, go build -o file ./... reports:

go build: cannot write multiple packages to non-directory file
@ianlancetaylor ianlancetaylor changed the title go/cmd: documentation of `go build` -o flag is misleading cmd/go: documentation of `go build` -o flag is misleading Jan 26, 2020
@bcmills

This comment has been minimized.

Copy link
Member

@bcmills bcmills commented Jan 27, 2020

Emphasis mine:

If the named output is a directory that exists, then any resulting executables will be written to that directory.

go build -o dir ./... does not generate non non-executable objects because they are not executables.

go build -o file ./... does not write an executable to the file because it would be ambiguous, and if you know that there is only one executable you may as well request only that executable.

(CC @jayconrod @matloob)

@bcmills

This comment has been minimized.

Copy link
Member

@bcmills bcmills commented Jan 27, 2020

The -o dir functionality was added for #14295, and intended to address the use-cases there.

Could you describe the use-cases that led you to expect different behavior for these conditions? That might help us better tailor the documentation and/or behavior for those use-cases.

@bcmills bcmills added this to the Unplanned milestone Jan 27, 2020
@perillo

This comment has been minimized.

Copy link
Author

@perillo perillo commented Feb 1, 2020

It is just that the documentation and error message seems a bit inconsistent to me.
As an example cannot write multiple packages to non-directory file may means that multiple packages (objects) can be written to a directory.

However today I found a behavior that surprised me. In my Go projects I have a Makefile with the rule:

build:
	go build -o build ./...

I have to change the rule to go build ./... when there are no main packages, but today I notice that when I have both main a non main packages, the non main packages are not compiled (and discarded).

This is consistent with how go build behave, however I think it would be much more intuitive is go build -o build ./... will compile everything and write the resulting executables and/or object files to the build directory.

@bcmills

This comment has been minimized.

Copy link
Member

@bcmills bcmills commented Feb 3, 2020

I have to change the rule to go build ./... when there are no main packages

That probably should not be necessary. However, that is significantly different from the issue that you reported initially, which was that “an object is generated only if the -o flag specifies a file.”

@perillo

This comment has been minimized.

Copy link
Author

@perillo perillo commented Feb 5, 2020

Sorry, probably it was a _test.go file that contained an error and was ignored (as documented) by go build.

About the documentation, what do you think about changing

The -o flag forces build to write the resulting executable or object
to the named output file or directory, instead of the default behavior described
in the last two paragraphs. If the named output is a directory that exists,
then any resulting executables will be written to that directory.

to

The -o flag forces build to write the resulting executable or object
to the named output file, instead of the default behavior described
in the last two paragraphs. If the named output is a directory that exists,
then any resulting executables will be written to that directory.

From some tests, go build never writes an object file to a directory; you have to specify a file.

$ go build/ -o build ./pkg
go build: no main packages to build

Thanks.

@bcmills

This comment has been minimized.

Copy link
Member

@bcmills bcmills commented Feb 5, 2020

I would like the first clause of the sentence to be complete and accurate, since that is often the only part that folks read (especially when they're just skimming flag descriptions).

So I think we need to keep “directory” in that first clause, rather than deferring it to the next sentence.

@perillo

This comment has been minimized.

Copy link
Author

@perillo perillo commented Feb 5, 2020

I can't think of a good solution .
The problem is that go build treats main packages and non main packages differently.

If the -o flag is a file, go build will write both the executable or the archive to that file.

But if the -o flag is a directory, go build will not write the resulting archive to an output file (in the directory specified by the -o flag) named after the first source file or the source code directory, like with a main package.

@bcmills

This comment has been minimized.

Copy link
Member

@bcmills bcmills commented Feb 7, 2020

The problem is that go build treats main packages and non main packages differently.

That property is intentional: the use-case in #14295 is to be able to build all of the binaries in a given project, without the restrictions of GOBIN (which, at least according to our documentation, must be an absolute path).

So, can we step up a level? What is the concrete problem that you're trying to address where the behavior of the -o flag is causing trouble? (Maybe we can find a clearer way to address that use-case directly.)

@perillo

This comment has been minimized.

Copy link
Author

@perillo perillo commented Feb 7, 2020

The problem is the one I wrote in the issue title: documentation of go build -o flag is misleading, at least for me.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.