Rules of Go-Lang Packaging
Posted: 2013-06-22
Based on experimentation and from looking at the language spec, I want to try to pin-down how Go packaging works.
Honestly, I haven’t found Go’s packaging and import mechanism that intuitive so far. It is possible that I’m just not viewing things right - maybe I’m too used to how things are done in languages like Python, Java and C++.
But it could also be I don’t have the full picture, because I’ve been reading the language spec, which leaves certain decisions open to the toolchain. The toolchain provides several commands for building and running (build
, install
, and run
), and several ways to specify what to build (by package, by file path or using wildcards).
So, here are the rules as far as I can tell.
For a library
- The name of the containing folder becomes the name of the binary library file. E.g. source files under a folder called
mystuff
are compiled intomystuff.a
. - The containing folder’s name and its path relative to
$GOPATH/src
form the package import-path. E.g. you would import themystuff
package asgithub.com/munckymagik/mystuff
, if this is the path to the.a
file relative to$GOPATH/pkg/<os>_<arch>
. - All source files within the package must declare the same package-name; but, this name does not need to be the same as the containing folder name. E.g. within the
mystuff
folder, I could use the package-namemystuffxxx
within the source files. Then in client code, I would still import the package asgithub.com/munckymagik/mystuff
, but I would refer to its symbols using the package-name, like:mystuffxxx.SymbolName
. However, the convention (unsurprisingly) is to use a package-name that matches the containing folder name. I see this more as an indication of how things are actually working under the hood. - The individual names of source files in the containing folder have no effect on the package name, how it’s imported, or how its symbols are resolved. The only reason to split a packages source into several files is to avoid having excessively large files. Nothing marked private within any of those files is private to any other file in the same folder!
For executables
- Source files that compile to executables must contain a
main()
function and must be declared in themain
package, regardless of what their folder path is relative to$GOPATH/src
. - An executable source file can be built, run or installed by specifying its folder path relative to
$GOPATH/src
. E.g.go install path/to/myexe
, in this case only one file within themyexe
folder may contain amain
function, otherwise go will report a “main redeclared” error. - An executable source file can be built or run directly using
go run path/to/myexe/filename.go
. In this case, many files within themyexe
folder may containmain
functions, go ignores the other files in the folder unless you list them on the command-line too. - Within a folder containing one or more executable source files, shared source code may be placed into separate files. These files must also be declared in the
main
package.
So folders are the unit-of-packaging and package names must match the containing folder names. Except for folders that contain executable main
files.