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