summaryrefslogtreecommitdiffstats
path: root/pkgs/rust/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/rust/default.nix')
-rw-r--r--pkgs/rust/default.nix102
1 files changed, 102 insertions, 0 deletions
diff --git a/pkgs/rust/default.nix b/pkgs/rust/default.nix
new file mode 100644
index 0000000..d273db6
--- /dev/null
+++ b/pkgs/rust/default.nix
@@ -0,0 +1,102 @@
+self: super:
+
+let
+ inherit (super) lib mylib;
+
+ # Merges an override into attrs. The override is attrs, or a function from
+ # the original attrs to attrs, like the argument of nixpkgs' .override.
+ applyOverride = override: attrs: attrs // lib.toFunction override attrs;
+
+ explicitPackages =
+ mylib.mapNixDir' (pname: path: path) [ ./. ];
+
+ automaticPackages =
+ let
+ root = /home/tv/sync/src;
+ in
+ lib.optionalAttrs (builtins.pathExists root)
+ (lib.mapAttrs (pname: _type: root + "/${pname}")
+ (lib.filterAttrs
+ (pname: type: type == "directory" && builtins.pathExists (root + "/${pname}/Cargo.toml"))
+ (builtins.readDir root)));
+
+ # callPackage adds override and overrideDerivation to the returned attrset,
+ # which crate2nix-package.nix would reject as unexpected arguments.
+ callArgs = path: builtins.removeAttrs (self.callPackage path {}) [ "override" "overrideDerivation" ];
+
+ # A plan kept next to the package in hrm: pkgs/rust/<pname>/Cargo.json.
+ # Settings in the package file itself take precedence.
+ hrmPlan = path:
+ lib.optionalAttrs (builtins.pathExists (path + "/Cargo.json")) {
+ resolvedJson = path + "/Cargo.json";
+ };
+in
+
+{
+ # Builds a crate2nix workspace.
+ crate2nixPackage = args: import ./lib/crate2nix-package.nix ({
+ inherit applyOverride;
+ pkgs = self;
+ } // args);
+
+ # Applied to our own crates: debug builds, but dependencies in release.
+ rustDevCrateAttrs = args: {
+ release = false;
+ codegenUnits = 256;
+ extraRustcOpts = args.extraRustcOpts or [] ++ [
+ "-C debuginfo=line-tables-only"
+ "-C link-arg=-fuse-ld=mold"
+ ];
+ nativeBuildInputs = args.nativeBuildInputs or [] ++ [ self.mold ];
+ };
+
+ # Builds a crate from rustCrateArgs.<pname> merged with an override: attrs,
+ # or a function from the stored arguments to attrs, e.g.
+ # rustCrateWith "continuum" { features = [ "tor" ]; }
+ # With {}, that's the package itself.
+ rustCrateWith = pname: f:
+ (self.crate2nixPackage (applyOverride f self.rustCrateArgs.${pname})).build;
+
+ # crate2nixPackage arguments per package. Change them in a later overlay:
+ # self: super: {
+ # rustCrateArgs = super.rustCrateArgs // {
+ # continuum = super.rustCrateArgs.continuum // { resolvedJson = ./continuum.json; };
+ # };
+ # }
+ rustCrateArgs =
+ lib.mapAttrs (pname: path: hrmPlan path // callArgs path) explicitPackages
+ //
+ lib.mapAttrs
+ (pname: dir: let
+ src = self.cleanCargoSource pname dir;
+ in
+ if explicitPackages ? ${pname} then
+ assert mylib.debug "pkgs/rust: overriding ${pname}.src with ${mylib.pretty dir}";
+ hrmPlan explicitPackages.${pname} // callArgs explicitPackages.${pname} // { inherit src; }
+ else
+ assert mylib.debug "pkgs/rust: automatic package ${pname} from ${mylib.pretty dir}";
+ { name = pname; inherit src; }
+ )
+ automaticPackages;
+
+ # Copies a Cargo workspace into the store, leaving out what the build
+ # doesn't need.
+ cleanCargoSource = name: src: builtins.path {
+ inherit name;
+ path = src;
+ filter = path: type:
+ !builtins.any lib.id [
+ (type == "directory" && builtins.elem (baseNameOf path) [ ".git" ".graveyard" ])
+ # Cargo.json is the resolved lock.
+ (type == "regular" && baseNameOf path == "Cargo.lock" && builtins.pathExists (builtins.dirOf path + "/Cargo.json"))
+ ];
+ };
+}
+
+//
+
+lib.mapAttrs
+ (pname: _path:
+ assert mylib.debugIf (super ? ${pname}) "pkgs/rust: overriding ${pname}";
+ self.rustCrateWith pname {})
+ (explicitPackages // automaticPackages)