1{
2 lib,
3 callPackage,
4 fixDarwinDylibNames,
5 libffi,
6 mbqn-source,
7 pkg-config,
8 stdenv,
9 # Boolean flags
10 enableReplxx ? false,
11 enableLibcbqn ? ((stdenv.hostPlatform.isLinux || stdenv.hostPlatform.isDarwin) && !enableReplxx),
12 generateBytecode ? false,
13 # "Configurable" options
14 bqn-interpreter,
15}:
16
17let
18 sources = callPackage ./sources.nix { };
19in
20stdenv.mkDerivation {
21 pname = "cbqn" + lib.optionalString (!generateBytecode) "-standalone";
22 inherit (sources.cbqn) version src;
23
24 nativeBuildInputs = [
25 pkg-config
26 ]
27 ++ lib.optionals stdenv.hostPlatform.isDarwin [
28 fixDarwinDylibNames
29 ];
30
31 buildInputs = [
32 libffi
33 ];
34
35 makeFlags = [
36 "CC=${stdenv.cc.targetPrefix}cc"
37 ];
38
39 buildFlags = [
40 # interpreter binary
41 "o3"
42 "notui=1" # display build progress in a plain-text format
43 "REPLXX=${if enableReplxx then "1" else "0"}"
44 ]
45 ++ lib.optionals stdenv.hostPlatform.avx2Support [
46 "has=avx2"
47 ]
48 ++ lib.optionals enableLibcbqn [
49 # embeddable interpreter as a shared lib
50 "shared-o3"
51 ];
52
53 outputs = [
54 "out"
55 ]
56 ++ lib.optionals enableLibcbqn [
57 "lib"
58 "dev"
59 ];
60
61 dontConfigure = true;
62
63 doInstallCheck = true;
64
65 strictDeps = true;
66
67 postPatch = ''
68 sed -i '/SHELL =.*/ d' makefile
69 patchShebangs build/build
70 '';
71
72 preBuild = ''
73 mkdir -p build/singeliLocal/
74 cp -r ${sources.singeli.src}/* build/singeliLocal/
75 ''
76 + (
77 if generateBytecode then
78 ''
79 mkdir -p build/bytecodeLocal/gen
80 ${bqn-interpreter} ./build/genRuntime ${mbqn-source} build/bytecodeLocal/
81 ''
82 else
83 ''
84 mkdir -p build/bytecodeLocal/gen
85 cp -r ${sources.cbqn-bytecode.src}/* build/bytecodeLocal/
86 ''
87 )
88 + lib.optionalString enableReplxx ''
89 mkdir -p build/replxxLocal/
90 cp -r ${sources.replxx.src}/* build/replxxLocal/
91 '';
92
93 installPhase = ''
94 runHook preInstall
95
96 mkdir -p $out/bin/
97 cp BQN -t $out/bin/
98 # note guard condition for case-insensitive filesystems
99 [ -e $out/bin/bqn ] || ln -s $out/bin/BQN $out/bin/bqn
100 [ -e $out/bin/cbqn ] || ln -s $out/bin/BQN $out/bin/cbqn
101 ''
102 + lib.optionalString enableLibcbqn ''
103 install -Dm644 include/bqnffi.h -t "$dev/include"
104 install -Dm755 libcbqn${stdenv.hostPlatform.extensions.sharedLibrary} -t "$lib/lib"
105 ''
106 + ''
107 runHook postInstall
108 '';
109
110 installCheckPhase = ''
111 runHook preInstallCheck
112
113 # main test suite from mlochbaum/BQN
114 $out/bin/BQN ${mbqn-source}/test/this.bqn
115
116 # CBQN tests that do not require compiling with test-only flags
117 $out/bin/BQN test/cmp.bqn
118 $out/bin/BQN test/equal.bqn
119 $out/bin/BQN test/copy.bqn
120 $out/bin/BQN test/bit.bqn
121 $out/bin/BQN test/hash.bqn
122 $out/bin/BQN test/squeezeValid.bqn
123 $out/bin/BQN test/squeezeExact.bqn
124 $out/bin/BQN test/various.bqn
125 $out/bin/BQN test/random.bqn
126
127 runHook postInstallCheck
128 '';
129
130 meta = {
131 homepage = "https://github.com/dzaima/CBQN/";
132 description = "BQN implementation in C";
133 license = with lib.licenses; [
134 # https://github.com/dzaima/CBQN?tab=readme-ov-file#licensing
135 asl20
136 boost
137 gpl3Only
138 lgpl3Only
139 mit
140 mpl20
141 ];
142 mainProgram = "cbqn";
143 maintainers = with lib.maintainers; [
144 detegr
145 shnarazk
146 sternenseemann
147 synthetica
148 ];
149 platforms = lib.platforms.all;
150 };
151}