btrbk: add mainProgram (#356350)
[NixPkgs.git] / pkgs / development / compilers / gerbil / gerbil-support.nix
blobe395d8ca1dec325687307b6eac6e02c727b3fc22
1 { pkgs, lib, callPackage, ... }:
3 let
4   inherit (builtins) filterSource;
6   inherit (lib)
7     commitIdFromGitRepo
8     concatStringsSep
9     elem
10     elemAt
11     hasSuffix
12     listToAttrs
13     mapAttrs
14     optionalString
15     pathExists
16     readFile
17     removeSuffix
18     substring
19     traceSeqN
20     ;
22   inherit (lib.strings) match;
24   # Implicitly calls through to this file, similar to `let .. in` or `rec`.
25   inherit (pkgs.gerbil-support)
26     callPpp
27     gerbilLoadPath
28     gerbilPackage
29     gerbilPackages-unstable
30     gerbilSkippableFiles
31     gerbilSourceFilter
32     overrideSrcIfShaDiff
33     ppaToPl
34     pppToKV
35     pppToName
36     ppplToPpa
37     prePackage-defaults
38     prePackages-unstable
39     resolve-pre-src
40     sha256-of-pre-src
41     view
42     ;
46   pppToName = ppp: removeSuffix ".nix" (baseNameOf ppp); # from pre-package path to name
47   callPpp = ppp: callPackage ppp prePackage-defaults; # from pre-package path to pre-package
48   pppToKV = ppp: { name = pppToName ppp; value = callPpp ppp; }; # from pre-package path to name
49   ppplToPpa = ppps: listToAttrs (map pppToKV ppps); # from pre-package path list to name/pre-package attr
51   prePackages-unstable =
52     ppplToPpa
53       [ ./gerbil-leveldb.nix ./gerbil-lmdb.nix ./gerbil-mysql.nix
54         ./gerbil-libxml.nix ./gerbil-libyaml.nix
55         ./smug-gerbil.nix # ./ftw.nix
56         ./gerbil-utils.nix ./gerbil-crypto.nix ./gerbil-poo.nix
57         ./gerbil-persist.nix ./gerbil-ethereum.nix
58         # ./gerbil-libp2p.nix
59         ./glow-lang.nix
60       ];
62   prePackage-defaults = {
63     gerbil = pkgs.gerbil-unstable;
64     gambit-params = pkgs.gambit-support.unstable-params;
65     gerbilPackages = gerbilPackages-unstable;
66     git-version = "";
67     version-path = "";
68     gerbilInputs = [];
69     nativeBuildInputs = [];
70     buildInputs = [];
71     buildScript = "./build.ss";
72     postInstall = "";
73     softwareName = "";
74   };
76   ppaToPl = mapAttrs (_: gerbilPackage);
77   gerbilPackages-unstable = ppaToPl prePackages-unstable;
79   resolve-pre-src = pre-src: pre-src.fun (removeAttrs pre-src ["fun"]);
81   gerbilVersionFromGit = srcDir: version-path:
82     let version-file = "${srcDir}/${version-path}.ss"; in
83     if pathExists version-file then
84       let m =
85         match "\\(import :clan/versioning.*\\)\n\\(register-software \"([-_.A-Za-z0-9]+)\" \"([-_.A-Za-z0-9]+)\"\\) ;; ([-0-9]+)\n"
86           (readFile version-file); in
87           { version = "${elemAt m 2}-git"; git-version = elemAt m 1; }
88      else { version = "0.0-git";
89             git-version = let gitpath = "${srcDir}/.git"; in
90               if pathExists gitpath then commitIdFromGitRepo gitpath else "0"; };
92   gerbilSkippableFiles = [".git" ".build" ".build_outputs" "run" "result" "dep" "BLAH" "tmp.nix"];
94   gerbilSourceFilter = path: type:
95     let baseName = baseNameOf path; in
96       ! (elem baseName gerbilSkippableFiles || hasSuffix "~" baseName);
98   gerbilFilterSource = filterSource gerbilSourceFilter;
100   # Use this function in any package that uses Gerbil libraries, to define the GERBIL_LOADPATH.
101   gerbilLoadPath =
102     gerbilInputs: concatStringsSep ":" (map (x: x + "/gerbil/lib") gerbilInputs);
104   path-src = path: { fun = _: path; };
106   view = traceSeqN 4;
108   sha256-of-pre-src = pre-src: if pre-src ? sha256 then pre-src.sha256 else "none";
110   overrideSrcIfShaDiff = name: new-pre-src: super:
111     let old-sha256 = sha256-of-pre-src super.${name}.pre-src;
112         new-sha256 = sha256-of-pre-src new-pre-src; in
113     if old-sha256 == new-sha256 then {} else
114     view "Overriding ${name} old-sha256: ${old-sha256} new-sha256: ${new-sha256}"
115     { ${name} = super.${name} // {
116                        pre-src = new-pre-src;
117                        version = "override";
118                        git-version = if new-pre-src ? rev
119                                      then substring 0 7 new-pre-src.rev
120                                      else "unknown";};
121                      };
123   pkgsOverrideGerbilPackageSrc = name: pre-src: pkgs: super: {
124     gerbil-support = (super-support:
125       { prePackages-unstable =
126           (super-ppu: super-ppu // (overrideSrcIfShaDiff name pre-src super-ppu))
127           super-support.prePackages-unstable;}) super.gerbil-support;};
129   # Use this function to create a Gerbil library. See gerbil-utils as an example.
130   gerbilPackage = prePackage:
131     let pre-pkg = prePackage-defaults // prePackage;
132         inherit (pre-pkg) pname version pre-src git-version meta
133           softwareName gerbil-package version-path gerbil gambit-params
134           gerbilInputs nativeBuildInputs buildInputs buildScript postInstall;
135         buildInputs_ = buildInputs; in
136     pkgs.gccStdenv.mkDerivation rec { # See ../gambit/build.nix regarding why we use gccStdenv
137       inherit meta pname version nativeBuildInputs postInstall;
138       passthru = {
139         inherit pre-pkg;
140       };
141       src = resolve-pre-src pre-src;
142       buildInputs = [ gerbil ] ++ gerbilInputs ++ buildInputs_;
144       postPatch = ''
145         set -e ;
146         ${optionalString (version-path != "")
147           ''echo -e '(import :clan/versioning${concatStringsSep ""
148                      (map (x: let px = x.passthru.pre-pkg; in
149                               optionalString (px.version-path != "")
150                                 " :${px.gerbil-package}/${px.version-path}")
151                           gerbilInputs)
152                      })\n(register-software "${softwareName}" "v${git-version}")\n' > "${version-path}.ss"''}
153         patchShebangs . ;
154       '';
156       postConfigure = ''
157         export GERBIL_BUILD_CORES=$NIX_BUILD_CORES
158         export GERBIL_PATH=$PWD/.build
159         export GERBIL_LOADPATH=${gerbilLoadPath (["$out"] ++ gerbilInputs)}
160         ${pkgs.gambit-support.export-gambopt gambit-params}
161       '';
163       buildPhase = ''
164         runHook preBuild
165         ${buildScript}
166         runHook postBuild
167       '';
169       installPhase = ''
170         runHook preInstall
171         mkdir -p $out/gerbil
172         cp -fa .build/* $out/gerbil/
173         if [[ -d $out/gerbil/bin ]] ; then
174           ( cd $out/gerbil
175             bins=$(find ../gerbil/bin -type f)
176             if [[ -n $bins ]] ; then
177               ( mkdir -p ../bin
178                 cd ..
179                 ln -s $bins bin
180               )
181             fi
182           )
183         fi
184         runHook postInstall
185       '';
187       dontFixup = true;
189       checkPhase = ''
190         runHook preCheck
191         if [[ -f unit-tests.ss ]] ; then
192           export GERBIL_APPLICATION_HOME=$PWD
193           ./unit-tests.ss version
194           ./unit-tests.ss
195         else
196           echo "No gerbil-utils style unit-tests.ss detected for ${pname} ${version}.";
197         fi
198         runHook postCheck
199       '';
201       doCheck = true;
202     };