{ stdenv, callPackage, fetchFromGitHub, fetchurl, lib, replaceVars, # Dependencies boehmgc, coreutils, git, gmp, hostname, libevent, libiconv, libxml2, libyaml, libffi, llvmPackages_15, llvmPackages_18, makeWrapper, openssl, pcre2, pkg-config, installShellFiles, readline, tzdata, which, zlib, }: # We need to keep around at least the latest version released with a stable # NixOS let archs = { x86_64-linux = "linux-x86_64"; i686-linux = "linux-i686"; x86_64-darwin = "darwin-universal"; aarch64-darwin = "darwin-universal"; aarch64-linux = "linux-aarch64"; }; arch = archs.${stdenv.system} or (throw "system ${stdenv.system} not supported"); nativeCheckInputs = [ git gmp openssl readline libxml2 libyaml libffi ]; binaryUrl = version: rel: if arch == archs.aarch64-linux then "https://dev.alpinelinux.org/archive/crystal/crystal-${version}-aarch64-alpine-linux-musl.tar.gz" else "https://github.com/crystal-lang/crystal/releases/download/${version}/crystal-${version}-${toString rel}-${arch}.tar.gz"; genericBinary = { version, sha256s, rel ? 1, }: stdenv.mkDerivation rec { pname = "crystal-binary"; inherit version; src = fetchurl { url = binaryUrl version rel; sha256 = sha256s.${stdenv.system}; }; buildCommand = '' mkdir -p $out tar --strip-components=1 -C $out -xf ${src} patchShebangs $out/bin/crystal ''; meta.platforms = lib.attrNames sha256s; }; generic = { version, sha256, binary, llvmPackages, doCheck ? true, extraBuildInputs ? [ ], buildFlags ? [ "all" "docs" "release=1" ], }: stdenv.mkDerivation (finalAttrs: { pname = "crystal"; inherit buildFlags doCheck version; src = fetchFromGitHub { owner = "crystal-lang"; repo = "crystal"; rev = version; inherit sha256; }; patches = [ (replaceVars ./tzdata.patch { inherit tzdata; }) ]; outputs = [ "out" "lib" "bin" ]; postPatch = '' export TMP=$(mktemp -d) export HOME=$TMP export TMPDIR=$TMP mkdir -p $HOME/test # Add dependency of crystal to docs to avoid issue on flag changes between releases # https://github.com/crystal-lang/crystal/pull/8792#issuecomment-614004782 substituteInPlace Makefile \ --replace 'docs: ## Generate standard library documentation' 'docs: crystal ## Generate standard library documentation' mkdir -p $TMP/crystal substituteInPlace spec/std/file_spec.cr \ --replace '/bin/ls' '${coreutils}/bin/ls' \ --replace '/usr/share' "$TMP/crystal" \ --replace '/usr' "$TMP" \ --replace '/tmp' "$TMP" substituteInPlace spec/std/process_spec.cr \ --replace '/bin/cat' '${coreutils}/bin/cat' \ --replace '/bin/ls' '${coreutils}/bin/ls' \ --replace '/usr/bin/env' '${coreutils}/bin/env' \ --replace '"env"' '"${coreutils}/bin/env"' \ --replace '/usr' "$TMP" \ --replace '/tmp' "$TMP" substituteInPlace spec/std/system_spec.cr \ --replace '`hostname`' '`${hostname}/bin/hostname`' # See https://github.com/crystal-lang/crystal/issues/8629 substituteInPlace spec/std/socket/udp_socket_spec.cr \ --replace 'it "joins and transmits to multicast groups"' 'pending "joins and transmits to multicast groups"' '' + lib.optionalString (stdenv.cc.isClang && (stdenv.cc.libcxx != null)) '' # Darwin links against libc++ not libstdc++. Newer versions of clang (12+) require # libc++abi to be linked explicitly (see https://github.com/NixOS/nixpkgs/issues/166205). substituteInPlace src/llvm/lib_llvm.cr \ --replace '@[Link("stdc++")]' '@[Link("c++")]' ''; # Defaults are 4 preBuild = '' export CRYSTAL_WORKERS=$NIX_BUILD_CORES export threads=$NIX_BUILD_CORES export CRYSTAL_CACHE_DIR=$TMP export MACOSX_DEPLOYMENT_TARGET=10.11 # Available since 1.13.0 https://github.com/crystal-lang/crystal/pull/14574 if [[ -f src/SOURCE_DATE_EPOCH ]]; then export SOURCE_DATE_EPOCH="$(