"go build" and "go run" are inconsistent

1,121 views
Skip to first unread message

anjan bacchu

unread,
Nov 7, 2014, 7:34:57 AM11/7/14
to golan...@googlegroups.com
All,

  I'm reviewing a book called "Go in action" from manning and learning go lang at the same time and found this issue(?).
I have a very simple app. When I "build" and then run the code, go doesn't complain. However, if I just try to run the code, go complains.

What am I missing ?

Thank you,

ABACCHU:test abacchu$ go version
go version go1.3.1 darwin/amd64
ABACCHU:test abacchu$ find .
.
./biz.go
./foo
./foo/search.go
./test
./test.go
ABACCHU:test abacchu$ cat test.go
package main

import "test/foo"


func main() {
     foo.Bar()
     Biz()
}ABACCHU:test abacchu$ cat biz.go
package main

import "fmt"

func Biz() {
     fmt.Println("from Biz() 2")
}
ABACCHU:test abacchu$ cat foo/search.go 
package foo

import "fmt"

func Bar() {
     fmt.Println("from bar");
}
ABACCHU:test abacchu$ go build
ABACCHU:test abacchu$ 
ABACCHU:test abacchu$ go run test.go
# command-line-arguments
./test.go:8: undefined: Biz
ABACCHU:test abacchu$ ./test
from bar
from Biz() 2
ABACCHU:test abacchu$ 


Jan Mercl

unread,
Nov 7, 2014, 7:44:04 AM11/7/14
to anjan bacchu, golang-nuts
On Fri, Nov 7, 2014 at 1:34 PM, anjan bacchu <anjan....@gmail.com> wrote:
> What am I missing ?

go run does not build, ie. it considers only files named as arguments.
go build transitively checks and, if necessary, recompiles and links
all dependencies. Cf:
http://golang.org/cmd/go/#hdr-Compile_and_run_Go_program

-j

Dave Cheney

unread,
Nov 7, 2014, 7:47:53 AM11/7/14
to golan...@googlegroups.com
Go run is the odd one out here, hopefully this post will give you some background into the difference.

http://dave.cheney.net/2014/01/21/using-go-test-build-and-install

Konstantin Khomoutov

unread,
Nov 7, 2014, 7:56:44 AM11/7/14
to anjan bacchu, golan...@googlegroups.com
On Fri, 7 Nov 2014 04:34:57 -0800 (PST)
anjan bacchu <anjan....@gmail.com> wrote:

> I'm reviewing a book called "Go in action" from manning and
> learning go lang at the same time and found this issue(?).
> I have a very simple app. When I "build" and then run the code, go
> doesn't complain. However, if I just try to run the code, go
> complains.
>
> What am I missing ?

This is by design. Please use the

go help {command}

to get quick help on particular commands.

From there (Go 1.3.2):

$ go help run
usage: go run [build flags] [-exec xprog] gofiles... [arguments...]

Run compiles and runs the main package comprising the named Go source
files. A Go source file is defined to be a file ending in a literal
".go" suffix.
...

$ go help build
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.
...

As you can see, `go run` expects a mandatory list of source code files,
all of which are supposed to comprise the package "main" ("meta"
package representing the "top-level" code and data of an executable)
while `go build` works on a much higher level and operates on a set of
packages, not files. This one is the chief reason of why it does not
run the produced executable: there may be many of them. For instance,
you can call `go build ./...` to build the whole hierarchy of packages
rooted in the current directory.

See also this recent thread [1] which touches on basically the same
issues and contains well put explanations from experienced folks.

1. https://groups.google.com/d/topic/golang-nuts/50wO63bZ7rc/discussion

anjan bacchu

unread,
Nov 7, 2014, 8:47:37 AM11/7/14
to golan...@googlegroups.com, anjan....@gmail.com
Hi Jan,

  Thank you.

  My issue is that if I import a file from a different package (test/foo), "go run test.go" works just fine. Only when I'm trying to reference a function/file in the same package(main), "go run test.go" is complaining. If indeed there is a compilation error, "go build" should not work.

Again, what am I missing ?

go run test.go

# command-line-arguments

./test.go:8: undefined: Biz

This seems to tell me there is some compilation/link error. However, if I run "go run test.go biz.go", then there are no complaints and it runs the code just fine. 
However, when I imported another package (test/foo), then there doesn't seem to be a requirement to say "go run test.go test/foo/Foo.go". I can just do "go run test.go" and it is able to run the code in the test/foo package.

Why is there an inconsistency (aka what am I not getting here ?)

BR,
~A

Jan Mercl

unread,
Nov 7, 2014, 9:03:08 AM11/7/14
to anjan bacchu, golang-nuts
On Fri, Nov 7, 2014 at 2:47 PM, anjan bacchu <anjan....@gmail.com> wrote:
> Again, what am I missing ?

If there's a package imported and installed in the $GOPATH/pkg cache,
it's used by the compiler automatically w/o need to name it. If some
file is not named when compiling a multi file package in a directory,
the compiler does not guess the file(s). Compare the outputs of go
build -x and go run -x <file list>. The go build should explicitly
name all non test .go files in the directory, while the go run command
you use probably does not.

-j
Reply all
Reply to author
Forward
0 new messages