18 # Some projects do not include a lock file, so you can pass one
20 # Generate shards.nix with `nix-shell -p crystal2nix --run crystal2nix` in the projects root
22 # We support different builders. To make things more straight forward, make it
23 # user selectable instead of trying to autodetect
25 installManPages ? true,
26 # Specify binaries to build in the form { foo.src = "src/foo.cr"; }
27 # The default `crystal build` options can be overridden with { foo.options = [ "--optionname" ]; }
28 crystalBinaries ? { },
29 enableParallelBuilding ? true,
30 # Copy all shards dependencies instead of symlinking and add write permissions
31 # to make environment more local-like
32 copyShardDeps ? false,
37 builtins.elem format [
44 mkDerivationArgs = builtins.removeAttrs args [
52 crystalLib = linkFarm "crystal-lib" (
53 lib.mapAttrsToList (name: value: {
55 path = if (builtins.hasAttr "url" value) then fetchgit value else fetchFromGitHub value;
56 }) (import shardsFile)
59 # We no longer use --no-debug in accordance with upstream's recommendation
66 buildDirectly = shardsFile == null || crystalBinaries != { };
70 lib.concatStringsSep " " (
75 ++ lib.optionals enableParallelBuilding [
82 (attrs.src or (throw "No source file for crystal binary ${bin} provided"))
83 (lib.concatStringsSep " " (attrs.options or defaultOptions))
93 args.configurePhase or (lib.concatStringsSep "\n" (
95 "runHook preConfigure"
97 ++ lib.optional (lockFile != null) "cp ${lockFile} ./shard.lock"
98 ++ lib.optionals (shardsFile != null) [
99 "test -e lib || mkdir lib"
101 if copyShardDeps then
102 "for d in ${crystalLib}/*; do cp -r $d/ lib/; done; chmod -R +w lib/"
104 "for d in ${crystalLib}/*; do ln -s $d lib/; done"
106 "cp shard.lock lib/.shards.info"
108 ++ [ "runHook postConfigure" ]
111 CRFLAGS = lib.concatStringsSep " " defaultOptions;
113 PREFIX = placeholder "out";
115 inherit enableParallelBuilding;
118 args.buildInputs or [ ]
120 ++ lib.optional (lib.versionAtLeast crystal.version "1.8") pcre2;
123 args.nativeBuildInputs or [ ]
132 ++ lib.optional (format != "crystal") shards;
135 args.buildPhase or (lib.concatStringsSep "\n" (
139 ++ lib.optional (format == "make") "make \${buildTargets:-build} $makeFlags"
140 ++ lib.optionals (format == "crystal") (lib.mapAttrsToList mkCrystalBuildArgs crystalBinaries)
142 lib.optional (format == "shards")
143 "shards build --local --production ${lib.concatStringsSep " " (args.options or defaultOptions)}"
144 ++ [ "runHook postBuild" ]
148 args.installPhase or (lib.concatStringsSep "\n" (
152 ++ lib.optional (format == "make") "make \${installTargets:-install} $installFlags"
153 ++ lib.optionals (format == "crystal") (
156 lib.escapeShellArgs [
158 "${placeholder "out"}/bin/${bin}"
161 '') (lib.attrNames crystalBinaries)
163 ++ lib.optional (format == "shards") "install -Dm555 bin/* -t $out/bin"
166 for f in README* *.md LICENSE; do
167 test -f $f && install -Dm444 $f -t $out/share/doc/${args.pname}
171 ++ (lib.optional installManPages ''
173 installManPage man/*.?
177 "remove-references-to -t ${lib.getLib crystal} $out/bin/*"
178 "runHook postInstall"
182 doCheck = args.doCheck or true;
185 args.checkPhase or (lib.concatStringsSep "\n" (
189 ++ lib.optional (format == "make") "make \${checkTarget:-test} $checkFlags"
190 ++ lib.optional (format != "make") "crystal \${checkTarget:-spec} $checkFlags"
191 ++ [ "runHook postCheck" ]
194 doInstallCheck = args.doInstallCheck or true;
197 args.installCheckPhase or ''
198 for f in $out/bin/*; do
199 if [ $f == $out/bin/*.dwarf ]; then
202 $f --help > /dev/null
206 meta = args.meta or { } // {
207 platforms = args.meta.platforms or crystal.meta.platforms;