Target audience: myself, professional developers.
This is probably quite a dull article; but I am summarising a lot of repetitious blog articles which omitted some data that I needed.
I do not know if it is considered better in prose to write “golang” or “go-lang”. For human to computer communication it is “go”.
Before I started using Golang; I was focussing on “how to type in this language”. When I started the project I suddenly realised I need to manage the build chain (à la C++ with UTF-8 and POSIX & win32 API). If I add threads to that problem spec; this is the sweet spot for Golang.
- For Ubuntu/Debian people, the OS doesn't prioritise new releases of Golang; but if you use
- As a general note, `go help X` will detail all options for X; like a poly-platform man page 3. The blog articles omit this point.
Compilation, files and build targets:
- When using `go build`, to get results, rather than validate; append a `-o $BIN_NAME`; or no binary file is made 4. Reading the `man` page gives you `go build -o /tmp/test1 -x -v -work ./...` to be abit more informative.
- When using the current version of goland; there is a small error in the default config; it sets -o twice [XXX]. This leads to files that can't be executed.
- As Golang is like another VM (see also Java); compiling any go native project to any platform supported by Go is trivial: in Bash set $GOOS and $GOARCH before running `go build` 5. With my current experience I am not aware of any single OS libraries in Go; but that statement is very limited scope. The other online examples seem to use `env`, which would save a sub-shell.
- NB for win32 users: Values match what Linux or python 6 uses (“amd64”, not “Azure”, “AMd64”, “Xbox Live™ " or something) .
- I tested linux/amd64 compiling for windows/amd64; which works on recent editions of windows without any fiddling at all. TODO: compat testing on a wider variety of machines.
- The build command `go build ./... ` can take a triple dot as a path quantifier to mean all the packages inside this base path 7.
- The default value for GOPATH is '~/go' on linux 8 9 10; and can be left as is, for many people
- Golang can build to blobs that seem like JAR files; and actual executable binaries. The “blobs” are technically Ar files, and can be unpacked/reviewed on any normal Linux server (I looked at the build artifact). An executable build in a PE2 or ELF file (etc for other OS) in normal fashion (I looked at the build artifacts).
- There is gccgo 11, but I haven't needed to use it.
- Golang binaries do not need a script host (see Java, ASP etc).
- The `go build` command includes the trace and debug data unless this is disabled. For applications which are considered stable adding -ldflags "-s” leads to smaller files 12
- If you are doing a manual build (i.e. no Make) use `go build -ldflags "-s” -o $RESULT_NAME $RELATIVEPATH_TO_FILE_WITH_MAIN()`. AFAIK, the main Package needs to link every other package (directly or indirectly), for Golang to be able to load the library.
- We want to target go1.5 or greater as the modules system is now complete. Notes 13 14. Golang defines modules as “A module is a collection of Go packages stored in a file tree with a go.mod file at its root. The go.mod file defines the module’s module path, which is also the import path used for the root directory, and its dependency requirements, which are the other modules needed for a successful build. Each dependency requirement is written as a module path and a specific semantic version." from 15. A worked example for golang modules 16.
- Go before go1.4, go is really keen on having all source in a single source root.
- Go after go1.4 adds support for modules, implying multi-homing for source code and adds $GOPATH. Current implementation of $GOPATH is weak, as not all features can read more than one directory in this variable. I hope this is enhanced in later versions.
- Go is painful for excess directories; whoever this can be managed with `go mod edit` 17.
- `go mod $BLAH` series of commands will be requirement for later versions of go; deprecating `go get $BLAH` 18.
- The main entry point must be in a package called 'main', and be a function called main 19 20 21.
- Those two statements do not talk about the file name; which is flexible.
- According to 22 the “main” package doesn't need to be in a directory called “main”; so it can be stored with the other Go files. My recent practical experience contradicts this. I make an extra “main” subpackage, to keep it out of the way.
- A range of package structures are outlined 23. I will update this point with which one is best.
- Golang files generally have .go as a suffix 24; I do not know if that is required anywhere.
- There is nearly a standard file system layout 25
- In a package, public symbols start with a capital letter; private ones do not 26 27.
- On my first simple test1; I did not run `go mod init`. I think for a more realistic and larger project with dependencies I will need to; and the previous build steps may need adjusting.
- On my second simple test2; I included a large middleware (iris 28); and things seem to work without attention.
- As of “time of print”; dependencies are added as source code via `go get $URL` 29 30. This (after go1.3) adds a line to go.mod file; secondly downloading the source code to a appropriately named sub-directory of $GOROOT.
- Dependencies can be removed via `go clean -i $URL` 31. I think this was added in `go1.3`.
- Dependencies can be upgraded with `go get -u $URL` 32.
- The `go get` command can be appended with GIT hashes or release tag names for greater precision 33 34.
- If a dependency is added before it is used; in go.mod it will be tagged with `/ /indirect` 35. Used dependencies (in the source code) are not.
- You can list/ verify dependencies with `go mod tidy -v`; to be able to reduce unneeded deps on your local disk 36 37.
- In the source files, dependencies are imported on the package level and using the keyword 'import' 38 39.
- The import can be an array or a scalar (which is better than most languages) 40. Much faster than Java as there is no need to specify each class. This can be tricky as C++ with many defines 41
- There is a compile constraint feature (like Pascal uses); this is written as a comment starting `// +build `. Some more detailed notes 42 43 44
- Notes on cross compilation 45
- The Golang supports alias 46 47; to be able to reference packages in a more convenient fashion.
- NB: just like Node, there is a high rate of change on quite a few projects.
- To support an CTO request; how-to link existing C++ code to a Golang runtime, a terse recipe: compile the C++ code as *SO, with exported symbols; put SO file in golang project root directory, with a *.syso suffix; add build-constraints to the go code to say load the external binary. This supports static and dynamic linking. Links: 48 49 50. Notes for run-time linking of the two binary formats 51
Preferred Source tree referencing 52
- situation: I have business objectives to make a small app; I have half of the features in existing libraries. I do not wish to upload non-compileable half typed code to git; but I need to do test builds.
- solution: I start a new project dir; I create sub modules/ directories as seems appropriate; in the very small sub module that holds main(), I create a vendor with `go mod vendor`; I create a symlink from the current project root dir to a new same name directory symlink in the system lib dir.
- This means I can test-compile/ and or build tests without uploading anything to the git server.
- On completion of the module; upload it to git; and delete local symlink
- Doing this needs a git ignore marker on the vendor directory.
- It is probably simplest to put the main() in the project root.
- A different solution is to have your own git server, and pull everything from there.