tvl-depot/nix/buildGo/README.md
Vincent Ambo 03bfe08e1d chore: Significantly restructure folder layout
This moves the various projects from "type-based" folders (such as
"services" or "tools") into more appropriate semantic folders (such as
"nix", "ops" or "web").

Deprecated projects (nixcon-demo & gotest) which only existed for
testing/demonstration purposes have been removed.

(Note: *all* builds are broken with this commit)
2019-12-20 20:18:41 +00:00

140 lines
5.2 KiB
Markdown

buildGo.nix
===========
This is an alternative [Nix][] build system for [Go][]. It supports building Go
libraries and programs, and even automatically generating Protobuf & gRPC
libraries.
*Note:* This will probably end up being folded into [Nixery][].
## Background
Most language-specific Nix tooling outsources the build to existing
language-specific build tooling, which essentially means that Nix ends up being
a wrapper around all sorts of external build systems.
However, systems like [Bazel][] take an alternative approach in which the
compiler is invoked directly and the composition of programs and libraries stays
within a single homogeneous build system.
Users don't need to learn per-language build systems and especially for
companies with large monorepo-setups ([like Google][]) this has huge
productivity impact.
This project is an attempt to prove that Nix can be used in a similar style to
build software directly, rather than shelling out to other build systems.
## Example
Given a program layout like this:
```
.
├── lib <-- some library component
│   ├── bar.go
│   └── foo.go
├── api.proto <-- gRPC API definition
├── main.go <-- program implementation
└── default.nix <-- build instructions
```
The contents of `default.nix` could look like this:
```nix
{ buildGo }:
let
api = buildGo.grpc {
name = "someapi";
proto = ./api.proto;
};
lib = buildGo.package {
name = "somelib";
srcs = [
./lib/bar.go
./lib/foo.go
];
};
in buildGo.program {
name = "my-program";
deps = [ api lib ];
srcs = [
./main.go
];
}
```
(If you don't know how to read Nix, check out [nix-1p][])
## Usage
`buildGo` exposes five different functions:
* `buildGo.program`: Build a Go binary out of the specified source files.
| parameter | type | use | required? |
|-----------|-------------------------|------------------------------------------------|-----------|
| `name` | `string` | Name of the program (and resulting executable) | yes |
| `srcs` | `list<path>` | List of paths to source files | yes |
| `deps` | `list<drv>` | List of dependencies (i.e. other Go libraries) | no |
| `x_defs` | `attrs<string, string>` | Attribute set of linker vars (i.e. `-X`-flags) | no |
* `buildGo.package`: Build a Go library out of the specified source files.
| parameter | type | use | required? |
|-----------|--------------|------------------------------------------------|-----------|
| `name` | `string` | Name of the library (and resulting executable) | yes |
| `srcs` | `list<path>` | List of paths to source files | yes |
| `deps` | `list<drv>` | List of dependencies (i.e. other Go libraries) | no |
| `path` | `string` | Go import path for the resulting library | no |
* `buildGo.external`: Build an externally defined Go library or program.
This function performs analysis on the supplied source code (which
can use the standard Go tooling layout) and creates a tree of all
the packages contained within.
This exists for compatibility with external libraries that were not
defined using buildGo.
| parameter | type | use | required? |
|-----------|----------------|-----------------------------------------------|-----------|
| `path` | `string` | Go import path for the resulting package | yes |
| `src` | `path` | Path to the source **directory** | yes |
| `deps` | `list<drv>` | List of dependencies (i.e. other Go packages) | no |
For some examples of how `buildGo.external` is used, check out
[`proto.nix`](./proto.nix).
* `buildGo.proto`: Build a Go library out of the specified Protobuf definition.
| parameter | type | use | required? |
|-------------|-------------|--------------------------------------------------|-----------|
| `name` | `string` | Name for the resulting library | yes |
| `proto` | `path` | Path to the Protobuf definition file | yes |
| `path` | `string` | Import path for the resulting Go library | no |
| `extraDeps` | `list<drv>` | Additional Go dependencies to add to the library | no |
* `buildGo.grpc`: Build a Go library out of the specified gRPC definition.
The parameters are identical to `buildGo.proto`.
## Current status
This project is work-in-progress. Crucially it is lacking the following features:
* feature flag parity with Bazel's Go rules
* documentation building
* test execution
There are still some open questions around how to structure some of those
features in Nix.
[Nix]: https://nixos.org/nix/
[Go]: https://golang.org/
[Nixery]: https://github.com/google/nixery
[Bazel]: https://bazel.build/
[like Google]: https://ai.google/research/pubs/pub45424
[nix-1p]: https://github.com/tazjin/nix-1p