feat: Add support for Protobuf-generated libraries
Adds a 'buildGo.proto' function which takes a single .proto file as its source and generates a corresponding Go library which can then be imported. 'proto' takes these arguments (Yants-style type definition): struct "protoArgs" { # required: name = string; proto = path; # optional: extraDeps = list goLib; # defaults to [ ] protocFlags = option string; } Note that proto libraries will automatically have dependencies for the required protobuf Go libraries added to them. gRPC is not (yet) supported.
This commit is contained in:
parent
24225580e8
commit
d441e035aa
1 changed files with 75 additions and 3 deletions
78
buildGo.nix
78
buildGo.nix
|
@ -15,9 +15,11 @@ let
|
||||||
filter
|
filter
|
||||||
map
|
map
|
||||||
match
|
match
|
||||||
readDir;
|
readDir
|
||||||
|
replaceStrings
|
||||||
|
toPath;
|
||||||
|
|
||||||
inherit (pkgs) lib go runCommand;
|
inherit (pkgs) lib go runCommand fetchFromGitHub protobuf;
|
||||||
|
|
||||||
# Helpers for low-level Go compiler invocations
|
# Helpers for low-level Go compiler invocations
|
||||||
spaceOut = lib.concatStringsSep " ";
|
spaceOut = lib.concatStringsSep " ";
|
||||||
|
@ -64,7 +66,77 @@ let
|
||||||
${srcList path (map (s: "${s}") srcs)}
|
${srcList path (map (s: "${s}") srcs)}
|
||||||
${go}/bin/go tool compile -o $out/${path}.a -trimpath=$PWD -trimpath=${go} -p ${path} ${includeSources uniqueDeps} ${spaceOut srcs}
|
${go}/bin/go tool compile -o $out/${path}.a -trimpath=$PWD -trimpath=${go} -p ${path} ${includeSources uniqueDeps} ${spaceOut srcs}
|
||||||
'') // { goDeps = uniqueDeps; };
|
'') // { goDeps = uniqueDeps; };
|
||||||
|
|
||||||
|
# Build a Go library out of the specified protobuf definition.
|
||||||
|
proto = { name, proto, path ? name, protocFlags ? "", extraDeps ? [] }: package {
|
||||||
|
inherit name path;
|
||||||
|
deps = [ goProto ] ++ extraDeps;
|
||||||
|
srcs = lib.singleton (runCommand "goproto-${name}.pb.go" {} ''
|
||||||
|
cp ${proto} ${baseNameOf proto}
|
||||||
|
${protobuf}/bin/protoc --plugin=${protocGo}/bin/protoc-gen-go \
|
||||||
|
--go_out=${protocFlags}import_path=${baseNameOf path}:. ${baseNameOf proto}
|
||||||
|
mv *.pb.go $out
|
||||||
|
'');
|
||||||
|
};
|
||||||
|
|
||||||
|
# Protobuf & gRPC integration requires these dependencies:
|
||||||
|
proto-go-src = fetchFromGitHub {
|
||||||
|
owner = "golang";
|
||||||
|
repo = "protobuf";
|
||||||
|
rev = "ed6926b37a637426117ccab59282c3839528a700";
|
||||||
|
sha256 = "0fynqrim022x9xi2bivkw19npbz4316v4yr7mb677s9s36z4dc4h";
|
||||||
|
};
|
||||||
|
|
||||||
|
protoPart = path: deps: package {
|
||||||
|
inherit deps;
|
||||||
|
name = replaceStrings ["/"] ["_"] path;
|
||||||
|
path = "github.com/golang/protobuf/${path}";
|
||||||
|
srcs = goFilesIn (toPath "${proto-go-src}/${path}");
|
||||||
|
};
|
||||||
|
|
||||||
|
goProto =
|
||||||
|
let
|
||||||
|
protobuf = package {
|
||||||
|
name = "protobuf";
|
||||||
|
path = "github.com/golang/protobuf/proto";
|
||||||
|
# TODO(tazjin): How does this build toggle work?
|
||||||
|
srcs = filter
|
||||||
|
(f: (match "(.*)/pointer_reflect.go" f) == null)
|
||||||
|
(goFilesIn (toPath "${proto-go-src}/proto"));
|
||||||
|
};
|
||||||
|
type = name: protoPart "ptypes/${name}" [ protobuf ];
|
||||||
|
descriptor = protoPart "descriptor" [ protobuf ];
|
||||||
|
ptypes = package {
|
||||||
|
name = "ptypes";
|
||||||
|
path = "github.com/golang/protobuf/ptypes";
|
||||||
|
srcs = goFilesIn (toPath "${proto-go-src}/ptypes");
|
||||||
|
deps = map type [
|
||||||
|
"any"
|
||||||
|
"duration"
|
||||||
|
"empty"
|
||||||
|
"struct"
|
||||||
|
"timestamp"
|
||||||
|
"wrappers"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in protobuf // { goDeps = allDeps (protobuf.goDeps ++ [ ptypes ]); };
|
||||||
|
|
||||||
|
protocDescriptor = (protoPart "protoc-gen-go/descriptor" [ goProto ]);
|
||||||
|
protocGo =
|
||||||
|
let
|
||||||
|
generator = protoPart "protoc-gen-go/generator" [
|
||||||
|
(protoPart "protoc-gen-go/generator/internal/remap" [])
|
||||||
|
(protoPart "protoc-gen-go/plugin" [ protocDescriptor ])
|
||||||
|
];
|
||||||
|
grpc = protoPart "protoc-gen-go/grpc" [ generator ];
|
||||||
|
in program {
|
||||||
|
name = "protoc-gen-go";
|
||||||
|
deps = [ goProto grpc generator ];
|
||||||
|
srcs = filter
|
||||||
|
(f: (match "(.*)/doc.go" f) == null)
|
||||||
|
(goFilesIn (toPath "${proto-go-src}/protoc-gen-go"));
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
# Only the high-level builder functions are exposed
|
# Only the high-level builder functions are exposed
|
||||||
inherit program package;
|
inherit program package proto;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue