diff options
Diffstat (limited to 'nix/buildGo')
-rw-r--r-- | nix/buildGo/default.nix | 91 | ||||
-rw-r--r-- | nix/buildGo/example/default.nix | 5 | ||||
-rw-r--r-- | nix/buildGo/external/default.nix | 50 | ||||
-rw-r--r-- | nix/buildGo/proto.nix | 3 |
4 files changed, 84 insertions, 65 deletions
diff --git a/nix/buildGo/default.nix b/nix/buildGo/default.nix index a2396dc3f770..0126a93d1621 100644 --- a/nix/buildGo/default.nix +++ b/nix/buildGo/default.nix @@ -4,8 +4,9 @@ # buildGo provides Nix functions to build Go packages in the style of Bazel's # rules_go. -{ pkgs ? import <nixpkgs> {} -, ... }: +{ pkgs ? import <nixpkgs> { } +, ... +}: let inherit (builtins) @@ -40,7 +41,7 @@ let xFlags = x_defs: spaceOut (map (k: "-X ${k}=${x_defs."${k}"}") (attrNames x_defs)); - pathToName = p: replaceStrings ["/"] ["_"] (toString p); + pathToName = p: replaceStrings [ "/" ] [ "_" ] (toString p); # Add an `overrideGo` attribute to a function result that works # similar to `overrideAttrs`, but is used specifically for the @@ -52,49 +53,50 @@ let # 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} - 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 - ''; + 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} + 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 + ''; # Build a Go library assembled out of the specified files. # # This outputs both the sources and compiled binary, as both are # needed when downstream packages depend on it. - package = { name, srcs, deps ? [], path ? name, sfiles ? [] }: - let - uniqueDeps = allDeps (map (d: d.gopkg) deps); - - # The build steps below need to be executed conditionally for Go - # assembly if the analyser detected any *.s files. - # - # 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} - ''; - asmLink = ifAsm "-symabis ./symabis -asmhdr $out/go_asm.h"; - asmPack = ifAsm '' - ${go}/bin/go tool pack r $out/${path}.a ./asm.o - ''; - - gopkg = (runCommand "golib-${name}" {} '' - 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} - ${asmPack} - '') // { - inherit gopkg; - goDeps = uniqueDeps; - goImportPath = path; - }; - in gopkg; + package = { name, srcs, deps ? [ ], path ? name, sfiles ? [ ] }: + let + uniqueDeps = allDeps (map (d: d.gopkg) deps); + + # The build steps below need to be executed conditionally for Go + # assembly if the analyser detected any *.s files. + # + # 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} + ''; + asmLink = ifAsm "-symabis ./symabis -asmhdr $out/go_asm.h"; + asmPack = ifAsm '' + ${go}/bin/go tool pack r $out/${path}.a ./asm.o + ''; + + gopkg = (runCommand "golib-${name}" { } '' + 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} + ${asmPack} + '') // { + inherit gopkg; + goDeps = uniqueDeps; + goImportPath = path; + }; + in + gopkg; # Build a tree of Go libraries out of an external Go source # directory that follows the standard Go layout and was not built @@ -110,10 +112,10 @@ let }; # Build a Go library out of the specified protobuf definition. - proto = { name, proto, path ? name, goPackage ? name, extraDeps ? [] }: (makeOverridable package) { + 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" {} '' + 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} @@ -124,7 +126,8 @@ let # Build a Go library out of the specified gRPC definition. grpc = args: proto (args // { extraDeps = [ protoLibs.goGrpc.gopkg ]; }); -in { +in +{ # Only the high-level builder functions are exposed, but made # overrideable. program = makeOverridable program; diff --git a/nix/buildGo/example/default.nix b/nix/buildGo/example/default.nix index 99c0a7d79bd6..08da075e1818 100644 --- a/nix/buildGo/example/default.nix +++ b/nix/buildGo/example/default.nix @@ -8,7 +8,7 @@ # users a quick introduction to how to use buildGo. let - buildGo = import ../default.nix {}; + buildGo = import ../default.nix { }; # Example use of buildGo.package, which creates an importable Go # package from the specified source files. @@ -29,7 +29,8 @@ let # 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.) -in buildGo.program { +in +buildGo.program { name = "example"; srcs = [ diff --git a/nix/buildGo/external/default.nix b/nix/buildGo/external/default.nix index 6540faf04c36..f713783a58be 100644 --- a/nix/buildGo/external/default.nix +++ b/nix/buildGo/external/default.nix @@ -17,12 +17,12 @@ let inherit (pkgs) lib runCommand go jq ripgrep; - pathToName = p: replaceStrings ["/"] ["_"] (toString p); + pathToName = p: replaceStrings [ "/" ] [ "_" ] (toString p); # Collect all non-vendored dependencies from the Go standard library # into a file that can be used to filter them out when processing # dependencies. - stdlibPackages = runCommand "stdlib-pkgs.json" {} '' + stdlibPackages = runCommand "stdlib-pkgs.json" { } '' export HOME=$PWD export GOPATH=/dev/null ${go}/bin/go list std | \ @@ -45,20 +45,28 @@ let }; mkset = path: value: - if path == [] then { gopkg = value; } + if path == [ ] then { gopkg = value; } else { "${head path}" = mkset (tail path) value; }; last = l: elemAt l ((length l) - 1); toPackage = self: src: path: depMap: entry: let - localDeps = map (d: lib.attrByPath (d ++ [ "gopkg" ]) ( - throw "missing local dependency '${lib.concatStringsSep "." d}' in '${path}'" - ) self) entry.localDeps; - - foreignDeps = map (d: lib.attrByPath [ d.path ] ( - throw "missing foreign dependency '${d.path}' in '${path}, imported at ${d.position}'" - ) depMap) entry.foreignDeps; + localDeps = map + (d: lib.attrByPath (d ++ [ "gopkg" ]) + ( + throw "missing local dependency '${lib.concatStringsSep "." d}' in '${path}'" + ) + self) + entry.localDeps; + + foreignDeps = map + (d: lib.attrByPath [ d.path ] + ( + throw "missing foreign dependency '${d.path}' in '${path}, imported at ${d.position}'" + ) + depMap) + entry.foreignDeps; args = { srcs = map (f: src + ("/" + f)) entry.files; @@ -74,22 +82,28 @@ let binArgs = args // { name = (last ((lib.splitString "/" path) ++ entry.locator)); }; - in if entry.isCommand then (program binArgs) else (package libArgs); + in + if entry.isCommand then (program binArgs) else (package libArgs); -in { src, path, deps ? [] }: let +in +{ src, path, deps ? [ ] }: +let # Build a map of dependencies (from their import paths to their # derivation) so that they can be conditionally imported only in # sub-packages that require them. - depMap = listToAttrs (map (d: { - name = d.goImportPath; - value = d; - }) (map (d: d.gopkg) deps)); + depMap = listToAttrs (map + (d: { + name = d.goImportPath; + value = d; + }) + (map (d: d.gopkg) deps)); name = pathToName path; - analysisOutput = runCommand "${name}-structure.json" {} '' + analysisOutput = runCommand "${name}-structure.json" { } '' ${analyser}/bin/analyser -path ${path} -source ${src} > $out ''; analysis = fromJSON (readFile analysisOutput); -in lib.fix(self: foldl' lib.recursiveUpdate {} ( +in +lib.fix (self: foldl' lib.recursiveUpdate { } ( map (entry: mkset entry.locator (toPackage self src path depMap entry)) analysis )) diff --git a/nix/buildGo/proto.nix b/nix/buildGo/proto.nix index 4bd3a572761d..6c37f758ced7 100644 --- a/nix/buildGo/proto.nix +++ b/nix/buildGo/proto.nix @@ -8,7 +8,8 @@ let inherit (builtins) fetchGit map; -in rec { +in +rec { goProto = external { path = "github.com/golang/protobuf"; src = fetchGit { |