Go: cmd/go: build fails if filename is provided

Created on 4 Aug 2018  路  8Comments  路  Source: golang/go

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

go1.11beta3

Does this issue reproduce with the latest release?

Doesn't repro on go1.10 or go1.11beta2

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

GOARCH="amd64"
GOOS="darwin"

What did you do?

Made single main.go hello world app with one line go.mod file
Ran go build -o bin/mod-test main.go

What did you expect to see?

Successful build

What did you see instead?

Build error:
build main: cannot find module for path main

If I run the build without the filename
go build -o bin/mod-test it works fine

This is a change from previous versions of Go.

FrozenDueToAge release-blocker

Most helpful comment

Not sure quite what's happening here, but it sounds like there has been a change in behavior. Re-opening.

All 8 comments

The go build command's arguments are interpreted only as packages, not files. You are asking to build the package "main.go", and there is no such package. See the output of "go help build", which begins:

usage: go build [-o output] [-i] [build flags] [packages]

Build compiles the packages named by the import paths,
along with their dependencies, but it does not install the results.

Our Makefiles have been building using the above syntax for years. I'll fix them up to be more correct.

This change in behavior, even though more correct, might want to be called out in the release notes. There may be other teams using go build incorrectly as well.

It also fails when using a package name

go build main
go: import "main": cannot find module providing package main

CC @bcmills

This works differently in module mode vs GOPATH mode

root@3a67ccb3e0d7:/go/src/mod-test# ls
main.go
root@3a67ccb3e0d7:/go/src/mod-test# cat main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello World.")
}
root@3a67ccb3e0d7:/go/src/mod-test# go build main.go       ## this works
root@3a67ccb3e0d7:/go/src/mod-test# go build main          ## fails
can't load package: package main: cannot find package "main" in any of:
    /usr/local/go/src/main (from $GOROOT)
    /go/src/main (from $GOPATH)

Not sure quite what's happening here, but it sounds like there has been a change in behavior. Re-opening.

Similarly executing go run main.go in a module directory results in errors:

$ go run main.go
build main: cannot find module for path main
$ go run main
go: import "main": cannot find module providing package main

However go run . works as expected.

This is a departure from previous documented behavior if we cannot specify a list of .go files to "go build".

The output of "go help build" continues:

If the arguments to build are a list of .go files, build treats
them as a list of source files specifying a single package.

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') ...

This has the same underlying cause as https://github.com/golang/go/issues/26722; so closing as a duplicate.

I've confirmed that the fix in https://go-review.googlesource.com/c/go/+/127796 for that issue fixes this case:

cd `mktemp -d`
export GOPATH=$(mktemp -d)
mkdir hello
cd hello
go mod init example.com/hello
cat <<EOD > main.go

package main

import "fmt"

func main() {
        fmt.Println("==========")
}
EOD
go build main.go
./main

gives:

==========

whereas on tip (5a720d229d5ebc2f8b599aa54a3d807a1d54365f) this fails.

Was this page helpful?
0 / 5 - 0 ratings