diff --git a/pkgs/development/compilers/crystal/build-package.nix b/pkgs/development/compilers/crystal/build-package.nix index 8ffa89a11b4..9cf5701d12f 100644 --- a/pkgs/development/compilers/crystal/build-package.nix +++ b/pkgs/development/compilers/crystal/build-package.nix @@ -1,6 +1,9 @@ -{ stdenv, lib, crystal, linkFarm, fetchFromGitHub }: -{ # Generate shards.nix with `nix-shell -p crystal2nix --run crystal2nix` in the projects root - shardsFile ? null +{ stdenv, lib, crystal, shards, git, pkgconfig, which, linkFarm, fetchFromGitHub }: +{ + # Some projects do not include a lock file, so you can pass one + lockFile ? null + # Generate shards.nix with `nix-shell -p crystal2nix --run crystal2nix` in the projects root +, shardsFile ? null # Specify binaries to build in the form { foo.src = "src/foo.cr"; } # The default `crystal build` options can be overridden with { foo.options = [ "--no-debug" ]; } , crystalBinaries ? {} @@ -9,45 +12,102 @@ let mkDerivationArgs = builtins.removeAttrs args [ "shardsFile" "crystalBinaries" ]; - crystalLib = linkFarm "crystal-lib" (lib.mapAttrsToList (name: value: { - inherit name; - path = fetchFromGitHub value; - }) (import shardsFile)); + crystalLib = linkFarm "crystal-lib" ( + lib.mapAttrsToList ( + name: value: { + inherit name; + path = fetchFromGitHub value; + } + ) (import shardsFile) + ); - defaultOptions = [ "--release" "--progress" "--no-debug" "--verbose" ]; + # we previously had --no-debug here but that is not recommended by upstream + defaultOptions = [ "--release" "--progress" "--verbose" ]; -in stdenv.mkDerivation (mkDerivationArgs // { + buildDirectly = shardsFile == null || crystalBinaries != {}; +in +stdenv.mkDerivation ( + mkDerivationArgs // { - configurePhase = args.configurePhase or '' - runHook preConfigure - ${lib.optionalString (shardsFile != null) "ln -s ${crystalLib} lib"} - runHook postConfigure - ''; + configurePhase = args.configurePhase or '' + runHook preConfigure - buildInputs = args.buildInputs or [] ++ [ crystal ]; + ${lib.optionalString (lockFile != null) "ln -s ${lockFile} ./shard.lock"} + ${lib.optionalString (shardsFile != null) "ln -s ${crystalLib} lib"} - buildPhase = args.buildPhase or '' - runHook preBuild - ${lib.concatStringsSep "\n" (lib.mapAttrsToList (bin: attrs: '' - crystal ${lib.escapeShellArgs ([ - "build" - "-o" bin - (attrs.src or (throw "No source file for crystal binary ${bin} provided")) - ] ++ attrs.options or defaultOptions)} - '') crystalBinaries)} - runHook postBuild - ''; + runHook postConfigure + ''; - installPhase = args.installPhase or '' - runHook preInstall - mkdir -p "$out/bin" - ${lib.concatMapStringsSep "\n" (bin: '' - mv ${lib.escapeShellArgs [ bin "${placeholder "out"}/bin/${bin}" ]} - '') (lib.attrNames crystalBinaries)} - runHook postInstall - ''; + CRFLAGS = lib.concatStringsSep " " defaultOptions; - meta = args.meta or {} // { - platforms = args.meta.platforms or crystal.meta.platforms; - }; -}) + buildInputs = args.buildInputs or [] ++ [ crystal shards ]; + + nativeBuildInputs = args.nativeBuildInputs or [] ++ [ git pkgconfig which ]; + + buildPhase = args.buildPhase or ( + '' + runHook preBuild + + if [ -e Makefile ]; then + echo " ** building with make" + + make ''${buildTargets:-build} $buildFlags + else + '' + ( + if buildDirectly then '' + echo " ** building with crystal" + + ${lib.concatStringsSep "\n" ( + lib.mapAttrsToList ( + bin: attrs: '' + crystal ${lib.escapeShellArgs ( + [ + "build" + "-o" + bin + (attrs.src or (throw "No source file for crystal binary ${bin} provided")) + ] ++ attrs.options or defaultOptions + )} + '' + ) crystalBinaries + )} + '' else '' + echo " ** building with shards" + shards build --local --production ${lib.concatStringsSep " " defaultOptions} + '' + ) + '' + fi + + runHook postBuild + '' + ); + + installPhase = args.installPhase or ( + '' + runHook preInstall + + if [ -e Makefile ]; then + make ''${installTargets:-install} $installFlags + else + '' + ( + if buildDirectly then + lib.concatMapStringsSep "\n" ( + bin: '' + install -Dm555 ${lib.escapeShellArgs [ bin "${placeholder "out"}/bin/${bin}" ]} + '' + ) (lib.attrNames crystalBinaries) + else '' + shards install + '' + ) + '' + fi + + runHook postInstall + '' + ); + + meta = args.meta or {} // { + platforms = args.meta.platforms or crystal.meta.platforms; + }; + } +)