about summary refs log tree commit diff
path: root/nixpkgs/pkgs/development/compilers/nim/default.nix
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2021-01-10 07:13:44 +0000
committerAlyssa Ross <hi@alyssa.is>2021-01-12 14:07:16 +0000
commite2698550456abba83c6dcd5d5e5a9990a0b96f8a (patch)
tree79a56f0df3fa55e470d84b4dff6059fbf487ec18 /nixpkgs/pkgs/development/compilers/nim/default.nix
parent1cdc42df888dc98c347e03bd942ed9825a55bcb3 (diff)
parent84d74ae9c9cbed73274b8e4e00be14688ffc93fe (diff)
downloadnixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar
nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar.gz
nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar.bz2
nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar.lz
nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar.xz
nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar.zst
nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.zip
Merge commit '84d74ae9c9cbed73274b8e4e00be14688ffc93fe'
Diffstat (limited to 'nixpkgs/pkgs/development/compilers/nim/default.nix')
-rw-r--r--nixpkgs/pkgs/development/compilers/nim/default.nix288
1 files changed, 229 insertions, 59 deletions
diff --git a/nixpkgs/pkgs/development/compilers/nim/default.nix b/nixpkgs/pkgs/development/compilers/nim/default.nix
index 86518b8db09f..0ec259b66084 100644
--- a/nixpkgs/pkgs/development/compilers/nim/default.nix
+++ b/nixpkgs/pkgs/development/compilers/nim/default.nix
@@ -1,69 +1,239 @@
-# based on https://github.com/nim-lang/Nim/blob/v0.18.0/.travis.yml
+# https://nim-lang.github.io/Nim/packaging.html
 
-{ stdenv, lib, fetchurl, makeWrapper, openssl, pcre, readline,
-  boehmgc, sfml, sqlite }:
-
-stdenv.mkDerivation rec {
-  pname = "nim";
-  version = "1.2.0";
+{ stdenv, lib, fetchgit, fetchurl, makeWrapper, gdb, openssl, pcre, readline
+, boehmgc, sqlite, nim-unwrapped, nim }:
 
+let
+  version = "1.2.6";
   src = fetchurl {
-    url = "https://nim-lang.org/download/${pname}-${version}.tar.xz";
-    sha256 = "0xf56xb42hc92h4xnvk72q4n3ysjbyhf0rg60lc84r9r6wx5i52f";
+    url = "https://nim-lang.org/download/nim-${version}.tar.xz";
+    sha256 = "0zk5qzxayqjw7kq6p92j4008g9bbyilyymhdc5xq9sln5rqym26z";
   };
 
-  enableParallelBuilding = true;
-
-  NIX_LDFLAGS = "-lcrypto -lpcre -lreadline -lgc -lsqlite3";
-
-  # we could create a separate derivation for the "written in c" version of nim
-  # used for bootstrapping, but koch insists on moving the nim compiler around
-  # as part of building it, so it cannot be read-only
-
-  nativeBuildInputs = [
-    makeWrapper
-  ];
-
-  buildInputs = [
-    openssl pcre readline boehmgc sfml sqlite
-  ];
-
-  buildPhase = ''
-    runHook preBuild
-
-    # build.sh wants to write to $HOME/.cache
-    HOME=$TMPDIR
-    sh build.sh
-    ./bin/nim c koch
-    ./koch boot  -d:release \
-                 -d:useGnuReadline \
-                 ${lib.optionals (stdenv.isDarwin || stdenv.isLinux) "-d:nativeStacktrace"}
-    ./koch tools -d:release
-
-    runHook postBuild
-  '';
-
-  installPhase = ''
-    runHook preInstall
-
-    install -Dt $out/bin bin/* koch
-    ./koch install $out
-    mv $out/nim/bin/* $out/bin/ && rmdir $out/nim/bin
-    mv $out/nim/*     $out/     && rmdir $out/nim
-
-    # Fortify hardening appends -O2 to gcc flags which is unwanted for unoptimized nim builds.
-    wrapProgram $out/bin/nim \
-      --run 'NIX_HARDENING_ENABLE=''${NIX_HARDENING_ENABLE/fortify/}' \
-      --suffix PATH : ${lib.makeBinPath [ stdenv.cc ]}
-
-    runHook postInstall
-  '';
-
-  meta = with stdenv.lib; {
+  meta = with lib; {
     description = "Statically typed, imperative programming language";
     homepage = "https://nim-lang.org/";
     license = licenses.mit;
     maintainers = with maintainers; [ ehmry ];
-    platforms = with platforms; linux ++ darwin; # arbitrary
   };
-}
+
+  parseCpu = platform:
+    with platform;
+    # Derive a Nim CPU identifier
+    if isAarch32 then
+      "arm"
+    else if isAarch64 then
+      "arm64"
+    else if isAlpha then
+      "alpha"
+    else if isAvr then
+      "avr"
+    else if isMips && is32bit then
+      "mips"
+    else if isMips && is64bit then
+      "mips64"
+    else if isMsp430 then
+      "msp430"
+    else if isPowerPC && is32bit then
+      "powerpc"
+    else if isPowerPC && is64bit then
+      "powerpc64"
+    else if isRiscV && is64bit then
+      "riscv64"
+    else if isSparc then
+      "sparc"
+    else if isx86_32 then
+      "i386"
+    else if isx86_64 then
+      "amd64"
+    else
+      abort "no Nim CPU support known for ${config}";
+
+  parseOs = platform:
+    with platform;
+    # Derive a Nim OS identifier
+    if isAndroid then
+      "Android"
+    else if isDarwin then
+      "MacOSX"
+    else if isFreeBSD then
+      "FreeBSD"
+    else if isGenode then
+      "Genode"
+    else if isLinux then
+      "Linux"
+    else if isNetBSD then
+      "NetBSD"
+    else if isNone then
+      "Standalone"
+    else if isOpenBSD then
+      "OpenBSD"
+    else if isWindows then
+      "Windows"
+    else if isiOS then
+      "iOS"
+    else
+      abort "no Nim OS support known for ${config}";
+
+  parsePlatform = p: {
+    cpu = parseCpu p;
+    os = parseOs p;
+  };
+
+  nimHost = parsePlatform stdenv.hostPlatform;
+  nimTarget = parsePlatform stdenv.targetPlatform;
+
+  wrapperInputs = rec {
+
+    bootstrap = stdenv.mkDerivation rec {
+      pname = "nim-bootstrap";
+      version = "0.20.0";
+
+      src = fetchgit {
+        # A Git checkout is much smaller than a GitHub tarball.
+        url = "https://github.com/nim-lang/csources.git";
+        rev = "v" + version;
+        sha256 = "0i6vsfy1sgapx43n226q8m0pvn159sw2mhp50zm3hhb9zfijanis";
+      };
+
+      enableParallelBuilding = true;
+
+      installPhase = ''
+        runHook preInstall
+        install -Dt $out/bin bin/nim
+        runHook postInstall
+      '';
+    };
+
+    unwrapped = stdenv.mkDerivation {
+      pname = "nim-unwrapped";
+      inherit version src;
+
+      buildInputs = [ boehmgc openssl pcre readline sqlite ];
+
+      patches = [
+        ./NIM_CONFIG_DIR.patch
+        # Override compiler configuration via an environmental variable
+
+        ./nixbuild.patch
+        # Load libraries at runtime by absolute path
+      ];
+
+      configurePhase = ''
+        runHook preConfigure
+        cp ${bootstrap}/bin/nim bin/
+        echo 'define:nixbuild' >> config/nim.cfg
+        runHook postConfigure
+      '';
+
+      kochArgs = [
+        "--cpu:${nimHost.cpu}"
+        "--os:${nimHost.os}"
+        "-d:release"
+        "-d:useGnuReadline"
+      ] ++ lib.optional (stdenv.isDarwin || stdenv.isLinux)
+        "-d:nativeStacktrace";
+
+      buildPhase = ''
+        runHook preBuild
+        local HOME=$TMPDIR
+        ./bin/nim c koch
+        ./koch boot $kochArgs --parallelBuild:$NIX_BUILD_CORES
+        ./koch tools $kochArgs --parallelBuild:$NIX_BUILD_CORES
+        runHook postBuild
+      '';
+
+      installPhase = ''
+        runHook preInstall
+        install -Dt $out/bin bin/*
+        ln -sf $out/nim/bin/nim $out/bin/nim
+        ./install.sh $out
+        runHook postInstall
+      '';
+
+      inherit meta;
+    };
+  };
+
+  wrapped = let
+    nim = nim-unwrapped;
+    inherit (stdenv) targetPlatform;
+  in stdenv.mkDerivation {
+    name = "${targetPlatform.config}-nim-wrapper-${nim.version}";
+    inherit (nim) version;
+    preferLocalBuild = true;
+
+    nativeBuildInputs = [ makeWrapper ];
+
+    unpackPhase = ''
+      runHook preUnpack
+      tar xf ${nim.src} nim-$version/config/nim.cfg
+      cd nim-$version
+      runHook postUnpack
+    '';
+
+    dontConfigure = true;
+
+    wrapperArgs = [
+      "--prefix PATH : ${lib.makeBinPath [ stdenv.cc gdb ]}:${
+        placeholder "out"
+      }/bin"
+      "--prefix LD_LIBRARY_PATH : ${
+        lib.makeLibraryPath [ stdenv.cc.libc openssl ]
+      }"
+      "--set NIM_CONFIG_PATH ${placeholder "out"}/etc/nim"
+      ''--set NIX_HARDENING_ENABLE "''${NIX_HARDENING_ENABLE/fortify}"''
+      # Fortify hardening appends -O2 to gcc flags which is unwanted for unoptimized nim builds.
+    ];
+
+    buildPhase = with stdenv;
+      let
+        ccType = if cc.isGNU then
+          "gcc"
+        else if cc.isClang then
+          "clang"
+        else
+          abort "no Nim configuration available for ${cc.name}";
+      in ''
+        runHook preBuild
+        cat >> config/nim.cfg << EOF
+
+        define:nixbuild
+        os = ${nimTarget.os}
+        cpu = ${nimTarget.cpu}
+        cc = ${ccType}
+        EOF
+
+        mkdir -p $out/bin $out/etc/nim
+        export cc=$CC
+        export cxx=$CXX
+        substituteAll config/nim.cfg $out/etc/nim/nim.cfg \
+          --replace "cc = gcc" ""
+
+        for binpath in ${nim}/bin/nim?*; do
+          local binname=`basename $binpath`
+          makeWrapper \
+            $binpath $out/bin/${targetPlatform.config}-$binname \
+            $wrapperArgs
+          ln -s $out/bin/${targetPlatform.config}-$binname $out/bin/$binname
+        done
+
+        makeWrapper \
+          ${nim}/nim/bin/nim $out/bin/${targetPlatform.config}-nim \
+          $wrapperArgs
+        ln -s $out/bin/${targetPlatform.config}-nim $out/bin/nim
+
+        runHook postBuild
+      '';
+
+    dontInstall = true;
+
+    meta = meta // {
+      description = nim.meta.description
+        + " (${targetPlatform.config} wrapper)";
+      platforms = lib.platforms.unix;
+    };
+
+  };
+
+in wrapped // wrapperInputs