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