lol
at 24.05-pre 325 lines 9.4 kB view raw
1# https://nim-lang.github.io/Nim/packaging.html 2# https://nim-lang.org/docs/nimc.html 3 4{ lib, callPackage, buildPackages, stdenv, fetchurl, fetchgit, fetchFromGitHub 5, makeWrapper, openssl, pcre, readline, boehmgc, sqlite, Security, nim-unwrapped 6, nim-unwrapped-2, nim }: 7 8let 9 parseCpu = platform: 10 with platform; 11 # Derive a Nim CPU identifier 12 if isAarch32 then 13 "arm" 14 else if isAarch64 then 15 "arm64" 16 else if isAlpha then 17 "alpha" 18 else if isAvr then 19 "avr" 20 else if isMips && is32bit then 21 "mips" 22 else if isMips && is64bit then 23 "mips64" 24 else if isMsp430 then 25 "msp430" 26 else if isPower && is32bit then 27 "powerpc" 28 else if isPower && is64bit then 29 "powerpc64" 30 else if isRiscV && is64bit then 31 "riscv64" 32 else if isSparc then 33 "sparc" 34 else if isx86_32 then 35 "i386" 36 else if isx86_64 then 37 "amd64" 38 else 39 abort "no Nim CPU support known for ${config}"; 40 41 parseOs = platform: 42 with platform; 43 # Derive a Nim OS identifier 44 if isAndroid then 45 "Android" 46 else if isDarwin then 47 "MacOSX" 48 else if isFreeBSD then 49 "FreeBSD" 50 else if isGenode then 51 "Genode" 52 else if isLinux then 53 "Linux" 54 else if isNetBSD then 55 "NetBSD" 56 else if isNone then 57 "Standalone" 58 else if isOpenBSD then 59 "OpenBSD" 60 else if isWindows then 61 "Windows" 62 else if isiOS then 63 "iOS" 64 else 65 abort "no Nim OS support known for ${config}"; 66 67 parsePlatform = p: { 68 cpu = parseCpu p; 69 os = parseOs p; 70 }; 71 72 nimHost = parsePlatform stdenv.hostPlatform; 73 nimTarget = parsePlatform stdenv.targetPlatform; 74 75in { 76 77 nim-unwrapped = stdenv.mkDerivation (finalAttrs: { 78 pname = "nim-unwrapped"; 79 version = "1.6.14"; 80 strictDeps = true; 81 82 src = fetchurl { 83 url = "https://nim-lang.org/download/nim-${finalAttrs.version}.tar.xz"; 84 hash = "sha256-0HDS8oriQA33/kpJ7OufRc1TmQaxB0gYVqCveo+oLck="; 85 }; 86 87 buildInputs = [ boehmgc openssl pcre readline sqlite ] 88 ++ lib.optional stdenv.isDarwin Security; 89 90 patches = [ 91 ./NIM_CONFIG_DIR.patch 92 # Override compiler configuration via an environmental variable 93 94 ./nixbuild.patch 95 # Load libraries at runtime by absolute path 96 97 ./extra-mangling.patch 98 # Mangle store paths of modules to prevent runtime dependence. 99 ] ++ lib.optional (!stdenv.hostPlatform.isWindows) ./toLocation.patch; 100 101 configurePhase = let 102 bootstrapCompiler = stdenv.mkDerivation { 103 pname = "nim-bootstrap"; 104 inherit (finalAttrs) version src preBuild; 105 enableParallelBuilding = true; 106 installPhase = '' 107 runHook preInstall 108 install -Dt $out/bin bin/nim 109 runHook postInstall 110 ''; 111 }; 112 in '' 113 runHook preConfigure 114 cp ${bootstrapCompiler}/bin/nim bin/ 115 echo 'define:nixbuild' >> config/nim.cfg 116 runHook postConfigure 117 ''; 118 119 kochArgs = [ 120 "--cpu:${nimHost.cpu}" 121 "--os:${nimHost.os}" 122 "-d:release" 123 "-d:useGnuReadline" 124 ] ++ lib.optional (stdenv.isDarwin || stdenv.isLinux) "-d:nativeStacktrace"; 125 126 preBuild = lib.optionalString (stdenv.isDarwin && stdenv.isAarch64) '' 127 substituteInPlace makefile \ 128 --replace "aarch64" "arm64" 129 ''; 130 131 buildPhase = '' 132 runHook preBuild 133 local HOME=$TMPDIR 134 ./bin/nim c --parallelBuild:$NIX_BUILD_CORES koch 135 ./koch boot $kochArgs --parallelBuild:$NIX_BUILD_CORES 136 ./koch toolsNoExternal $kochArgs --parallelBuild:$NIX_BUILD_CORES 137 ./bin/nim js -d:release tools/dochack/dochack.nim 138 runHook postBuild 139 ''; 140 141 installPhase = '' 142 runHook preInstall 143 install -Dt $out/bin bin/* 144 ln -sf $out/nim/bin/nim $out/bin/nim 145 ln -sf $out/nim/lib $out/lib 146 ./install.sh $out 147 cp -a tools $out/nim/ 148 runHook postInstall 149 ''; 150 151 meta = with lib; { 152 description = "Statically typed, imperative programming language"; 153 homepage = "https://nim-lang.org/"; 154 license = licenses.mit; 155 mainProgram = "nim"; 156 maintainers = with maintainers; [ ehmry ]; 157 }; 158 }); 159 160 nim-unwrapped-2 = nim-unwrapped.overrideAttrs (finalAttrs: rec { 161 version = "2.0.0"; 162 src = fetchurl { 163 url = "https://nim-lang.org/download/nim-${version}.tar.xz"; 164 hash = "sha256-vWEB2EADb7eOk6ad9s8/n9DCHNdUtpX/hKO0rdjtCvc="; 165 }; 166 167 patches = [ 168 ./NIM_CONFIG_DIR.patch 169 # Override compiler configuration via an environmental variable 170 171 ./nixbuild.patch 172 # Load libraries at runtime by absolute path 173 174 ./extra-mangling.patch 175 # Mangle store paths of modules to prevent runtime dependence. 176 177 ./openssl.patch 178 # dlopen is widely used by Python, Ruby, Perl, ... what you're really telling me here is that your OS is fundamentally broken. That might be news for you, but it isn't for me. 179 ]; 180 }); 181 182} // (let 183 wrapNim = { nim', patches }: 184 let 185 targetPlatformConfig = stdenv.targetPlatform.config; 186 self = stdenv.mkDerivation (finalAttrs: { 187 name = "${targetPlatformConfig}-nim-wrapper-${nim'.version}"; 188 inherit (nim') version; 189 preferLocalBuild = true; 190 strictDeps = true; 191 192 nativeBuildInputs = [ makeWrapper ]; 193 194 # Needed for any nim package that uses the standard library's 195 # 'std/sysrand' module. 196 depsTargetTargetPropagated = lib.optional stdenv.isDarwin Security; 197 198 inherit patches; 199 200 unpackPhase = '' 201 runHook preUnpack 202 tar xf ${nim'.src} nim-$version/config 203 cd nim-$version 204 runHook postUnpack 205 ''; 206 207 dontConfigure = true; 208 209 buildPhase = 210 # Configure the Nim compiler to use $CC and $CXX as backends 211 # The compiler is configured by two configuration files, each with 212 # a different DSL. The order of evaluation matters and that order 213 # is not documented, so duplicate the configuration across both files. 214 '' 215 runHook preBuild 216 cat >> config/config.nims << WTF 217 218 switch("os", "${nimTarget.os}") 219 switch("cpu", "${nimTarget.cpu}") 220 switch("define", "nixbuild") 221 222 # Configure the compiler using the $CC set by Nix at build time 223 import strutils 224 let cc = getEnv"CC" 225 if cc.contains("gcc"): 226 switch("cc", "gcc") 227 elif cc.contains("clang"): 228 switch("cc", "clang") 229 WTF 230 231 mv config/nim.cfg config/nim.cfg.old 232 cat > config/nim.cfg << WTF 233 os = "${nimTarget.os}" 234 cpu = "${nimTarget.cpu}" 235 define:"nixbuild" 236 WTF 237 238 cat >> config/nim.cfg < config/nim.cfg.old 239 rm config/nim.cfg.old 240 241 cat >> config/nim.cfg << WTF 242 243 clang.cpp.exe %= "\$CXX" 244 clang.cpp.linkerexe %= "\$CXX" 245 clang.exe %= "\$CC" 246 clang.linkerexe %= "\$CC" 247 gcc.cpp.exe %= "\$CXX" 248 gcc.cpp.linkerexe %= "\$CXX" 249 gcc.exe %= "\$CC" 250 gcc.linkerexe %= "\$CC" 251 WTF 252 253 runHook postBuild 254 ''; 255 256 wrapperArgs = lib.optionals (!(stdenv.isDarwin && stdenv.isAarch64)) [ 257 "--prefix PATH : ${lib.makeBinPath [ buildPackages.gdb ]}:${ 258 placeholder "out" 259 }/bin" 260 # Used by nim-gdb 261 262 "--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ openssl pcre ]}" 263 # These libraries may be referred to by the standard library. 264 # This is broken for cross-compilation because the package 265 # set will be shifted back by nativeBuildInputs. 266 267 "--set NIM_CONFIG_PATH ${placeholder "out"}/etc/nim" 268 # Use the custom configuration 269 ]; 270 271 installPhase = '' 272 runHook preInstall 273 274 mkdir -p $out/bin $out/etc 275 276 cp -r config $out/etc/nim 277 278 for binpath in ${nim'}/bin/nim?*; do 279 local binname=`basename $binpath` 280 makeWrapper \ 281 $binpath $out/bin/${targetPlatformConfig}-$binname \ 282 $wrapperArgs 283 ln -s $out/bin/${targetPlatformConfig}-$binname $out/bin/$binname 284 done 285 286 makeWrapper \ 287 ${nim'}/nim/bin/nim $out/bin/${targetPlatformConfig}-nim \ 288 --set-default CC $(command -v $CC) \ 289 --set-default CXX $(command -v $CXX) \ 290 $wrapperArgs 291 ln -s $out/bin/${targetPlatformConfig}-nim $out/bin/nim 292 293 makeWrapper \ 294 ${nim'}/bin/testament $out/bin/${targetPlatformConfig}-testament \ 295 $wrapperArgs 296 ln -s $out/bin/${targetPlatformConfig}-testament $out/bin/testament 297 298 '' + '' 299 runHook postInstall 300 ''; 301 302 passthru = { nim = nim'; }; 303 304 meta = nim'.meta // { 305 description = nim'.meta.description 306 + " (${targetPlatformConfig} wrapper)"; 307 platforms = with lib.platforms; unix ++ genode; 308 }; 309 }); 310 in self // { 311 pkgs = callPackage ../../../top-level/nim-packages.nix { nim = self; }; 312 }; 313in { 314 315 nim = wrapNim { 316 nim' = buildPackages.nim-unwrapped; 317 patches = [ ./nim.cfg.patch ]; 318 }; 319 320 nim2 = wrapNim { 321 nim' = buildPackages.nim-unwrapped-2; 322 patches = [ ./nim2.cfg.patch ]; 323 }; 324 325})