at master 8.9 kB view raw
1{ 2 stdenv, 3 callPackage, 4 fetchFromGitHub, 5 fetchurl, 6 lib, 7 replaceVars, 8 # Dependencies 9 boehmgc, 10 coreutils, 11 git, 12 gmp, 13 hostname, 14 libevent, 15 libiconv, 16 libxml2, 17 libyaml, 18 libffi, 19 llvmPackages_19, 20 llvmPackages_20, 21 llvmPackages_21, 22 makeWrapper, 23 openssl, 24 pcre2, 25 pkg-config, 26 installShellFiles, 27 readline, 28 tzdata, 29 which, 30 zlib, 31}: 32 33# We need to keep around at least the latest version released with a stable 34# NixOS 35let 36 archs = { 37 x86_64-linux = "linux-x86_64"; 38 i686-linux = "linux-i686"; 39 x86_64-darwin = "darwin-universal"; 40 aarch64-darwin = "darwin-universal"; 41 aarch64-linux = "linux-aarch64"; 42 }; 43 44 arch = archs.${stdenv.system} or (throw "system ${stdenv.system} not supported"); 45 46 nativeCheckInputs = [ 47 git 48 gmp 49 openssl 50 readline 51 libxml2 52 libyaml 53 libffi 54 ]; 55 56 binaryUrl = 57 version: rel: 58 if arch == archs.aarch64-linux then 59 "https://dev.alpinelinux.org/archive/crystal/crystal-${version}-aarch64-alpine-linux-musl.tar.gz" 60 else 61 "https://github.com/crystal-lang/crystal/releases/download/${version}/crystal-${version}-${toString rel}-${arch}.tar.gz"; 62 63 genericBinary = 64 { 65 version, 66 sha256s, 67 rel ? 1, 68 }: 69 stdenv.mkDerivation rec { 70 pname = "crystal-binary"; 71 inherit version; 72 73 src = fetchurl { 74 url = binaryUrl version rel; 75 sha256 = sha256s.${stdenv.system}; 76 }; 77 78 buildCommand = '' 79 mkdir -p $out 80 tar --strip-components=1 -C $out -xf ${src} 81 patchShebangs $out/bin/crystal 82 ''; 83 84 meta.platforms = lib.attrNames sha256s; 85 }; 86 87 generic = 88 { 89 version, 90 sha256, 91 binary, 92 llvmPackages, 93 doCheck ? true, 94 extraBuildInputs ? [ ], 95 buildFlags ? [ 96 "all" 97 "docs" 98 "release=1" 99 ], 100 }: 101 stdenv.mkDerivation (finalAttrs: { 102 pname = "crystal"; 103 inherit buildFlags doCheck version; 104 105 src = fetchFromGitHub { 106 owner = "crystal-lang"; 107 repo = "crystal"; 108 rev = version; 109 inherit sha256; 110 }; 111 112 patches = [ 113 (replaceVars ./tzdata.patch { 114 inherit tzdata; 115 }) 116 ]; 117 118 outputs = [ 119 "out" 120 "lib" 121 "bin" 122 ]; 123 124 postPatch = '' 125 export TMP=$(mktemp -d) 126 export HOME=$TMP 127 export TMPDIR=$TMP 128 mkdir -p $HOME/test 129 130 # Add dependency of crystal to docs to avoid issue on flag changes between releases 131 # https://github.com/crystal-lang/crystal/pull/8792#issuecomment-614004782 132 substituteInPlace Makefile \ 133 --replace 'docs: ## Generate standard library documentation' 'docs: crystal ## Generate standard library documentation' 134 135 mkdir -p $TMP/crystal 136 137 substituteInPlace spec/std/file_spec.cr \ 138 --replace '/bin/ls' '${coreutils}/bin/ls' \ 139 --replace '/usr/share' "$TMP/crystal" \ 140 --replace '/usr' "$TMP" \ 141 --replace '/tmp' "$TMP" 142 143 substituteInPlace spec/std/process_spec.cr \ 144 --replace '/bin/cat' '${coreutils}/bin/cat' \ 145 --replace '/bin/ls' '${coreutils}/bin/ls' \ 146 --replace '/usr/bin/env' '${coreutils}/bin/env' \ 147 --replace '"env"' '"${coreutils}/bin/env"' \ 148 --replace '/usr' "$TMP" \ 149 --replace '/tmp' "$TMP" 150 151 substituteInPlace spec/std/system_spec.cr \ 152 --replace '`hostname`' '`${hostname}/bin/hostname`' 153 154 # See https://github.com/crystal-lang/crystal/issues/8629 155 substituteInPlace spec/std/socket/udp_socket_spec.cr \ 156 --replace 'it "joins and transmits to multicast groups"' 'pending "joins and transmits to multicast groups"' 157 158 '' 159 + lib.optionalString (stdenv.cc.isClang && (stdenv.cc.libcxx != null)) '' 160 # Darwin links against libc++ not libstdc++. Newer versions of clang (12+) require 161 # libc++abi to be linked explicitly (see https://github.com/NixOS/nixpkgs/issues/166205). 162 substituteInPlace src/llvm/lib_llvm.cr \ 163 --replace '@[Link("stdc++")]' '@[Link("c++")]' 164 ''; 165 166 # Defaults are 4 167 preBuild = '' 168 export CRYSTAL_WORKERS=$NIX_BUILD_CORES 169 export threads=$NIX_BUILD_CORES 170 export CRYSTAL_CACHE_DIR=$TMP 171 export MACOSX_DEPLOYMENT_TARGET=10.11 172 export SOURCE_DATE_EPOCH="$(<src/SOURCE_DATE_EPOCH)" 173 ''; 174 175 strictDeps = true; 176 nativeBuildInputs = [ 177 binary 178 makeWrapper 179 which 180 pkg-config 181 llvmPackages.llvm 182 installShellFiles 183 ]; 184 buildInputs = [ 185 boehmgc 186 pcre2 187 libevent 188 libyaml 189 zlib 190 libxml2 191 openssl 192 ] 193 ++ extraBuildInputs 194 ++ lib.optionals stdenv.hostPlatform.isDarwin [ libiconv ]; 195 196 makeFlags = [ 197 "CRYSTAL_CONFIG_VERSION=${version}" 198 "progress=1" 199 ]; 200 201 LLVM_CONFIG = "${llvmPackages.llvm.dev}/bin/llvm-config"; 202 203 FLAGS = [ 204 "--single-module" # needed for deterministic builds 205 ]; 206 207 # This makes sure we don't keep depending on the previous version of 208 # crystal used to build this one. 209 CRYSTAL_LIBRARY_PATH = "${placeholder "lib"}/crystal"; 210 211 # We *have* to add `which` to the PATH or crystal is unable to build 212 # stuff later if which is not available. 213 installPhase = '' 214 runHook preInstall 215 216 install -Dm755 .build/crystal $bin/bin/crystal 217 wrapProgram $bin/bin/crystal \ 218 --suffix PATH : ${ 219 lib.makeBinPath [ 220 pkg-config 221 llvmPackages.clang 222 which 223 ] 224 } \ 225 --suffix CRYSTAL_PATH : lib:$lib/crystal \ 226 --suffix PKG_CONFIG_PATH : ${ 227 lib.makeSearchPathOutput "dev" "lib/pkgconfig" finalAttrs.buildInputs 228 } \ 229 --suffix CRYSTAL_LIBRARY_PATH : ${lib.makeLibraryPath finalAttrs.buildInputs} 230 install -dm755 $lib/crystal 231 cp -r src/* $lib/crystal/ 232 233 install -dm755 $out/share/doc/crystal/api 234 cp -r docs/* $out/share/doc/crystal/api/ 235 cp -r samples $out/share/doc/crystal/ 236 237 installShellCompletion --cmd ${finalAttrs.meta.mainProgram} etc/completion.* 238 239 installManPage man/crystal.1 240 241 install -Dm644 -t $out/share/licenses/crystal LICENSE README.md 242 243 mkdir -p $out 244 ln -s $bin/bin $out/bin 245 ln -s $bin/share/bash-completion $out/share/bash-completion 246 ln -s $bin/share/zsh $out/share/zsh 247 ln -s $bin/share/fish $out/share/fish 248 ln -s $lib $out/lib 249 250 runHook postInstall 251 ''; 252 253 enableParallelBuilding = true; 254 255 dontStrip = true; 256 257 checkTarget = "compiler_spec"; 258 259 preCheck = '' 260 export LIBRARY_PATH=${lib.makeLibraryPath nativeCheckInputs}:$LIBRARY_PATH 261 export PATH=${lib.makeBinPath nativeCheckInputs}:$PATH 262 ''; 263 264 passthru.buildBinary = binary; 265 passthru.buildCrystalPackage = callPackage ./build-package.nix { 266 crystal = finalAttrs.finalPackage; 267 }; 268 passthru.llvmPackages = llvmPackages; 269 270 meta = with lib; { 271 inherit (binary.meta) platforms; 272 description = "Compiled language with Ruby like syntax and type inference"; 273 mainProgram = "crystal"; 274 homepage = "https://crystal-lang.org/"; 275 license = licenses.asl20; 276 maintainers = with maintainers; [ 277 david50407 278 manveru 279 peterhoeg 280 donovanglover 281 ]; 282 }; 283 }); 284in 285rec { 286 binaryCrystal_1_10 = genericBinary { 287 version = "1.10.1"; 288 sha256s = { 289 x86_64-linux = "sha256-F0LjdV02U9G6B8ApHxClF/o5KvhxMNukSX7Z2CwSNIs="; 290 aarch64-darwin = "sha256-5kkObQl0VIO6zqQ8TYl0JzYyUmwfmPE9targpfwseSQ="; 291 x86_64-darwin = "sha256-5kkObQl0VIO6zqQ8TYl0JzYyUmwfmPE9targpfwseSQ="; 292 aarch64-linux = "sha256-AzFz+nrU/HJmCL1hbCKXf5ej/uypqV1GJPVLQ4J3778="; 293 }; 294 }; 295 296 crystal_1_14 = generic { 297 version = "1.14.1"; 298 sha256 = "sha256-cQWK92BfksOW8GmoXn4BmPGJ7CLyLAeKccOffQMh5UU="; 299 binary = binaryCrystal_1_10; 300 llvmPackages = llvmPackages_19; 301 doCheck = false; # Some compiler spec problems on x86-64_linux with the .0 release 302 }; 303 304 crystal_1_15 = generic { 305 version = "1.15.1"; 306 sha256 = "sha256-L/Q8yZdDq/wn4kJ+zpLfi4pxznAtgjxTCbLnEiCC2K0="; 307 binary = binaryCrystal_1_10; 308 llvmPackages = llvmPackages_19; 309 doCheck = false; 310 }; 311 312 crystal_1_16 = generic { 313 version = "1.16.3"; 314 sha256 = "sha256-U9H1tHUMyDNicZnXzEccDki5bGXdV0B2Wu2PyCksPVI="; 315 binary = binaryCrystal_1_10; 316 llvmPackages = llvmPackages_20; 317 doCheck = false; 318 }; 319 320 crystal_1_17 = generic { 321 version = "1.17.1"; 322 sha256 = "sha256-+wHhozPhpIsfQy1Lw+V48zvuWCfXzT4IC9KA1AU/DLw="; 323 binary = binaryCrystal_1_10; 324 llvmPackages = llvmPackages_21; 325 doCheck = false; 326 }; 327 328 crystal = crystal_1_16; 329}