1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 fetchurl,
6 fetchzip,
7 autoconf,
8 automake,
9 autoreconfHook,
10 dos2unix,
11 file,
12 perl,
13 pkg-config,
14 alsa-lib,
15 coreutils,
16 freetype,
17 glib,
18 glibc,
19 gnugrep,
20 libGL,
21 libpulseaudio,
22 libtool,
23 libuuid,
24 openssl,
25 pango,
26 xorg,
27 squeakImageHash ? null,
28 squeakSourcesHash ? null,
29 squeakSourcesVersion ? null,
30 squeakVersion ? null,
31 squeakVmCommitHash ? null,
32 squeakVmCommitHashHash ? null,
33 squeakVmVersion ? null,
34}@args:
35
36let
37 inherit (builtins) elemAt toString;
38
39 nullableOr = o: default: if o == null then default else o;
40
41 bits = stdenv.hostPlatform.parsed.cpu.bits;
42
43 squeakVersion = nullableOr args.squeakVersion or null "5.3-19459";
44 squeakVersionSplit = builtins.split "-" squeakVersion;
45 squeakVersionBase = elemAt squeakVersionSplit 0;
46 squeakVersionBaseSplit = lib.splitVersion squeakVersionBase;
47 squeakVersionMajor = elemAt squeakVersionBaseSplit 0;
48 squeakVersionMinor = elemAt squeakVersionBaseSplit 1;
49
50 squeakImageVersion = elemAt squeakVersionSplit 2;
51
52 squeakSourcesVersion = nullableOr args.squeakSourcesVersion or null "50";
53
54 squeakVmVersion = nullableOr args.squeakVmVersion or null "5.0-202003021730";
55 squeakVmVersionSplit = builtins.split "-" squeakVmVersion;
56 squeakVmVersionBase = elemAt squeakVmVersionSplit 0;
57 squeakVmVersionBaseSplit = lib.splitVersion squeakVmVersionBase;
58 squeakVmVersionMajor = elemAt squeakVmVersionBaseSplit 0;
59 squeakVmVersionMinor = elemAt squeakVmVersionBaseSplit 1;
60 squeakVmVersionRelease = elemAt squeakVmVersionSplit 2;
61
62 squeakVmCommitHash = nullableOr args.squeakVmCommitHash or null (fetchurl {
63 url = "https://api.github.com/repos/OpenSmalltalk/opensmalltalk-vm/commits/${squeakVmVersionRelease}";
64 curlOpts = "--header Accept:application/vnd.github.v3.sha";
65 hash =
66 nullableOr args.squeakVmCommitHashHash or null
67 "sha256-quwmhpJlb2fp0fI9b03fBxSR44j1xmHPW20wkSqTOhQ=";
68 });
69in
70stdenv.mkDerivation {
71 pname = "squeak";
72 version = squeakVersion;
73
74 vmVersionRelease = squeakVmVersionRelease; # "202003021730"
75 vmHash = squeakVmCommitHash;
76
77 vmSrcUrl = "https://github.com/OpenSmalltalk/opensmalltalk-vm.git";
78 src = fetchFromGitHub {
79 owner = "OpenSmalltalk";
80 repo = "opensmalltalk-vm";
81 rev = squeakVmVersionRelease;
82 hash = nullableOr args.squeakVmHash or null "sha256-rNJn5ya+7ggC21MpwSrl2ByJDjVycONKHADboH7dQLM=";
83 };
84 imageSrc =
85 let
86 squeakImageName = "Squeak${squeakVersionBase}-${squeakImageVersion}-${toString bits}bit";
87 in
88 fetchzip {
89 url = "https://files.squeak.org/${squeakVersionBase}/${squeakImageName}/${squeakImageName}.zip";
90 name = "source";
91 stripRoot = false;
92 hash =
93 nullableOr args.squeakImageHash or null
94 "sha256-wDuRyc/DNqG1D4DzyBkUvrzFkBlXBtbpnANZlRV/Fas=";
95 };
96 sourcesSrc = fetchurl {
97 url = "https://files.squeak.org/sources_files/SqueakV${squeakSourcesVersion}.sources.gz";
98 hash =
99 nullableOr args.squeakSourcesHash or null
100 "sha256-ZViZ1VgI32LwLTEyw7utp8oaAK3UmCNJnHqsGm1IKYE=";
101 };
102
103 vmBuild = "linux64x64";
104
105 nativeBuildInputs = [
106 autoconf
107 automake
108 autoreconfHook
109 dos2unix
110 file
111 perl
112 pkg-config
113 ];
114 buildInputs = [
115 alsa-lib
116 coreutils
117 freetype
118 glib
119 glibc
120 gnugrep
121 libGL
122 libpulseaudio
123 libtool
124 libuuid
125 openssl
126 pango
127 xorg.libX11
128 ];
129
130 postUnpack = ''
131 for file in "$imageSrc"/*.{image,changes}; do
132 gzip -c "$file" > "$sourceRoot/''${file##"$imageSrc"/}.gz"
133 done
134 '';
135
136 prePatch = ''
137 dos2unix platforms/unix/plugins/*/{Makefile.inc,acinclude.m4}
138 '';
139
140 patches = [
141 ./squeak-configure-version.patch
142 ./squeak-plugins-discovery.patch
143 ./squeak-squeaksh-nixpkgs.patch
144 # it looks like -export-dynamic is being passed erroneously to the compiler,
145 # as it is a linker flag and at this step the build is just compiling notice the -c flag.
146 ./cc-no-export-dynamic.patch
147 ];
148
149 postPatch = ''
150 vmVersionDate=$(sed 's/\([0-9][0-9][0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)/\1-\2-\3T\4:\5+0000/' <<< "$vmVersionRelease")
151 vmVersionDate=$(date -u '+%a %b %-d %T %Y %z' -d "$vmVersionDate")
152 vmVersionFiles=$(sed -n 's/^versionfiles="\(.*\)"/\1/p' ./scripts/updateSCCSVersions)
153 vmHash=$(< "$vmHash")
154 vmAbbrevHash=''${vmHash:0:12}
155 printf '%s\n' "$vmAbbrevHash"
156 for vmVersionFile in $vmVersionFiles; do
157 substituteInPlace "$vmVersionFile" \
158 --replace "\$Date\$" "\$Date: ''${vmVersionDate} \$" \
159 --replace "\$URL\$" "\$URL: ''${vmSrcUrl} \$" \
160 --replace "\$Rev\$" "\$Rev: ''${vmVersionRelease} \$" \
161 --replace "\$CommitHash\$" "\$CommitHash: ''${vmAbbrevHash} \$"
162 done
163 patchShebangs --build ./"build.$vmBuild"/squeak.cog.spur ./scripts
164 for squeaksh in ./platforms/unix/config/{,bin.}squeak.sh.in; do
165 substituteInPlace "$squeaksh" \
166 --subst-var-by 'glibc' ${lib.escapeShellArg (lib.getBin glibc)} \
167 --subst-var-by 'gnugrep' ${lib.escapeShellArg (lib.getBin gnugrep)}
168 done
169 substituteInPlace ./platforms/unix/config/mkmf \
170 --replace '/bin/rm ' '${coreutils}/bin/rm '
171 '';
172
173 # Workaround build failure on -fno-common toolchains:
174 # ld: vm/vm.a(cogit.o):spur64src/vm/cogitX64SysV.c:2552: multiple definition of
175 # `traceStores'; vm/vm.a(gcc3x-cointerp.o):spur64src/vm/cogit.h:140: first defined here
176 env.NIX_CFLAGS_COMPILE = toString (
177 [ "-fcommon" ]
178 ++ (lib.optionals stdenv.cc.isClang [
179 # LLVM 16 turned these into errors (rightly, perhaps.)
180 # Allow this package to continue to build despite this change.
181 "-Wno-error=int-conversion"
182 "-Wno-error=implicit-function-declaration"
183 "-Wno-error=incompatible-function-pointer-types"
184 ])
185 );
186
187 preAutoreconf = ''
188 pushd ./platforms/unix/config > /dev/null
189 ./mkacinc > ./acplugins.m4
190 '';
191 postAutoreconf = ''
192 rm ./acplugins.m4
193 popd > /dev/null
194 '';
195
196 preConfigure = ''
197 if [ -z "''${dontFixLibtool:-}" ]; then
198 local i
199 find ./platforms/unix/config -iname "ltmain.sh" -print0 | while IFS=''' read -r -d ''' i; do
200 echo "fixing libtool script $i"
201 fixLibtool "$i"
202 done
203 fi
204
205 substituteInPlace ./platforms/unix/config/configure \
206 --replace "/usr/bin/file" "${file}/bin/file"
207 cd ./"build.$vmBuild"/squeak.cog.spur/build
208 substituteInPlace ./mvm \
209 --replace 'read a' 'a=y' \
210 --replace $'if [ $# -ge 1 ]; then\n\tINSTALLDIR="$1"; shift\nfi\n' "" \
211 --replace 'config/configure' 'config/configure "$@"' \
212 --replace 'make install' '# make install'
213 '';
214
215 configureFlags = [
216 "--disable-dynamicopenssl"
217 "SQ_MAJOR=${squeakVersionMajor}"
218 "SQ_MINOR=${squeakVersionMinor}"
219 "SQ_UPDATE=${squeakImageVersion}"
220 "SQ_VERSION=${squeakVersion}-${toString bits}bit"
221 "SQ_SRC_VERSION=${squeakSourcesVersion}"
222 "VM_MAJOR=${squeakVmVersionMajor}"
223 "VM_MINOR=${squeakVmVersionMinor}"
224 "VM_RELEASE=${squeakVmVersionRelease}"
225 "VM_VERSION=${squeakVmVersion}"
226 ];
227 configureScript = "./mvm";
228
229 installTargets = [
230 "install"
231 "install-image"
232 ];
233
234 postInstall = ''
235 rm "$out/squeak"
236 cp --no-preserve mode "$sourcesSrc" "$out"/lib/squeak/SqueakV${lib.escapeShellArg squeakSourcesVersion}.sources
237 '';
238
239 meta = with lib; {
240 description = "Squeak virtual machine";
241 homepage = "https://opensmalltalk.org/";
242 license = with licenses; [
243 asl20
244 mit
245 ];
246 platforms = [ "x86_64-linux" ];
247 };
248}