From 8c60f67f2dbc0b1eeddf67db317964ae3619d646 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Mon, 26 Aug 2019 16:31:48 +0200 Subject: [PATCH 1/6] mint: Fix build --- pkgs/development/compilers/mint/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/development/compilers/mint/default.nix b/pkgs/development/compilers/mint/default.nix index 1c8e9fb7eb2..95b30da5b75 100644 --- a/pkgs/development/compilers/mint/default.nix +++ b/pkgs/development/compilers/mint/default.nix @@ -3,7 +3,7 @@ # wget https://raw.githubusercontent.com/mint-lang/mint/0.3.1/shard.lock # nix-shell -p crystal libyaml --run 'crystal run crystal2nix.cr' # -{stdenv, lib, fetchFromGitHub, crystal, zlib, openssl, duktape, which, libyaml }: +{stdenv, lib, fetchFromGitHub, crystal, zlib, openssl_1_0_2, duktape, which, libyaml }: let crystalPackages = lib.mapAttrs (name: src: stdenv.mkDerivation { @@ -42,7 +42,7 @@ stdenv.mkDerivation rec { sha256 = "0vxbx38c390rd2ysvbwgh89v2232sh5rbsp3nk9wzb70jybpslvl"; }; - nativeBuildInputs = [ which crystal zlib openssl duktape libyaml ]; + nativeBuildInputs = [ which crystal zlib openssl_1_0_2 duktape libyaml ]; buildPhase = '' mkdir -p $out/bin tmp From a3aec20f266c57d989524f02b1243b4ad24020a2 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Mon, 26 Aug 2019 18:22:55 +0200 Subject: [PATCH 2/6] Implement crystal.buildCrystalPackage --- .../compilers/crystal/build-package.nix | 53 +++++++++++++++++++ .../development/compilers/crystal/default.nix | 11 ++-- 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 pkgs/development/compilers/crystal/build-package.nix diff --git a/pkgs/development/compilers/crystal/build-package.nix b/pkgs/development/compilers/crystal/build-package.nix new file mode 100644 index 00000000000..8ffa89a11b4 --- /dev/null +++ b/pkgs/development/compilers/crystal/build-package.nix @@ -0,0 +1,53 @@ +{ stdenv, lib, crystal, linkFarm, fetchFromGitHub }: +{ # 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 ? {} +, ... +}@args: +let + mkDerivationArgs = builtins.removeAttrs args [ "shardsFile" "crystalBinaries" ]; + + crystalLib = linkFarm "crystal-lib" (lib.mapAttrsToList (name: value: { + inherit name; + path = fetchFromGitHub value; + }) (import shardsFile)); + + defaultOptions = [ "--release" "--progress" "--no-debug" "--verbose" ]; + +in stdenv.mkDerivation (mkDerivationArgs // { + + configurePhase = args.configurePhase or '' + runHook preConfigure + ${lib.optionalString (shardsFile != null) "ln -s ${crystalLib} lib"} + runHook postConfigure + ''; + + buildInputs = args.buildInputs or [] ++ [ crystal ]; + + 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 + ''; + + 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 + ''; + + meta = args.meta or {} // { + platforms = args.meta.platforms or crystal.meta.platforms; + }; +}) diff --git a/pkgs/development/compilers/crystal/default.nix b/pkgs/development/compilers/crystal/default.nix index db57bc3e9df..0cb0a3733ed 100644 --- a/pkgs/development/compilers/crystal/default.nix +++ b/pkgs/development/compilers/crystal/default.nix @@ -1,6 +1,7 @@ { stdenv, lib, fetchFromGitHub, fetchurl, makeWrapper , coreutils, git, gmp, nettools, openssl, readline, tzdata, libxml2, libyaml -, boehmgc, libatomic_ops, pcre, libevent, libiconv, llvm, clang, which, zlib }: +, boehmgc, libatomic_ops, pcre, libevent, libiconv, llvm, clang, which, zlib +, callPackage }: # We need multiple binaries as a given binary isn't always able to build # (even slightly) older or newer versions. @@ -37,7 +38,7 @@ let }; generic = { version, sha256, binary, doCheck ? true }: - stdenv.mkDerivation rec { + let compiler = stdenv.mkDerivation rec { pname = "crystal"; inherit doCheck version; @@ -134,6 +135,10 @@ let export PATH=${lib.makeBinPath checkInputs}:$PATH ''; + passthru.buildCrystalPackage = callPackage ./build-package.nix { + crystal = compiler; + }; + meta = with lib; { description = "A compiled language with Ruby like syntax and type inference"; homepage = https://crystal-lang.org/; @@ -141,7 +146,7 @@ let maintainers = with maintainers; [ manveru david50407 peterhoeg ]; platforms = builtins.attrNames archs; }; - }; + }; in compiler; in rec { binaryCrystal_0_26 = genericBinary { From 1ffdf01777360f548cc7c10ef5b168cbe78fd183 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Mon, 26 Aug 2019 18:23:55 +0200 Subject: [PATCH 3/6] crystal2nix: Put it into pkgs --- .../compilers/{mint => crystal}/crystal2nix.cr | 2 +- .../compilers/crystal/crystal2nix.nix | 16 ++++++++++++++++ pkgs/development/compilers/crystal/default.nix | 2 ++ pkgs/top-level/all-packages.nix | 3 ++- 4 files changed, 21 insertions(+), 2 deletions(-) rename pkgs/development/compilers/{mint => crystal}/crystal2nix.cr (94%) create mode 100644 pkgs/development/compilers/crystal/crystal2nix.nix diff --git a/pkgs/development/compilers/mint/crystal2nix.cr b/pkgs/development/compilers/crystal/crystal2nix.cr similarity index 94% rename from pkgs/development/compilers/mint/crystal2nix.cr rename to pkgs/development/compilers/crystal/crystal2nix.cr index f608102a37b..0610de5cfa4 100644 --- a/pkgs/development/compilers/mint/crystal2nix.cr +++ b/pkgs/development/compilers/crystal/crystal2nix.cr @@ -26,7 +26,7 @@ File.open "shards.nix", "w+" do |file| sha256 = "" args = ["--url", url, "--rev", rev] - Process.run("nix-prefetch-git", args: args) do |x| + Process.run("@nixPrefetchGit@", args: args) do |x| x.error.each_line { |e| puts e } sha256 = PrefetchJSON.from_json(x.output).sha256 end diff --git a/pkgs/development/compilers/crystal/crystal2nix.nix b/pkgs/development/compilers/crystal/crystal2nix.nix new file mode 100644 index 00000000000..ac69b9b3d96 --- /dev/null +++ b/pkgs/development/compilers/crystal/crystal2nix.nix @@ -0,0 +1,16 @@ +{ lib, crystal, nix-prefetch-git }: +crystal.buildCrystalPackage { + pname = "crystal2nix"; + version = "unstable-2018-07-31"; + + nixPrefetchGit = "${lib.getBin nix-prefetch-git}/bin/nix-prefetch-git"; + unpackPhase = "substituteAll ${./crystal2nix.cr} crystal2nix.cr"; + + crystalBinaries.crystal2nix.src = "crystal2nix.cr"; + + meta = with lib; { + description = "Utility to convert Crystal's shard.lock files to a Nix file"; + license = licenses.mit; + maintainers = [ maintainers.manveru ]; + }; +} diff --git a/pkgs/development/compilers/crystal/default.nix b/pkgs/development/compilers/crystal/default.nix index 0cb0a3733ed..c7a74880e44 100644 --- a/pkgs/development/compilers/crystal/default.nix +++ b/pkgs/development/compilers/crystal/default.nix @@ -212,4 +212,6 @@ in rec { }; crystal = crystal_0_30; + + crystal2nix = callPackage ./crystal2nix.nix {}; } diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index cbe997367c8..d788224cf39 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -7453,7 +7453,8 @@ in crystal_0_27 crystal_0_29 crystal_0_30 - crystal; + crystal + crystal2nix; icr = callPackage ../development/tools/icr {}; From 2f92cd6960f26f1f45e862cf4fea277305a07a4e Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Mon, 26 Aug 2019 18:24:45 +0200 Subject: [PATCH 4/6] mint: Use buildCrystalPackage --- pkgs/development/compilers/mint/default.nix | 59 ++++----------------- 1 file changed, 11 insertions(+), 48 deletions(-) diff --git a/pkgs/development/compilers/mint/default.nix b/pkgs/development/compilers/mint/default.nix index 95b30da5b75..5f72bd3649b 100644 --- a/pkgs/development/compilers/mint/default.nix +++ b/pkgs/development/compilers/mint/default.nix @@ -1,40 +1,7 @@ -# Updating the dependencies for this package: -# -# wget https://raw.githubusercontent.com/mint-lang/mint/0.3.1/shard.lock -# nix-shell -p crystal libyaml --run 'crystal run crystal2nix.cr' -# -{stdenv, lib, fetchFromGitHub, crystal, zlib, openssl_1_0_2, duktape, which, libyaml }: -let - crystalPackages = lib.mapAttrs (name: src: - stdenv.mkDerivation { - name = lib.replaceStrings ["/"] ["-"] name; - src = fetchFromGitHub src; - phases = "installPhase"; - installPhase = ''cp -r $src $out''; - passthru = { libName = name; }; - } - ) (import ./shards.nix); - - crystalLib = stdenv.mkDerivation { - name = "crystal-lib"; - src = lib.attrValues crystalPackages; - libNames = lib.mapAttrsToList (k: v: [k v]) crystalPackages; - phases = "buildPhase"; - buildPhase = '' - mkdir -p $out - linkup () { - while [ "$#" -gt 0 ]; do - ln -s $2 $out/$1 - shift; shift - done - } - linkup $libNames - ''; - }; -in -stdenv.mkDerivation rec { +{ lib, fetchFromGitHub, crystal, zlib, openssl_1_0_2, duktape, which, libyaml }: +crystal.buildCrystalPackage rec { version = "0.5.0"; - name = "mint-${version}"; + pname = "mint"; src = fetchFromGitHub { owner = "mint-lang"; repo = "mint"; @@ -42,23 +9,19 @@ stdenv.mkDerivation rec { sha256 = "0vxbx38c390rd2ysvbwgh89v2232sh5rbsp3nk9wzb70jybpslvl"; }; - nativeBuildInputs = [ which crystal zlib openssl_1_0_2 duktape libyaml ]; + buildInputs = [ openssl_1_0_2 ]; - buildPhase = '' - mkdir -p $out/bin tmp - cd tmp - ln -s ${crystalLib} lib - cp -r $src/* . - crystal build src/mint.cr -o $out/bin/mint --verbose --progress --release --no-debug - ''; - - installPhase = ''true''; + # Update with + # nix-shell -p crystal2nix --run crystal2nix + # with mint's shard.lock file in the current directory + shardsFile = ./shards.nix; + crystalBinaries.mint.src = "src/mint.cr"; meta = { description = "A refreshing language for the front-end web"; homepage = https://mint-lang.com/; - license = stdenv.lib.licenses.bsd3; - maintainers = with stdenv.lib.maintainers; [ manveru ]; + license = lib.licenses.bsd3; + maintainers = with lib.maintainers; [ manveru ]; platforms = [ "x86_64-linux" "i686-linux" "x86_64-darwin" ]; }; } From 1d0749139d2edc1ce20ae71e5258cf1f802fba48 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Mon, 26 Aug 2019 20:12:15 +0200 Subject: [PATCH 5/6] docs: Add Crystal language framework section --- doc/languages-frameworks/crystal.section.md | 71 +++++++++++++++++++++ doc/languages-frameworks/index.xml | 1 + 2 files changed, 72 insertions(+) create mode 100644 doc/languages-frameworks/crystal.section.md diff --git a/doc/languages-frameworks/crystal.section.md b/doc/languages-frameworks/crystal.section.md new file mode 100644 index 00000000000..07bfc65a553 --- /dev/null +++ b/doc/languages-frameworks/crystal.section.md @@ -0,0 +1,71 @@ +# Crystal + +## Building a Crystal package + +This section uses [Mint](https://github.com/mint-lang/mint) as an example for how to build a Crystal package. + +If the Crystal project has any dependencies, the first step is to get a `shards.nix` file encoding those. Get a copy of the project and go to its root directory such that its `shard.lock` file is in the current directory, then run `crystal2nix` in it +```bash +$ git clone https://github.com/mint-lang/mint +$ cd mint +$ git checkout 0.5.0 +$ nix-shell -p crystal2nix --run crystal2nix +``` + +This should have generated a `shards.nix` file. + +Next create a Nix file for your derivation and use `pkgs.crystal.buildCrystalPackage` as follows: +```nix +with import {}; +crystal.buildCrystalPackage rec { + pname = "mint"; + version = "0.5.0"; + + src = fetchFromGitHub { + owner = "mint-lang"; + repo = "mint"; + rev = version; + sha256 = "0vxbx38c390rd2ysvbwgh89v2232sh5rbsp3nk9wzb70jybpslvl"; + }; + + # Insert the path to your shards.nix file here + shardsFile = ./shards.nix; + + ... +} +``` + +This won't build anything yet, because we haven't told it what files build. We can specify a mapping from binary names to source files with the `crystalBinaries` attribute. The project's compilation instructions should show this. For Mint, the binary is called "mint", which is compiled from the source file `src/mint.cr`, so we'll specify this as follows: + +```nix + crystalBinaries.mint.src = "src/mint.cr"; + + # ... +``` + +Additionally you can override the default `crystal build` options (which are currently `--release --progress --no-debug --verbose`) with + +```nix + crystalBinaries.mint.options = [ "--release" "--verbose" ]; +``` + +Depending on the project, you might need additional steps to get it to compile successfully. In Mint's case, we need to link against openssl, so in the end the Nix file looks as follows: + +```nix +with import {}; +crystal.buildCrystalPackage rec { + version = "0.5.0"; + pname = "mint"; + src = fetchFromGitHub { + owner = "mint-lang"; + repo = "mint"; + rev = version; + sha256 = "0vxbx38c390rd2ysvbwgh89v2232sh5rbsp3nk9wzb70jybpslvl"; + }; + + shardsFile = ./shards.nix; + crystalBinaries.mint.src = "src/mint.cr"; + + buildInputs = [ openssl_1_0_2 ]; +} +``` diff --git a/doc/languages-frameworks/index.xml b/doc/languages-frameworks/index.xml index 4564df98fe9..cd4e95cfae6 100644 --- a/doc/languages-frameworks/index.xml +++ b/doc/languages-frameworks/index.xml @@ -32,4 +32,5 @@ + From 7f6a9eef2602a9ddb369ec3318ee99e98054989b Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Thu, 29 Aug 2019 03:31:14 +0200 Subject: [PATCH 6/6] crystal: Fix runtime by switching to openssl_1_0_2 This makes `crystal play` work --- pkgs/development/compilers/crystal/default.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/development/compilers/crystal/default.nix b/pkgs/development/compilers/crystal/default.nix index c7a74880e44..2bc3d396da6 100644 --- a/pkgs/development/compilers/crystal/default.nix +++ b/pkgs/development/compilers/crystal/default.nix @@ -1,5 +1,5 @@ { stdenv, lib, fetchFromGitHub, fetchurl, makeWrapper -, coreutils, git, gmp, nettools, openssl, readline, tzdata, libxml2, libyaml +, coreutils, git, gmp, nettools, openssl_1_0_2, readline, tzdata, libxml2, libyaml , boehmgc, libatomic_ops, pcre, libevent, libiconv, llvm, clang, which, zlib , callPackage }: @@ -20,7 +20,7 @@ let arch = archs."${stdenv.system}" or (throw "system ${stdenv.system} not supported"); - checkInputs = [ git gmp openssl readline libxml2 libyaml ]; + checkInputs = [ git gmp openssl_1_0_2 readline libxml2 libyaml ]; genericBinary = { version, sha256s, rel ? 1 }: stdenv.mkDerivation rec { @@ -73,7 +73,7 @@ let buildInputs = [ boehmgc libatomic_ops pcre libevent libyaml - llvm zlib openssl + llvm zlib openssl_1_0_2 ] ++ stdenv.lib.optionals stdenv.isDarwin [ libiconv ];