diff options
Diffstat (limited to 'pkgs/rust/default.nix')
| -rw-r--r-- | pkgs/rust/default.nix | 102 |
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) |
