No description
Find a file
Vincent Ambo fb4dd76146 feat(external): Implement tool to analyse external dependencies
Adds a tool that can analyse dependencies that were not originally
meant to be built with buildGo.nix and return information that can be
used to construct appropriate Nix dependencies.

The tool will return information about package-local and foreign
dependencies separately to let Nix determine whether all required
dependencies are provided and to correctly link together sub-packages.

To avoid listing standard library imports in the dependencies, a list
of all packages in the standard library is generated statically to
allow for those to be filtered out during the analysis.

This tool is still work-in-progress.
2019-12-13 00:39:53 +00:00
example feat(example): Demonstrate usage of x_defs flag to buildGo.program 2019-11-24 20:41:29 +00:00
external feat(external): Implement tool to analyse external dependencies 2019-12-13 00:39:53 +00:00
buildGo.nix feat(buildGo): Expose Go import path for packages 2019-12-13 00:39:53 +00:00
proto.nix feat(proto): Add protobuf & gRPC dependencies via external 2019-11-26 12:28:10 +00:00
README.md docs: Add README file that describes project usage & background 2019-11-27 15:14:43 +00:00

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:

{ 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 a Go library or program using standard go tooling.

    This exists for compatibility with complex external dependencies. In theory it is possible to write buildGo.package specifications for each subpackage of an external dependency, but it is often cumbersome to do so.

    parameter type use required?
    path string Go import path for the resulting library yes
    src path Path to the source directory yes
    deps list<drv> List of dependencies (i.e. other Go libraries) no
    srcOnly bool Only copy sources, do not perform a build. no
    targets list<string> Sub-packages to build (defaults to all) no

    For some examples of how buildGo.external is used, check out 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.