@@ -21,7 +21,86 @@ with types;
2121
2222# Work around issue that can cause _lots_ of files to be copied into the store.
2323# See https://github.com/NixOS/nixpkgs/pull/64691
24−let path = types.path // { check = x: types.path.check (x.origSrc or x); };
24+let
25+ path = types.path // { check = x: types.path.check (x.origSrc or x); };
26+
27+ componentType = submodule {
28+ # add the shared componentOptions
29+ options = (packageOptions config) // {
30+ buildable = mkOption {
31+ type = bool;
32+ default = true;
33+ };
34+ depends = mkOption {
35+ type = listOfFilteringNulls unspecified;
36+ default = [];
37+ };
38+ libs = mkOption {
39+ type = listOfFilteringNulls (nullOr package);
40+ default = [];
41+ };
42+ frameworks = mkOption {
43+ type = listOfFilteringNulls package;
44+ default = [];
45+ };
46+ pkgconfig = mkOption {
47+ type = listOf (listOfFilteringNulls package);
48+ default = [];
49+ };
50+ build-tools = mkOption {
51+ type = listOfFilteringNulls unspecified;
52+ default = [];
53+ };
54+ modules = mkOption {
55+ type = listOfFilteringNulls unspecified;
56+ default = [];
57+ };
58+ asmSources = mkOption {
59+ type = listOfFilteringNulls unspecified;
60+ default = [];
61+ };
62+ cmmSources = mkOption {
63+ type = listOfFilteringNulls unspecified;
64+ default = [];
65+ };
66+ cSources = mkOption {
67+ type = listOfFilteringNulls unspecified;
68+ default = [];
69+ };
70+ cxxSources = mkOption {
71+ type = listOfFilteringNulls unspecified;
72+ default = [];
73+ };
74+ jsSources = mkOption {
75+ type = listOfFilteringNulls unspecified;
76+ default = [];
77+ };
78+ hsSourceDirs = mkOption {
79+ type = listOfFilteringNulls unspecified;
80+ default = ["."];
81+ };
82+ includeDirs = mkOption {
83+ type = listOfFilteringNulls unspecified;
84+ default = [];
85+ };
86+ includes = mkOption {
87+ type = listOfFilteringNulls unspecified;
88+ default = [];
89+ };
90+ mainPath = mkOption {
91+ type = listOfFilteringNulls unspecified;
92+ default = [];
93+ };
94+ extraSrcFiles = mkOption {
95+ type = listOfFilteringNulls unspecified;
96+ default = [];
97+ };
98+ platforms = mkOption {
99+ type = nullOr (listOfFilteringNulls unspecified);
100+ default = null;
101+ };
102+ };
103+ };
25104
26105in {
27106 # This is how the Nix expressions generated by *-to-nix receive
@@ -138,85 +217,7 @@ in {
138217 };
139218 };
140219
141− components = let
142− componentType = submodule {
143− # add the shared componentOptions
144− options = (packageOptions config) // {
145− buildable = mkOption {
146− type = bool;
147− default = true;
148− };
149− depends = mkOption {
150− type = listOfFilteringNulls unspecified;
151− default = [];
152− };
153− libs = mkOption {
154− type = listOfFilteringNulls (nullOr package);
155− default = [];
156− };
157− frameworks = mkOption {
158− type = listOfFilteringNulls package;
159− default = [];
160− };
161− pkgconfig = mkOption {
162− type = listOf (listOfFilteringNulls package);
163− default = [];
164− };
165− build-tools = mkOption {
166− type = listOfFilteringNulls unspecified;
167− default = [];
168− };
169− modules = mkOption {
170− type = listOfFilteringNulls unspecified;
171− default = [];
172− };
173− asmSources = mkOption {
174− type = listOfFilteringNulls unspecified;
175− default = [];
176− };
177− cmmSources = mkOption {
178− type = listOfFilteringNulls unspecified;
179− default = [];
180− };
181− cSources = mkOption {
182− type = listOfFilteringNulls unspecified;
183− default = [];
184− };
185− cxxSources = mkOption {
186− type = listOfFilteringNulls unspecified;
187− default = [];
188− };
189− jsSources = mkOption {
190− type = listOfFilteringNulls unspecified;
191− default = [];
192− };
193− hsSourceDirs = mkOption {
194− type = listOfFilteringNulls unspecified;
195− default = ["."];
196− };
197− includeDirs = mkOption {
198− type = listOfFilteringNulls unspecified;
199− default = [];
200− };
201− includes = mkOption {
202− type = listOfFilteringNulls unspecified;
203− default = [];
204− };
205− mainPath = mkOption {
206− type = listOfFilteringNulls unspecified;
207− default = [];
208− };
209− extraSrcFiles = mkOption {
210− type = listOfFilteringNulls unspecified;
211− default = [];
212− };
213− platforms = mkOption {
214− type = nullOr (listOfFilteringNulls unspecified);
215− default = null;
216− };
217− };
218− };
219− in {
220+ components = {
220221 setup = mkOption {
221222 type = nullOr componentType;
222223 default = {
@@ -295,5 +296,43 @@ in {
295296 type = listOf (either unspecified path);
296297 default = [];
297298 };
299+ # This used to be `components.all` but it has been added back as `allComponent` to
300+ # to avoid confusion. It is not mapped by `builder/hspkg-builder.nix` to anything
301+ # you can build. Instead it is used internally when `configureAllComponents`
302+ # is set or for tests whe on `cabal-doctest` is in the `setup-depends` of the package.
303+ allComponent = mkOption {
304+ type = componentType;
305+ apply = all: all // {
306+ # TODO: Should this check for the entire component
307+ # definition to match, rather than just the identifier?
308+ depends = builtins.filter (p: p.identifier != config.package.identifier) all.depends;
309+ };
310+ description = "The merged dependencies of all other components";
311+ };
298312 };
313+
314+ # This has one quirk. Manually setting options on the all component
315+ # will be considered a conflict. This is almost always fine; most
316+ # settings should be modified in either the package options, or an
317+ # individual component's options. When this isn't sufficient,
318+ # mkForce is a reasonable workaround.
319+ #
320+ # An alternative solution to mkForce for many of the options where
321+ # this is relevant would be to switch from the bool type to
322+ # something like an anyBool type, which would merge definitions by
323+ # returning true if any is true.
324+ config.allComponent =
325+ let allComps = haskellLib.getAllComponents config;
326+ in lib.mkMerge (
327+ builtins.map (c:
328+ # Exclude attributes that are likely to have conflicting definitions
329+ # (a common use case for `all` is in `shellFor` and it only has an
330+ # install phase).
331+ builtins.removeAttrs c ["preCheck" "postCheck" "keepSource"]
332+ ) allComps
333+ ) // {
334+ # If any one of the components needs us to keep the source
335+ # then keep it for the `all` component
336+ keepSource = lib.foldl' (x: comp: x || comp.keepSource) false allComps;
337+ };
299338}