go build ./... will produce a binary of one and only one main package is found

153 views
Skip to first unread message

tapi...@gmail.com

unread,
Apr 19, 2021, 9:40:00 AM4/19/21
to golang-nuts
I often use "go build ./..." command to check if there are compilation errors. Before ./... included 2+ main packages but now only one. Then the behavior changes, I accidentally commit and push a 10M binary to the remote repository.

Is this a intended design?

tapi...@gmail.com

unread,
Apr 19, 2021, 9:40:33 AM4/19/21
to golang-nuts
Sorry, "of" should "if" in title.

Brian Candler

unread,
Apr 19, 2021, 10:59:33 AM4/19/21
to golang-nuts
In short, yes this is as intended, although somewhat obscure.  The documentation is here:

"When compiling a single main package, build writes the resulting executable to an output file named after the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe') or the source code directory ('go build unix/sam' writes 'sam' or 'sam.exe'). The '.exe' suffix is added when writing a Windows executable.

When compiling multiple packages or a single non-main package, build compiles the packages but discards the resulting object, serving only as a check that the packages can be built.

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."

For me I had the problem the other way: "go build ./..." was happily building the binary when there was only one main package, but stopped working when I added a second.  The solution for me was "go build -o . ./..."

Sorry but I don't know how to make go build with a single main package discard the output.  I'd be inclined to make use of .gitignore

tapi...@gmail.com

unread,
Apr 19, 2021, 11:36:14 AM4/19/21
to golang-nuts
Thanks for the information.

Personally, I think the behavior is hard to predict. The binary should be only produced when a single path is specified.

Amnon

unread,
Apr 20, 2021, 1:25:13 AM4/20/21
to golang-nuts
go build ./... does build you program. I think most people would be a bit surprised if it did
something other than build.

If you don't want to build your program, but just vet that they are syntactically correct
then maybe try something like

go vet ./...

Brian Candler

unread,
Apr 20, 2021, 3:08:02 AM4/20/21
to golang-nuts
I agree with the OP: it would be less surprising if "go build ./..." always did build and store the artefacts, and there were a separate flag to discard them.

Currently, "go build ./..." discards the build artefacts under certain conditions, see this example.

Manlio Perillo

unread,
Apr 20, 2021, 3:26:33 PM4/20/21
to golang-nuts
Il giorno martedì 20 aprile 2021 alle 09:08:02 UTC+2 Brian Candler ha scritto:
I agree with the OP: it would be less surprising if "go build ./..." always did build and store the artefacts, and there were a separate flag to discard them.

Currently, "go build ./..." discards the build artefacts under certain conditions, see this example.

You can discard build artifacts with `go build -o /dev/null ./...`.  This is not documented and works thanks to

Manlio 

Manlio Perillo

unread,
Apr 20, 2021, 3:28:56 PM4/20/21
to golang-nuts
And I notice only now that you can do `go build -o "" ./...`.

Manlio

Brian Candler

unread,
Apr 21, 2021, 3:07:23 AM4/21/21
to golang-nuts
On Tuesday, 20 April 2021 at 20:28:56 UTC+1 manlio....@gmail.com wrote:
And I notice only now that you can do `go build -o "" ./...`.


Testing with go 1.16.3 shows that it doesn't:

MacBook-Pro-4:simpletest $ ls
go.mod main.go
MacBook-Pro-4:simpletest $ go build -o "" ./...
MacBook-Pro-4:simpletest $ ls
go.mod main.go simpletest

However, -o /dev/null does work:

MacBook-Pro-4:simpletest $ rm simpletest
MacBook-Pro-4:simpletest $ go build -o /dev/null ./...
MacBook-Pro-4:simpletest $ ls
go.mod main.go

Manlio Perillo

unread,
Apr 21, 2021, 9:20:41 AM4/21/21
to golang-nuts
Il giorno mercoledì 21 aprile 2021 alle 09:07:23 UTC+2 Brian Candler ha scritto:
On Tuesday, 20 April 2021 at 20:28:56 UTC+1 manlio....@gmail.com wrote:
And I notice only now that you can do `go build -o "" ./...`.


No, sorry.  I was confused by the code that set `BuildO = ""` when it is equal to `os.DevNull`.
For some reasons I was assuming the default value of `BuildO` to be the current directory ".".

 
> [...]


Manlio 
Reply all
Reply to author
Forward
0 new messages