about summary refs log tree commit diff
path: root/nix/buildGo
diff options
context:
space:
mode:
Diffstat (limited to 'nix/buildGo')
-rw-r--r--nix/buildGo/README.md27
-rw-r--r--nix/buildGo/default.nix77
-rw-r--r--nix/buildGo/example/default.nix8
-rw-r--r--nix/buildGo/example/thing.proto10
-rw-r--r--nix/buildGo/external/default.nix5
-rw-r--r--nix/buildGo/external/main.go7
-rw-r--r--nix/buildGo/proto.nix87
7 files changed, 56 insertions, 165 deletions
diff --git a/nix/buildGo/README.md b/nix/buildGo/README.md
index 37e0c06933..e9667c039a 100644
--- a/nix/buildGo/README.md
+++ b/nix/buildGo/README.md
@@ -2,8 +2,7 @@ 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.
+libraries and programs.
 
 *Note:* This will probably end up being folded into [Nixery][].
 
@@ -33,7 +32,6 @@ 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
 ```
@@ -44,11 +42,6 @@ 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 = [
@@ -58,7 +51,7 @@ let
   };
 in buildGo.program {
   name = "my-program";
-  deps = [ api lib ];
+  deps = [ lib ];
 
   srcs = [
     ./main.go
@@ -105,22 +98,6 @@ in buildGo.program {
   | `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:
diff --git a/nix/buildGo/default.nix b/nix/buildGo/default.nix
index 92951b3cb2..c93642a127 100644
--- a/nix/buildGo/default.nix
+++ b/nix/buildGo/default.nix
@@ -22,7 +22,8 @@ let
     replaceStrings
     toString;
 
-  inherit (pkgs) lib go runCommand fetchFromGitHub protobuf symlinkJoin;
+  inherit (pkgs) lib runCommand fetchFromGitHub protobuf symlinkJoin go;
+  goStdlib = buildStdlib go;
 
   # Helpers for low-level Go compiler invocations
   spaceOut = lib.concatStringsSep " ";
@@ -41,8 +42,6 @@ let
 
   xFlags = x_defs: spaceOut (map (k: "-X ${k}=${x_defs."${k}"}") (attrNames x_defs));
 
-  pathToName = p: replaceStrings [ "/" ] [ "_" ] (toString p);
-
   # Add an `overrideGo` attribute to a function result that works
   # similar to `overrideAttrs`, but is used specifically for the
   # arguments passed to Go builders.
@@ -50,16 +49,52 @@ let
     overrideGo = new: makeOverridable f (orig // (new orig));
   };
 
+  buildStdlib = go: runCommand "go-stdlib-${go.version}"
+    {
+      nativeBuildInputs = [ go ];
+    } ''
+    HOME=$NIX_BUILD_TOP/home
+    mkdir $HOME
+
+    goroot="$(go env GOROOT)"
+    cp -R "$goroot/src" "$goroot/pkg" .
+
+    chmod -R +w .
+    GODEBUG=installgoroot=all GOROOT=$NIX_BUILD_TOP go install -v --trimpath std
+
+    mkdir $out
+    cp -r pkg/*_*/* $out
+
+    find $out -name '*.a' | while read -r ARCHIVE_FULL; do
+      ARCHIVE="''${ARCHIVE_FULL#"$out/"}"
+      PACKAGE="''${ARCHIVE%.a}"
+      echo "packagefile $PACKAGE=$ARCHIVE_FULL"
+    done > $out/importcfg
+  '';
+
+  importcfgCmd = { name, deps, out ? "importcfg" }: ''
+    echo "# nix buildGo ${name}" > "${out}"
+    cat "${goStdlib}/importcfg" >> "${out}"
+    ${lib.concatStringsSep "\n" (map (dep: ''
+      find "${dep}" -name '*.a' | while read -r pkgp; do
+        relpath="''${pkgp#"${dep}/"}"
+        pkgname="''${relpath%.a}"
+        echo "packagefile $pkgname=$pkgp"
+      done >> "${out}"
+    '') deps)}
+  '';
+
   # High-level build functions
 
   # Build a Go program out of the specified files and dependencies.
   program = { name, srcs, deps ? [ ], x_defs ? { } }:
     let uniqueDeps = allDeps (map (d: d.gopkg) deps);
     in runCommand name { } ''
-      ${go}/bin/go tool compile -o ${name}.a -trimpath=$PWD -trimpath=${go} ${includeSources uniqueDeps} ${spaceOut srcs}
+      ${importcfgCmd { inherit name; deps = uniqueDeps; }}
+      ${go}/bin/go tool compile -o ${name}.a -importcfg=importcfg -trimpath=$PWD -trimpath=${go} -p main ${includeSources uniqueDeps} ${spaceOut srcs}
       mkdir -p $out/bin
       export GOROOT_FINAL=go
-      ${go}/bin/go tool link -o $out/bin/${name} -buildid nix ${xFlags x_defs} ${includeLibs uniqueDeps} ${name}.a
+      ${go}/bin/go tool link -o $out/bin/${name} -importcfg=importcfg -buildid nix ${xFlags x_defs} ${includeLibs uniqueDeps} ${name}.a
     '';
 
   # Build a Go library assembled out of the specified files.
@@ -76,8 +111,8 @@ let
       # This is required for several popular packages (e.g. x/sys).
       ifAsm = do: lib.optionalString (sfiles != [ ]) do;
       asmBuild = ifAsm ''
-        ${go}/bin/go tool asm -trimpath $PWD -I $PWD -I ${go}/share/go/pkg/include -D GOOS_linux -D GOARCH_amd64 -gensymabis -o ./symabis ${spaceOut sfiles}
-        ${go}/bin/go tool asm -trimpath $PWD -I $PWD -I ${go}/share/go/pkg/include -D GOOS_linux -D GOARCH_amd64 -o ./asm.o ${spaceOut sfiles}
+        ${go}/bin/go tool asm -p ${path} -trimpath $PWD -I $PWD -I ${go}/share/go/pkg/include -D GOOS_linux -D GOARCH_amd64 -gensymabis -o ./symabis ${spaceOut sfiles}
+        ${go}/bin/go tool asm -p ${path} -trimpath $PWD -I $PWD -I ${go}/share/go/pkg/include -D GOOS_linux -D GOARCH_amd64 -o ./asm.o ${spaceOut sfiles}
       '';
       asmLink = ifAsm "-symabis ./symabis -asmhdr $out/go_asm.h";
       asmPack = ifAsm ''
@@ -88,7 +123,8 @@ let
         mkdir -p $out/${path}
         ${srcList path (map (s: "${s}") srcs)}
         ${asmBuild}
-        ${go}/bin/go tool compile -pack ${asmLink} -o $out/${path}.a -trimpath=$PWD -trimpath=${go} -p ${path} ${includeSources uniqueDeps} ${spaceOut srcs}
+        ${importcfgCmd { inherit name; deps = uniqueDeps; }}
+        ${go}/bin/go tool compile -pack ${asmLink} -o $out/${path}.a -importcfg=importcfg -trimpath=$PWD -trimpath=${go} -p ${path} ${includeSources uniqueDeps} ${spaceOut srcs}
         ${asmPack}
       '').overrideAttrs (_: {
         passthru = {
@@ -108,33 +144,14 @@ let
   # named "gopkg", and an attribute named "gobin" for binaries.
   external = import ./external { inherit pkgs program package; };
 
-  # Import support libraries needed for protobuf & gRPC support
-  protoLibs = import ./proto.nix {
-    inherit external;
-  };
-
-  # Build a Go library out of the specified protobuf definition.
-  proto = { name, proto, path ? name, goPackage ? name, extraDeps ? [ ] }: (makeOverridable package) {
-    inherit name path;
-    deps = [ protoLibs.goProto.proto.gopkg ] ++ extraDeps;
-    srcs = lib.singleton (runCommand "goproto-${name}.pb.go" { } ''
-      cp ${proto} ${baseNameOf proto}
-      ${protobuf}/bin/protoc --plugin=${protoLibs.goProto.protoc-gen-go.gopkg}/bin/protoc-gen-go \
-        --go_out=plugins=grpc,import_path=${baseNameOf path}:. ${baseNameOf proto}
-      mv ./${goPackage}/*.pb.go $out
-    '');
-  };
-
-  # Build a Go library out of the specified gRPC definition.
-  grpc = args: proto (args // { extraDeps = [ protoLibs.goGrpc.gopkg ]; });
-
 in
 {
   # Only the high-level builder functions are exposed, but made
   # overrideable.
   program = makeOverridable program;
   package = makeOverridable package;
-  proto = makeOverridable proto;
-  grpc = makeOverridable grpc;
   external = makeOverridable external;
+
+  # re-expose the Go version used
+  inherit go;
 }
diff --git a/nix/buildGo/example/default.nix b/nix/buildGo/example/default.nix
index 08da075e18..6756bf39e2 100644
--- a/nix/buildGo/example/default.nix
+++ b/nix/buildGo/example/default.nix
@@ -19,13 +19,6 @@ let
     ];
   };
 
-  # Example use of buildGo.proto, which generates a Go library from a
-  # Protobuf definition file.
-  exampleProto = buildGo.proto {
-    name = "exampleproto";
-    proto = ./thing.proto;
-  };
-
   # Example use of buildGo.program, which builds an executable using
   # the specified name and dependencies (which in turn must have been
   # created via buildGo.package etc.)
@@ -39,7 +32,6 @@ buildGo.program {
 
   deps = [
     examplePackage
-    exampleProto
   ];
 
   x_defs = {
diff --git a/nix/buildGo/example/thing.proto b/nix/buildGo/example/thing.proto
deleted file mode 100644
index 0f6d6575e0..0000000000
--- a/nix/buildGo/example/thing.proto
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2019 Google LLC.
-// SPDX-License-Identifier: Apache-2.0
-
-syntax = "proto3";
-package example;
-
-message Thing {
-  string id = 1;
-  string kind_of_thing = 2;
-}
diff --git a/nix/buildGo/external/default.nix b/nix/buildGo/external/default.nix
index f713783a58..42592c67e4 100644
--- a/nix/buildGo/external/default.nix
+++ b/nix/buildGo/external/default.nix
@@ -13,6 +13,7 @@ let
     readFile
     replaceStrings
     tail
+    unsafeDiscardStringContext
     throw;
 
   inherit (pkgs) lib runCommand go jq ripgrep;
@@ -102,7 +103,9 @@ let
   analysisOutput = runCommand "${name}-structure.json" { } ''
     ${analyser}/bin/analyser -path ${path} -source ${src} > $out
   '';
-  analysis = fromJSON (readFile analysisOutput);
+  # readFile adds the references of the read in file to the string context for
+  # Nix >= 2.6 which would break the attribute set construction in fromJSON
+  analysis = fromJSON (unsafeDiscardStringContext (readFile analysisOutput));
 in
 lib.fix (self: foldl' lib.recursiveUpdate { } (
   map (entry: mkset entry.locator (toPackage self src path depMap entry)) analysis
diff --git a/nix/buildGo/external/main.go b/nix/buildGo/external/main.go
index a77c43b371..4402a8eb86 100644
--- a/nix/buildGo/external/main.go
+++ b/nix/buildGo/external/main.go
@@ -10,7 +10,6 @@ import (
 	"flag"
 	"fmt"
 	"go/build"
-	"io/ioutil"
 	"log"
 	"os"
 	"path"
@@ -74,8 +73,8 @@ func findGoDirs(at string) ([]string, error) {
 	}
 
 	goDirs := []string{}
-	for k, _ := range dirSet {
-		goDirs = append(goDirs, k)
+	for goDir := range dirSet {
+		goDirs = append(goDirs, goDir)
 	}
 
 	return goDirs, nil
@@ -148,7 +147,7 @@ func analysePackage(root, source, importpath string, stdlib map[string]bool) (pk
 }
 
 func loadStdlibPkgs(from string) (pkgs map[string]bool, err error) {
-	f, err := ioutil.ReadFile(from)
+	f, err := os.ReadFile(from)
 	if err != nil {
 		return
 	}
diff --git a/nix/buildGo/proto.nix b/nix/buildGo/proto.nix
deleted file mode 100644
index 6c37f758ce..0000000000
--- a/nix/buildGo/proto.nix
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright 2019 Google LLC.
-# SPDX-License-Identifier: Apache-2.0
-#
-# This file provides derivations for the dependencies of a gRPC
-# service in Go.
-
-{ external }:
-
-let
-  inherit (builtins) fetchGit map;
-in
-rec {
-  goProto = external {
-    path = "github.com/golang/protobuf";
-    src = fetchGit {
-      url = "https://github.com/golang/protobuf";
-      rev = "ed6926b37a637426117ccab59282c3839528a700";
-    };
-  };
-
-  xnet = external {
-    path = "golang.org/x/net";
-
-    src = fetchGit {
-      url = "https://go.googlesource.com/net";
-      rev = "ffdde105785063a81acd95bdf89ea53f6e0aac2d";
-    };
-
-    deps = [
-      xtext.secure.bidirule
-      xtext.unicode.bidi
-      xtext.unicode.norm
-    ];
-  };
-
-  xsys = external {
-    path = "golang.org/x/sys";
-    src = fetchGit {
-      url = "https://go.googlesource.com/sys";
-      rev = "bd437916bb0eb726b873ee8e9b2dcf212d32e2fd";
-    };
-  };
-
-  xtext = external {
-    path = "golang.org/x/text";
-    src = fetchGit {
-      url = "https://go.googlesource.com/text";
-      rev = "cbf43d21aaebfdfeb81d91a5f444d13a3046e686";
-    };
-  };
-
-  genproto = external {
-    path = "google.golang.org/genproto";
-    src = fetchGit {
-      url = "https://github.com/google/go-genproto";
-      # necessary because https://github.com/NixOS/nix/issues/1923
-      ref = "main";
-      rev = "83cc0476cb11ea0da33dacd4c6354ab192de6fe6";
-    };
-
-    deps = with goProto; [
-      proto
-      ptypes.any
-    ];
-  };
-
-  goGrpc = external {
-    path = "google.golang.org/grpc";
-    deps = ([
-      xnet.trace
-      xnet.http2
-      xsys.unix
-      xnet.http2.hpack
-      genproto.googleapis.rpc.status
-    ] ++ (with goProto; [
-      proto
-      ptypes
-      ptypes.duration
-      ptypes.timestamp
-    ]));
-
-    src = fetchGit {
-      url = "https://github.com/grpc/grpc-go";
-      rev = "d8e3da36ac481ef00e510ca119f6b68177713689";
-    };
-  };
-}