nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
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_15,
20 llvmPackages_18,
21 makeWrapper,
22 openssl,
23 pcre2,
24 pkg-config,
25 installShellFiles,
26 readline,
27 tzdata,
28 which,
29 zlib,
30}:
31
32# We need to keep around at least the latest version released with a stable
33# NixOS
34let
35 archs = {
36 x86_64-linux = "linux-x86_64";
37 i686-linux = "linux-i686";
38 x86_64-darwin = "darwin-universal";
39 aarch64-darwin = "darwin-universal";
40 aarch64-linux = "linux-aarch64";
41 };
42
43 arch = archs.${stdenv.system} or (throw "system ${stdenv.system} not supported");
44
45 nativeCheckInputs = [
46 git
47 gmp
48 openssl
49 readline
50 libxml2
51 libyaml
52 libffi
53 ];
54
55 binaryUrl =
56 version: rel:
57 if arch == archs.aarch64-linux then
58 "https://dev.alpinelinux.org/archive/crystal/crystal-${version}-aarch64-alpine-linux-musl.tar.gz"
59 else
60 "https://github.com/crystal-lang/crystal/releases/download/${version}/crystal-${version}-${toString rel}-${arch}.tar.gz";
61
62 genericBinary =
63 {
64 version,
65 sha256s,
66 rel ? 1,
67 }:
68 stdenv.mkDerivation rec {
69 pname = "crystal-binary";
70 inherit version;
71
72 src = fetchurl {
73 url = binaryUrl version rel;
74 sha256 = sha256s.${stdenv.system};
75 };
76
77 buildCommand = ''
78 mkdir -p $out
79 tar --strip-components=1 -C $out -xf ${src}
80 patchShebangs $out/bin/crystal
81 '';
82
83 meta.platforms = lib.attrNames sha256s;
84 };
85
86 generic =
87 {
88 version,
89 sha256,
90 binary,
91 llvmPackages,
92 doCheck ? true,
93 extraBuildInputs ? [ ],
94 buildFlags ? [
95 "all"
96 "docs"
97 "release=1"
98 ],
99 }:
100 stdenv.mkDerivation (finalAttrs: {
101 pname = "crystal";
102 inherit buildFlags doCheck version;
103
104 src = fetchFromGitHub {
105 owner = "crystal-lang";
106 repo = "crystal";
107 rev = version;
108 inherit sha256;
109 };
110
111 patches = [
112 (replaceVars ./tzdata.patch {
113 inherit tzdata;
114 })
115 ];
116
117 outputs = [
118 "out"
119 "lib"
120 "bin"
121 ];
122
123 postPatch =
124 ''
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
173 # Available since 1.13.0 https://github.com/crystal-lang/crystal/pull/14574
174 if [[ -f src/SOURCE_DATE_EPOCH ]]; then
175 export SOURCE_DATE_EPOCH="$(<src/SOURCE_DATE_EPOCH)"
176 fi
177 '';
178
179 strictDeps = true;
180 nativeBuildInputs = [
181 binary
182 makeWrapper
183 which
184 pkg-config
185 llvmPackages.llvm
186 installShellFiles
187 ];
188 buildInputs =
189 [
190 boehmgc
191 pcre2
192 libevent
193 libyaml
194 zlib
195 libxml2
196 openssl
197 ]
198 ++ extraBuildInputs
199 ++ lib.optionals stdenv.hostPlatform.isDarwin [ libiconv ];
200
201 makeFlags = [
202 "CRYSTAL_CONFIG_VERSION=${version}"
203 "progress=1"
204 ];
205
206 LLVM_CONFIG = "${llvmPackages.llvm.dev}/bin/llvm-config";
207
208 FLAGS = [
209 "--single-module" # needed for deterministic builds
210 ];
211
212 # This makes sure we don't keep depending on the previous version of
213 # crystal used to build this one.
214 CRYSTAL_LIBRARY_PATH = "${placeholder "lib"}/crystal";
215
216 # We *have* to add `which` to the PATH or crystal is unable to build
217 # stuff later if which is not available.
218 installPhase = ''
219 runHook preInstall
220
221 install -Dm755 .build/crystal $bin/bin/crystal
222 wrapProgram $bin/bin/crystal \
223 --suffix PATH : ${
224 lib.makeBinPath [
225 pkg-config
226 llvmPackages.clang
227 which
228 ]
229 } \
230 --suffix CRYSTAL_PATH : lib:$lib/crystal \
231 --suffix PKG_CONFIG_PATH : ${
232 lib.makeSearchPathOutput "dev" "lib/pkgconfig" finalAttrs.buildInputs
233 } \
234 --suffix CRYSTAL_LIBRARY_PATH : ${lib.makeLibraryPath finalAttrs.buildInputs}
235 install -dm755 $lib/crystal
236 cp -r src/* $lib/crystal/
237
238 install -dm755 $out/share/doc/crystal/api
239 cp -r docs/* $out/share/doc/crystal/api/
240 cp -r samples $out/share/doc/crystal/
241
242 installShellCompletion --cmd ${finalAttrs.meta.mainProgram} etc/completion.*
243
244 installManPage man/crystal.1
245
246 install -Dm644 -t $out/share/licenses/crystal LICENSE README.md
247
248 mkdir -p $out
249 ln -s $bin/bin $out/bin
250 ln -s $bin/share/bash-completion $out/share/bash-completion
251 ln -s $bin/share/zsh $out/share/zsh
252 # fish completion was introduced in 1.6.0
253 test -f etc/completion.fish && ln -s $bin/share/fish $out/share/fish
254 ln -s $lib $out/lib
255
256 runHook postInstall
257 '';
258
259 enableParallelBuilding = true;
260
261 dontStrip = true;
262
263 checkTarget = "compiler_spec";
264
265 preCheck = ''
266 export LIBRARY_PATH=${lib.makeLibraryPath nativeCheckInputs}:$LIBRARY_PATH
267 export PATH=${lib.makeBinPath nativeCheckInputs}:$PATH
268 '';
269
270 passthru.buildBinary = binary;
271 passthru.buildCrystalPackage = callPackage ./build-package.nix {
272 crystal = finalAttrs.finalPackage;
273 };
274 passthru.llvmPackages = llvmPackages;
275
276 meta = with lib; {
277 inherit (binary.meta) platforms;
278 description = "Compiled language with Ruby like syntax and type inference";
279 mainProgram = "crystal";
280 homepage = "https://crystal-lang.org/";
281 license = licenses.asl20;
282 maintainers = with maintainers; [
283 david50407
284 manveru
285 peterhoeg
286 donovanglover
287 ];
288 };
289 });
290in
291rec {
292 binaryCrystal_1_10 = genericBinary {
293 version = "1.10.1";
294 sha256s = {
295 x86_64-linux = "sha256-F0LjdV02U9G6B8ApHxClF/o5KvhxMNukSX7Z2CwSNIs=";
296 aarch64-darwin = "sha256-5kkObQl0VIO6zqQ8TYl0JzYyUmwfmPE9targpfwseSQ=";
297 x86_64-darwin = "sha256-5kkObQl0VIO6zqQ8TYl0JzYyUmwfmPE9targpfwseSQ=";
298 aarch64-linux = "sha256-AzFz+nrU/HJmCL1hbCKXf5ej/uypqV1GJPVLQ4J3778=";
299 };
300 };
301
302 # When removing this version, also remove checks for src/SOURCE_DATE_EPOCH existence
303 crystal_1_11 = generic {
304 version = "1.11.2";
305 sha256 = "sha256-BBEDWqFtmFUNj0kuGBzv71YHO3KjxV4d2ySTCD4HhLc=";
306 binary = binaryCrystal_1_10;
307 llvmPackages = llvmPackages_15;
308 };
309
310 crystal_1_14 = generic {
311 version = "1.14.1";
312 sha256 = "sha256-cQWK92BfksOW8GmoXn4BmPGJ7CLyLAeKccOffQMh5UU=";
313 binary = binaryCrystal_1_10;
314 llvmPackages = llvmPackages_18;
315 doCheck = false; # Some compiler spec problems on x86-64_linux with the .0 release
316 };
317
318 crystal_1_15 = generic {
319 version = "1.15.1";
320 sha256 = "sha256-L/Q8yZdDq/wn4kJ+zpLfi4pxznAtgjxTCbLnEiCC2K0=";
321 binary = binaryCrystal_1_10;
322 llvmPackages = llvmPackages_18;
323 doCheck = false;
324 };
325
326 crystal_1_16 = generic {
327 version = "1.16.3";
328 sha256 = "sha256-U9H1tHUMyDNicZnXzEccDki5bGXdV0B2Wu2PyCksPVI=";
329 binary = binaryCrystal_1_10;
330 llvmPackages = llvmPackages_18;
331 doCheck = false;
332 };
333
334 crystal = crystal_1_16;
335}