permit multiline comments and strings in macros
[bpt/coccinelle.git] / release.nix
CommitLineData
17ba0788
C
1# Hydra build file for coccinelle
2
755320b0 3{ nixpkgs ? "/etc/nixos/nixpkgs"
17ba0788
C
4, cocciSrc ? { outPath = ./.; revCount = 1234; gitTag = "abcdef"; }
5, testsSrc ? { outPath = ../big-tests; rev = 1234; }
6, officialRelease ? false
d6ce1786 7, performRegress ? true
17ba0788
C
8}:
9
feec80c3 10
17ba0788
C
11let
12
13 # version information
14 version = builtins.readFile ./version;
15 versionSuffix = if officialRelease then "" else "pre${toString cocciSrc.revCount}-${cocciSrc.gitTag}";
16
feec80c3
C
17
18 #
19 # Source release (tarball)
20 #
21
17ba0788
C
22 # The source tarball taken from the repository.
23 # The tarball should actually be compilable using
24 # ./configure && make depend && make opt && make install
25 # on systems other than nix.
26 tarball =
feec80c3 27 let pkgs = import nixpkgs { };
17ba0788
C
28 in with pkgs; with ocamlPackages; releaseTools.sourceTarball {
29 name = "coccinelle-tarball";
30 src = cocciSrc;
31 inherit officialRelease;
32 inherit version;
33 inherit versionSuffix;
34
35 buildInputs = [
feec80c3
C
36 ocaml findlib menhir python
37 texLiveFull # for building the documentation
38 pkgconfig # for the autoconf macros
17ba0788 39 ];
17ba0788
C
40
41 preDist = ''
42 local PREVHOME=$HOME
43 export HOME=$TMPDIR # the latex installation needs to write to the $HOME directory, so rename it here
44 '';
45
46 dontCopyDist = 1; # we'll copy the tarball to the tarballs folder ourselves (and rename it)
47 postDist = ''
48 export HOME=$PREVHOME # restore the home directory
49
755320b0 50 mkdir -p "$out/tarballs"
17ba0788
C
51
52 # rename the tarball to give it a version-specific name
53 cp coccinelle-*.tar.gz "$out/tarballs/coccinelle-${version}${versionSuffix}.tar.gz"
54 '';
55 };
56
57
d6ce1786
C
58 #
59 # Helper functions for building configurations
60 #
61
62 selOcamlDefault = orig: orig.ocamlPackages;
755320b0 63 selOcaml400 = orig: orig.ocamlPackages_4_00_0;
d6ce1786
C
64 selOcaml312 = orig: orig.ocamlPackages_3_12_1;
65 selOcaml311 = orig: orig.ocamlPackages_3_11_2;
66 selOcaml310 = orig: orig.ocamlPackages_3_10_0;
67
68 selCommonOcamlPkgs = ocamlPackages: with ocamlPackages; [
755320b0 69 findlib menhir ocaml_sexplib
d6ce1786
C
70 ];
71
72 selMinimalOcamlPkgs = ocamlPackages: with ocamlPackages; [
73 findlib menhir
74 ];
75
76 selAllOcamlPkgs = ocamlPackages: with ocamlPackages; [
755320b0 77 findlib menhir ocaml_sexplib ocaml_pcre pycaml
d6ce1786
C
78 ];
79
80 selCommonInputs = pkgs: [ pkgs.pkgconfig pkgs.pcre ];
81
82 selDefaultShell = pkgs: pkgs.stdenv.shell;
83
84 selPythonNone = pkgs: [];
85 selPythonDefault = pkgs: [ pkgs.python ];
86 selPython2 = pkgs: [ pkgs.python27 ];
87 selPython3 = pkgs: [ pkgs.python3 ];
88
89 # creates a configuration for a given python version
90 mkCfgPython = f: pkgs: with (f pkgs); {
91 inherit name pythons flags;
92
93 ocamls = selCommonOcamlPkgs pkgs.ocamlPackages ++ [ pkgs.ocamlPackages.pycaml ];
94 selOcaml = selOcamlDefault;
95 extras = selCommonInputs pkgs;
96 shell = selDefaultShell pkgs;
755320b0 97 extraAttrs = { };
d6ce1786
C
98 };
99
100 # creates a configuration for a given ocaml version
101 mkCfgOcaml = { name, selOcaml, flags }: pkgs: {
102 inherit flags selOcaml;
103
104 name = "ocaml-${name}";
105 pythons = selPythonDefault pkgs;
106 ocamls = selMinimalOcamlPkgs pkgs.ocamlPackages;
107 extras = selCommonInputs pkgs;
108 shell = selDefaultShell pkgs;
755320b0 109 extraAttrs = { };
d6ce1786
C
110 };
111
112 # creates a default configuration with additional flags
755320b0 113 mkCfgDefault = { name, flags, extra ? {} }: pkgs: {
d6ce1786
C
114 inherit name flags;
115 pythons = selPythonDefault pkgs;
116 ocamls = selAllOcamlPkgs pkgs.ocamlPackages;
117 selOcaml = selOcamlDefault;
118 extras = selCommonInputs pkgs;
119 shell = selDefaultShell pkgs;
755320b0 120 extraAttrs = extra;
d6ce1786
C
121 };
122
123 # creates a minimal configuration with additional flags
124 mkCfgMinimal = { name, flags }: pkgs: {
125 inherit name flags;
126 pythons = [];
127 ocamls = [];
128 selOcaml = selOcamlDefault;
129 extras = [];
130 shell = selDefaultShell pkgs;
755320b0 131 extraAttrs = { };
d6ce1786
C
132 };
133
134 # creates a configuration for the given ocaml packages
135 mkCfgPackage = { name, ocamls, flags }: pkgs: {
136 inherit name flags;
137 pythons = selPythonDefault pkgs;
138 ocamls = selMinimalOcamlPkgs pkgs.ocamlPackages ++ ocamls pkgs.ocamlPackages;
139 selOcaml = selOcamlDefault;
140 extras = selCommonInputs pkgs;
141 shell = selDefaultShell pkgs;
755320b0 142 extraAttrs = { };
d6ce1786
C
143 };
144
145 # build the project using the given shell
146 # it takes a minimal configuration, but then with all the
147 # libraries that trigger features of coccinelle to be enabled.
148 mkCfgShell = { name, selShell }: pkgs: {
149 inherit name;
150 pythons = selPythonDefault pkgs;
151 ocamls = selMinimalOcamlPkgs pkgs.ocamlPackages;
152 selOcaml = selOcamlDefault;
153 flags = [];
154 extras = [ pkgs.pcre ];
155 shell = selShell pkgs;
755320b0 156 extraAttrs = { };
d6ce1786
C
157 };
158
159 # creates a configuration with multiple ocaml versions: this gives
160 # conflicts. This is just a test to see whether our build system is
161 # not too much confused in this case. It seems at least that ocamlfind
162 # cannot be used in this setting.
163 mkCfgManyOcaml =
164 let
165 selOcaml = pkgs: ocamlPkgSel: with (ocamlPkgSel pkgs); ocaml;
166 selPkgs = pkgs: ocamlPkgSel: with (ocamlPkgSel pkgs); [ menhir ];
167 in sels: pkgs: {
168 name = "many-ocaml";
169 pythons = [];
170 ocamls = pkgs.lib.concatMap (selPkgs pkgs) sels;
171 selOcaml = selOcamlDefault;
172 flags = [];
173 extras = selCommonInputs pkgs ++ map (selOcaml pkgs) sels;
174 shell = selDefaultShell pkgs;
755320b0 175 extraAttrs = { };
d6ce1786
C
176 };
177
178
179 #
180 # Configurations
181 #
182
183 defaultCfg = mkCfgDefault { name = "default"; flags = []; };
184 debugCfg = mkCfgDefault { name = "debug"; flags = [ "--enable-release=no" ]; };
185 wrappersCfg = mkCfgDefault { name = "wrappers"; flags = [ "--enable-python" "--enable-ocaml" "--without-pkg-config" "--without-ocamlfind" ]; };
755320b0 186 manyOcamlCfg = mkCfgManyOcaml [ selOcaml400 selOcaml312 selOcaml311 selOcaml310 ];
d6ce1786
C
187
188 minimalCfgs = map mkCfgMinimal [
189 { name = "minimal"; flags = []; }
190 { name = "noocamlscripting"; flags = [ "--disable-ocaml" ]; }
191 ];
192
193 # Several configurations testing different python versions.
194 # We exlicitly pass the "--enable-python" flag so that the
195 # build should fail if no suitable python can be detected.
196 pythonCfgs =
197 map mkCfgPython [
198 ( _ : { name = "no-python"; pythons = []; flags = []; })
199
200 (pkgs: {
201 name = "python2-local";
202 pythons = selPython2 pkgs;
203 flags = [ "--enable-python" "--disable-pycaml" ];
204 })
205
206 (pkgs: {
207 name = "python3-local";
208 pythons = selPython3 pkgs;
209 flags = [ "--enable-python" "--disable-pycaml" ];
210 })
211
212 (pkgs: {
213 name = "python3-global";
214 pythons = selPython3 pkgs;
215 flags = [ "--enable-python" ];
216 })
217
218 (pkgs: {
219 name = "python-nopkgconfig";
220 pythons = selPython2 pkgs;
221 flags = [ "--enable-python" "--without-pkg-config" ];
222 })
223
224# disabled because this combination does not work in NixOS
225# (pkgs: {
226# name = "many-pythons";
227# pythons = selPython3 pkgs ++ selPython2 pkgs;
228# flags = [ "--with-python=python3" ];
229# })
230 ];
231
232 # Several configurations testing different OCaml versions.
233 # These versions ship with minimal global packages in order
234 # to thest the bundled packages with these ocaml versions.
235 ocamlCfgs = map mkCfgOcaml [
755320b0
C
236 { name = "400nat"; selOcaml = selOcaml400; flags = [ "--enable-release=yes" ]; }
237 { name = "400byt"; selOcaml = selOcaml400; flags = []; }
d6ce1786
C
238 { name = "312"; selOcaml = selOcaml312; flags = []; }
239 { name = "311"; selOcaml = selOcaml311; flags = [ "--enable-release=yes" ]; }
240 { name = "310"; selOcaml = selOcaml310; flags = []; }
241 ];
242
243 # Several configurations testing different available
244 # ocaml packages.
245 pkgCfgs = map mkCfgPackage [
d6ce1786
C
246 { name = "pcre"; ocamls = ps: [ ps.ocaml_pcre ]; flags = [ "--enable-pcre-syntax" ]; }
247 { name = "sexplib"; ocamls = ps: [ ps.ocaml_sexplib ]; flags = [ "--enable-sexplib" ]; }
248 { name = "pycaml"; ocamls = ps: [ ps.pycaml ]; flags = [ "--enable-pycaml" ]; }
249 ];
250
abad11c5 251 # Tests using several different types of shells.
d6ce1786
C
252 shellCfgs = map mkCfgShell [
253 { name = "bash"; selShell = pkgs: "${pkgs.bash}/bin/bash"; }
254 { name = "dash"; selShell = pkgs: "${pkgs.dash}/bin/dash"; }
255 { name = "zsh"; selShell = pkgs: "${pkgs.zsh}/bin/zsh"; }
256
257 # the configure script is not compatible with tcsh
258 # { name = "tcsh"; selShell = pkgs: "${pkgs.tcsh}/bin/tcsh"; }
259 ];
260
abad11c5
C
261 #
262 # Configurations for the compilation of coccinelle using ocamlbuild.
263 #
264
265 ocamlbuildZeroCfg = mkCfgMinimal {
266 name = "ocamlbuild-zero";
267 flags = [ "--enable-ocamlbuild" "--enable-release" ];
268 };
269
270 ocamlbuildFullCfg = mkCfgDefault {
271 name = "ocamlbuild-full";
272 flags = [ "--enable-ocamlbuild" "--enable-release" ];
273 };
274
275 ocamlbuildCfgs = map mkCfgOcaml [
276 { name = "ocamlbuild-400nat"; selOcaml = selOcaml400;
277 flags = [ "--enable-ocamlbuild" "--enable-release=yes" ]; }
278 { name = "ocamlbuild-400byte"; selOcaml = selOcaml400;
279 flags = [ "--enable-ocamlbuild" ]; }
280 { name = "ocamlbuild-312"; selOcaml = selOcaml312;
281 flags = [ "--enable-ocamlbuild" "--enable-release" ]; }
282 { name = "ocamlbuild-311"; selOcaml = selOcaml311;
283 flags = [ "--enable-ocamlbuild" ]; }
284 { name = "ocamlbuild-310"; selOcaml = selOcaml310;
285 flags = [ "--enable-ocamlbuild" "--enable-release" ]; }
286 ] ++ [ ocamlbuildZeroCfg ocamlbuildFullCfg ];
287
d6ce1786
C
288 altCfgs =
289 [ debugCfg manyOcamlCfg ]
290 ++ minimalCfgs
291 ++ ocamlCfgs ++ pythonCfgs
abad11c5
C
292 ++ pkgCfgs ++ shellCfgs
293 ++ ocamlbuildCfgs;
d6ce1786
C
294
295
feec80c3
C
296 #
297 # Builds for specific configurations
298 #
299
300 # builds coccinelle, parameterized over the ocaml and python packages, and the configure flags.
17ba0788 301 # the result should be a usable nix-expression
feec80c3
C
302
303 # mkConfiguration is a function that takes the nix package collection of the build
304 # (called 'pkgs') and results in a record containing:
d6ce1786
C
305 # name of the configuration, python packages, ocaml packages selection function
306 # (which takes the original 'pkgs' as parameter), and ocaml packages. The selection
307 # function is used by 'mkConfiguration' to determine the appropriate ocamlPackages
308 # field in 'pkgs'.
feec80c3 309 mkBuild = mkConfiguration: { system ? builtins.currentSystem }:
17ba0788
C
310 let pkgs = import nixpkgs {
311 inherit system;
feec80c3
C
312 config.packageOverrides = orig : {
313 ocamlPackages = cfg.selOcaml orig;
314 };
17ba0788 315 };
feec80c3 316 cfg = mkConfiguration pkgs;
d6ce1786 317 flags = [ "--enable-release=world" ] ++ cfg.flags;
755320b0 318 in with pkgs; releaseTools.nixBuild ({
d6ce1786 319 inherit (cfg) shell;
feec80c3 320 name = "cocci-build-${cfg.name}";
17ba0788 321 src = tarball;
d6ce1786
C
322 enableParallelBuilding = true;
323 buildInputs = cfg.extras ++ [ ncurses ocamlPackages.ocaml ] ++ cfg.ocamls ++ cfg.pythons;
324 configureFlags = pkgs.lib.concatStringsSep " " flags; # hmm, flags are now not allowed to contain spaces
325 doCheck = true;
326
17ba0788 327 buildPhase = ''
feec80c3
C
328 mkdir -p "$out/nix-support/"
329 touch "$out/nix-support/make.log"
330 echo "report log $out/nix-support/result.log" >> "$out/nix-support/hydra-build-products"
17ba0788 331
feec80c3 332 make all 2> >(tee -a "$out/nix-support/make.log" >&2)
17ba0788 333 '';
17ba0788 334
d6ce1786
C
335 # changes the shell in some of the scripts to the configured one
336 prePatch = ''
337 echo "patching the shell in scripts to: ${cfg.shell}"
338 for script in configure scripts/spatch.sh.in scripts/genversion.sh \
339 setup/fake-subst.sh setup/fake-menhir.sh setup/fake-pdflatex.sh; do
340 substituteInPlace $script --replace '#! /bin/sh' '#! ${cfg.shell}'
341 done
342 '';
755320b0 343 } // cfg.extraAttrs);
17ba0788 344
d6ce1786
C
345 build = mkBuild defaultCfg;
346 altBuilds = map mkBuild altCfgs;
347 allBuilds = [ build ] ++ altBuilds;
feec80c3 348
755320b0
C
349 # compile with ocaml profiling turned on and then running the
350 # test suite to collect results.
351 profileCfg = mkCfgDefault {
352 name = "profiling";
353 flags = [ "--enable-release=profile" ];
354 extra = {
355 installPhase = ''
356 mkdir -p "$out/nix-support"
357 cp ocamlprof.dump "$out/ocamlprof.dump"
358 echo "file binary $out/ocamlprof.dump" >> "$out/nix-support/hydra-build-products"
359 '';
360 };
361 };
362 profile = mkBuild profileCfg {};
363
feec80c3
C
364
365 #
366 # Package builders
367 #
368
17ba0788
C
369 # package builder for Debian-based OS'ses
370 makeDeb =
371 system: diskImageFun:
372
373 with import nixpkgs { inherit system; };
374 releaseTools.debBuild {
375 name = "coccinelle-deb";
376 src = tarball;
377 diskImage = diskImageFun vmTools.diskImageFuns {
378 extraPackages = [ "python" "python-support" "ocaml-nox" "ocaml-findlib" ];
379 };
380 debRequires = [ "python" "python-support" "ocaml-nox" "ocaml-findlib" ];
381 doCheck = false;
382
383 buildPhase = ''
384 make depend
385 make all
386 make all.opt
387 '';
388 };
389
390 makeDeb_i686 = makeDeb "i686-linux";
391 makeDeb_x86_64 = makeDeb "x86_64-linux";
392
feec80c3
C
393 # different debian builds
394 # deb_ubuntu1010_i386 = makeDeb_i686 (disk: disk.ubuntu1010i386);
395 # deb_ubuntu1010_x86_64 = makeDeb_x86_64 (disk: disk.ubuntu1010x86_64);
396
397
398 #
399 # Testing tasks
400 #
401
17ba0788
C
402 mkTask =
403 argsfun: { system ? builtins.currentSystem }:
404 let pkgs = import nixpkgs { inherit system; };
405 args = argsfun pkgs system;
406 name = "${args.name}-${version}${versionSuffix}";
407 in pkgs.stdenv.mkDerivation ({
408 phases = [ "runPhase" ];
409
410 runPhase = ''
755320b0
C
411 mkdir -p "$out"
412 mkdir -p "$out/nix-support"
17ba0788
C
413 touch "$TMPDIR/result.log"
414 exec > >(tee -a "$TMPDIR/result.log") 2> >(tee -a "$TMPDIR/result.log" >&2)
415 runHook execPhase
416 cp "$TMPDIR/result.log" "$out/"
417 echo "report log $out/result.log" >> "$out/nix-support/hydra-build-products"
418 echo "$name" > "$out/nix-support/hydra-release-name"
419 '';
420
421 meta = {
422 description = "Coccinelle post-build task";
423 schedulingPriority = 8;
424 };
425 } // args // { inherit name; });
426
d6ce1786
C
427 mkReport = inputs: mkTask (pkgs: _: with pkgs;
428 let builds = map (i: i { inherit (pkgs.stdenv) system; }) inputs; in {
429 name = "report";
430
431 execPhase = ''
432 echo "collecting logs"
433 for build in ${lib.concatStringsSep " " builds}; do
434 echo "log: $build/nix-support/make.log"
435 cat "$build/nix-support/make.log"
436 done
437
438 echo "grepping OCaml warnings"
439 if grep -2 "Warning " "$TMPDIR/result.log"
440 then
441 echo "found warnings!"
442 false
443 else
444 echo "there are apparently no significant warnings"
445 fi
446 '';
17ba0788 447
d6ce1786
C
448 meta = {
449 description = "Analysis of the coccinelle build reports";
450 schedulingPriority = 5;
451 };
452 });
453
454 report = mkReport allBuilds;
feec80c3
C
455
456
457 #
458 # Regression tests
459 #
460
17ba0788
C
461 # Produces regression test results, which can be positive or
462 # negative. The build should succeed regardless of the outcome
463 # of individual tests unless coccinelle is horribly broken.
464 # The resulting files are stored in a tarball so that it allows
465 # manual inspection.
466 mkRegress = cocciSelect: mkTask (pkgs: system: with pkgs;
467 let coccinelle = cocciSelect { inherit system; };
468 in {
469 name = "regression-${toString testsSrc.rev}";
470 buildInputs = [ coccinelle ];
471
472 execPhase = ''
473 # prepare a writeable tests directory
474 # as this directory contains large
475 # files, we'll create links to the
476 # individual files.
755320b0 477 mkdir -p "$TMPDIR/tests"
17ba0788
C
478 cp -rs ${testsSrc}/* "$TMPDIR/tests/"
479 chmod -R u+w "$TMPDIR/tests/"
480 cd "$TMPDIR/tests"
481
482 # initialize essential environment variables
483 # for the makefile
d6ce1786 484 export COCCINELLE_HOME=${coccinelle}/share/coccinelle
17ba0788
C
485 export COCCIDIR=$TMPDIR
486 export SPATCH=${coccinelle}/bin/spatch.opt
487 export ISO=${coccinelle}/share/coccinelle/standard.iso
488 export DEFS=${coccinelle}/share/coccinelle/standard.h
489
d6ce1786
C
490 # generate the test outcomes using a parallel build
491 make -e all -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES
17ba0788
C
492
493 # collect the results
494 # note: the tarball is likely to contain useless
d6ce1786
C
495 # symbolic links to files in the nix store. We therefore
496 # delete these symlinks. As a result, you should be able
497 # to unpack the tarball in the tests directory.
498 find "$TMPDIR/tests" -depth -type l -delete
17ba0788
C
499 cd "$TMPDIR"
500 tar -czf "$out/results.tar.gz" ./tests
501 echo "file binary-dist $out/results.tar.gz" >> "$out/nix-support/hydra-build-products"
502 '';
503
504 meta = {
505 description = "Regression test of Coccinelle";
506 schedulingPriority = 8;
507 };
508 });
509
510 # Checks whether the regression tests meet our expectations.
511 # If the set of failed tests is different than specified in
512 # the tests repository, this check fails.
513 checkRegress = regressSelect: mkTask (pkgs: system: with pkgs;
514 let regress = regressSelect { inherit system; };
515 in {
516 name = "test-${toString testsSrc.rev}";
517
518 execPhase = ''
519 # prepare a writeable tests directory
520 # as this directory contains large
521 # files, we'll create links to the
522 # individual files.
755320b0 523 mkdir -p "$TMPDIR/tests"
17ba0788
C
524 cp -rs ${testsSrc}/* "$TMPDIR/tests/"
525 chmod -R u+w "$TMPDIR/tests/"
526
527 # extract the outcome of the regression test over it
528 echo "reconstructing regression directory"
529 cd "$TMPDIR"
530 tar xfz "${regress}/results.tar.gz"
531 cd "$TMPDIR/tests"
532
533 echo "analyzing results"
534 make failedlog
535
536 echo "verifying the outcome"
537 make check
538 '';
539
540 meta = {
541 description = "Regression test of Coccinelle";
542 schedulingPriority = 8;
543 };
544 });
545
d6ce1786 546 regress = mkRegress build;
feec80c3 547 test = checkRegress regress;
17ba0788 548
17ba0788 549
feec80c3
C
550 #
551 # Performing release actions
552 #
17ba0788 553
feec80c3
C
554 dist =
555 let pkgs = import nixpkgs { };
556 name = "release-${version}${versionSuffix}";
557 in with pkgs; releaseTools.nixBuild {
558 inherit name;
559 src = cocciSrc;
560 buildInputs = with ocamlPackages; [
561 pkgconfig ncurses texLiveFull
562 ocaml findlib menhir
d6ce1786 563 python pcre patchelf
feec80c3 564 ];
abad11c5 565 configureFlags = "--enable-release";
d6ce1786 566
feec80c3 567 buildPhase = ''
d6ce1786
C
568 export TARGETDIR="$TMPDIR/dists"
569 mkdir -p $TARGETDIR
feec80c3 570 export HOME=$TMPDIR
d6ce1786
C
571 make prerelease GIT=echo TMP=$TARGETDIR
572 make release GIT=echo TMP=$TARGETDIR
573 make package TMP=$TARGETDIR
feec80c3 574 '';
17ba0788 575
feec80c3
C
576 installPhase = ''
577 mkdir -p "$out/nix-support/"
578 echo "cocci-dist-${version}" > "$out/nix-support/hydra-release-name"
d6ce1786 579 cp $TMPDIR/dists/*.tgz "$out/"
feec80c3
C
580 for file in $out/*.tgz; do
581 echo "file binary-dist $file" >> $out/nix-support/hydra-build-products
582 done
583 '';
584
585 dontInstall = false;
586 doCheck = false;
587 };
588
589 #
590 # collections of build tasks
591 #
592
593 basicAttrs = {
594 inherit tarball;
595 inherit build;
feec80c3
C
596 inherit report;
597 inherit dist;
755320b0 598 inherit profile;
feec80c3
C
599 };
600
d6ce1786
C
601 # artificial dependency on report to ensure that we are not going through
602 # an expensive regression test when there is already something wrong with
603 # the build process.
604 reportFirst = x : if report == null then x else x;
605 testAttrs = reportFirst {
feec80c3
C
606 inherit regress;
607 inherit test;
608 };
609
610in basicAttrs // (if performRegress then testAttrs else {})