blob: c26cf9de6354ed094e8f6598685351e2c6e4e391 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
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";
};
# Checks the JSON plan against the checkout's Cargo.lock and Cargo.toml.
# These come from dir, not src, because cleanCargoSource drops Cargo.lock
# next to a Cargo.json.
planChecks = dir:
lib.optionalAttrs (builtins.pathExists (dir + "/Cargo.lock")) {
cargoLock = dir + "/Cargo.lock";
}
// lib.optionalAttrs (builtins.pathExists (dir + "/Cargo.toml")) {
cargoToml = dir + "/Cargo.toml";
};
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; } // planChecks dir
else
assert mylib.debug "pkgs/rust: automatic package ${pname} from ${mylib.pretty dir}";
{ name = pname; inherit src; } // planChecks dir
)
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)
|