24

I'm playing with Google Go and I'm having fun (!), but I'm having some problems with package subsystem.

I'm running Go 1.0.1 on Mac OS X Lion. I've build also various single file programs without problems (I've also build a small webapp using html/templates without problems and it compiles and runs without any error).

I've defined a "reusable" package (even.go):

package even

func Even(i int) bool {
    return i % 2 == 0
}

func Odd(i int) bool {
    return i % 2 == 1
}

and a consumer program (useeven.go):

package main

import (
    "./even"
    "fmt"
)

func main() {
    a := 5
    b := 6

    fmt.Printf("%d is even %v?\n", a, even.Even(a))
    fmt.Printf("%d is odd %v?\n", b, even.Odd(b))
}

But when I compile the "library" using

go build even.go

I got nothing... No errors, no message... What happens?

How should I do this?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
gsscoder
  • 3,088
  • 4
  • 33
  • 49

4 Answers4

12

The answer to your question, "How should I do this?" is explained in How to Write Go Code. It's really pretty important stuff and worth taking a look at.

The behavior of go build might seem puzzling, but is actually conventional for command line programs--no output means that the program ran successfully. So what did it do? For that your answer is in go help build

... Otherwise build compiles the packages but discards the results, serving only as a check that the packages can be built.

What, you wanted more? Of course. "How to Write Go Code" explains good ways of doing this. For a quick fix to your program, I'll explain that the go command expects each package and each executable program to be in a separate directory. If you just make a directory called even, immediately under the location of useeven.go, and move even.go to it, then go run useeven.go should run just as you have it.

Kiana
  • 1,415
  • 11
  • 17
Sonia
  • 27,135
  • 8
  • 52
  • 54
  • 1
    I've created a directory called **even** and moved **even.go** inside. Now I can build and run the program. Then (for learn purpose) I've renamed **even** to **_even**. The executable still work but when I use `go run useeven.go` it fails. I think this an evidence that the **useeven** executable contains then module **even.go** embedded in its bin image. I always read docs before going to play code, but I'm new to this language and in this point docs (for me) are not really clear. Maybe that to obtain some some kind of _dynamic link_ at runtime, we need to `go install` the module. Is it right? – gsscoder May 02 '12 at 18:08
  • 2
    No. Currently anyway, Go programs are always statically linked and there is no way to have Go packages dynamically linked at run time. `go install` uses `GOPATH`, as explained in the docs, so that file system specifications like "./" can be avoided in import paths. – Sonia May 02 '12 at 18:22
  • OK, now this point is clear. Anyway I expect this language to grow. I found it very expressive, clear and synthetic. I hope that package library will grow to extend usage in more and more fields. – gsscoder May 03 '12 at 03:26
  • Links tend to die and while the answer contains some information, it doesn't actually answers the real question of how to build the package and get the compiled library file on the disk. – Eugene Mayevski 'Callback Feb 29 '20 at 10:58
5

go build only generates an output file when it builds a "single main package". If you want to output a file for your other package you should use go install. That will build and install that package to your pkgs directory.

Code Commander
  • 16,771
  • 8
  • 64
  • 65
2

As noted in a comment by the OP, go build and go run useeven.go work fine, once you put even.go in its own folder: ./even/even.go. There is a bit of Go magic in the ./ (in the import) that makes the "local package" build automatically without requiring it to be installed anywhere.

useeven/
├── even
│   └── even.go
└── useeven.go

If you wanted to make this work without the magic ./, then the library need to be installed. A quick-and-dirty way (at the risk of polluting your library namespace) of making this work for your project is to simply register the library's source location by using a symbolic link like so (in this example GOPATH is ~/go):

[ useeven ]
$ ln -s $(pwd)/even ~/go/src

Now when you build the program, it automatically performs a go get even to install an up-to-date version of your library.

Note that this doesn't make go install* work for the library, it just makes doing that unnecessary.


There are more idiomatic ways of doing this, if you're not in a hurry: How to import local packages in go?

Brent Bradburn
  • 51,587
  • 17
  • 154
  • 173
  • These tricks may be platform specific. I tested on Ubuntu 18.04. – Brent Bradburn May 07 '19 at 01:10
  • 2
    Somebody gave me some Go source today and I just wanted to get it running, but SO's best advice was to go read "How to Write Go Code". – Brent Bradburn May 07 '19 at 01:32
  • Note: `go run` manages packages differently than does `go build`: [`go run !(*_test).go`](https://stackoverflow.com/a/41479692/86967) – Brent Bradburn Aug 12 '19 at 21:23
  • There's probably some way to leverage `go mod init` as asked about here: [Can someone please dumb down go mod init for me? \[closed\]](https://stackoverflow.com/questions/67606062/can-someone-please-dumb-down-go-mod-init-for-me) – Brent Bradburn Nov 14 '22 at 03:28
  • Not to be missed: [How to run all .go files within current directory through the command line (multi file package)](https://stackoverflow.com/a/54095754/86967) – Brent Bradburn Nov 14 '22 at 03:33
  • To outsmart Go when using `go mod`: https://stackoverflow.com/a/58754175/86967. In short, you use the current module name rather than `.`. There are also some hints about building/installing, but I'm not sure that's necessary. – Brent Bradburn Apr 30 '23 at 05:20
0

The reason that output is not being generated here is because you're running the

go build even.go

command on the package and not the main go file. Doing so on the package will check for errors on the package, but because it's not a main with an output, no success messages will be generated. If there are issues with the package's contents, errors will be displayed, otherwise if it compiles fine there will be no output

Instead, you should run:

go build useeven.go

To create the binary, then to execute the binary and get output from the program:

./useeven