140 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			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                            | 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
 |