Go-Lang Packaging: Creating a Library that Bundles an Executable

Go is a lovely language, but the parts I have found hard to intuit are how to group source code and how to get it to build.

For my first project, what I wanted to do was create a library and bundle a front-end executable with it. The tutorial everyone refers to (http://golang.org/doc/code.html) gives an example of building a library and an exe as separate projects, which implies separate git repositories; not what I want.

Intuitively, my first attempt to was to try to put both types of source code into the same folder:

$GOPATH/src/
└── github.com
    └── munckymagik
        └── mystuff
            ├── frontend.go # contains "package main"
            └── libfile.go # contains "package mystuff"

No, good. Doesn’t work like this.

$ cd $GOPATH
$ go install github.com/munckymagik/mystuff
can't load package: package github.com/munckymagik/mystuff: found packages
mystuff (libfile.go) and main (frontend.go) in
/Users/daniel/Go/src/github.com/munckymagik/mystuff

You can’t mix package names within the same folder. Well, I say that but, Go’s own library contradicts this: some of the *_test.go source files have different package names to the sources they test, see example_test.go in the ‘sort’ package. I tried to do this same thing with no luck. I don’t yet know what’s going on there; I haven’t investigated.

Eventually, I found a description of the convention I need to use for my library: can-i-have-a-library-and-binary-with-the-same-name. You need to put the front-end source file into a different folder than the library, so you can simply put one or the other into a sub-folder. This works, and allows me to build the library and the executable in one step by building the executable:

$ cd $GOPATH/src
$ go install github.com/munckymagik/mystuff/mystuff
$ tree $GOPATH
/Users/daniel/Go
├── bin
│   └── mystuff
├── pkg
│   └── darwin_amd64
│       └── github.com
│           └── munckymagik
│               └── mystuff.a
└── src
    └── github.com
        └── munckymagik
            └── mystuff
                ├── libfile.go
                └── mystuff
                    └── frontend.go

Note that to build the executable I am referring to its containing folder. There are other ways to build the exe, but by doing it this way using go install, the binary is output to $GOPATH/bin, it takes the name of its containing folder, and I can run this command from any directory in the filesystem.