{ lib , stdenv , fetchFromGitHub , fetchurl , fetchzip , autoconf , automake , autoreconfHook , dos2unix , file , perl , pkg-config , alsa-lib , coreutils , freetype , glib , glibc , gnugrep , libGL , libpulseaudio , libtool , libuuid , openssl , pango , xorg , squeakImageHash ? null , squeakSourcesHash ? null , squeakSourcesVersion ? null , squeakVersion ? null , squeakVmCommitHash ? null , squeakVmCommitHashHash ? null , squeakVmVersion ? null } @ args: let inherit (builtins) elemAt toString; nullableOr = o: default: if o == null then default else o; bits = stdenv.hostPlatform.parsed.cpu.bits; squeakVersion = nullableOr args.squeakVersion or null "5.3-19459"; squeakVersionSplit = builtins.split "-" squeakVersion; squeakVersionBase = elemAt squeakVersionSplit 0; squeakVersionBaseSplit = lib.splitVersion squeakVersionBase; squeakVersionMajor = elemAt squeakVersionBaseSplit 0; squeakVersionMinor = elemAt squeakVersionBaseSplit 1; squeakImageVersion = elemAt squeakVersionSplit 2; squeakSourcesVersion = nullableOr args.squeakSourcesVersion or null "50"; squeakVmVersion = nullableOr args.squeakVmVersion or null "5.0-202003021730"; squeakVmVersionSplit = builtins.split "-" squeakVmVersion; squeakVmVersionBase = elemAt squeakVmVersionSplit 0; squeakVmVersionBaseSplit = lib.splitVersion squeakVmVersionBase; squeakVmVersionMajor = elemAt squeakVmVersionBaseSplit 0; squeakVmVersionMinor = elemAt squeakVmVersionBaseSplit 1; squeakVmVersionRelease = elemAt squeakVmVersionSplit 2; squeakVmCommitHash = nullableOr args.squeakVmCommitHash or null (fetchurl { url = "https://api.github.com/repos/OpenSmalltalk/opensmalltalk-vm/commits/${squeakVmVersionRelease}"; curlOpts = "--header Accept:application/vnd.github.v3.sha"; hash = nullableOr args.squeakVmCommitHashHash or null "sha256-quwmhpJlb2fp0fI9b03fBxSR44j1xmHPW20wkSqTOhQ="; }); in stdenv.mkDerivation { pname = "squeak"; version = squeakVersion; vmVersionRelease = squeakVmVersionRelease; # "202003021730" vmHash = squeakVmCommitHash; vmSrcUrl = "https://github.com/OpenSmalltalk/opensmalltalk-vm.git"; src = fetchFromGitHub { owner = "OpenSmalltalk"; repo = "opensmalltalk-vm"; rev = squeakVmVersionRelease; hash = nullableOr args.squeakVmHash or null "sha256-rNJn5ya+7ggC21MpwSrl2ByJDjVycONKHADboH7dQLM="; }; imageSrc = let squeakImageName = "Squeak${squeakVersionBase}-${squeakImageVersion}-${toString bits}bit"; in fetchzip { url = "https://files.squeak.org/${squeakVersionBase}/${squeakImageName}/${squeakImageName}.zip"; name = "source"; stripRoot = false; hash = nullableOr args.squeakImageHash or null "sha256-wDuRyc/DNqG1D4DzyBkUvrzFkBlXBtbpnANZlRV/Fas="; }; sourcesSrc = fetchurl { url = "https://files.squeak.org/sources_files/SqueakV${squeakSourcesVersion}.sources.gz"; hash = nullableOr args.squeakSourcesHash or null "sha256-ZViZ1VgI32LwLTEyw7utp8oaAK3UmCNJnHqsGm1IKYE="; }; vmBuild = "linux64x64"; nativeBuildInputs = [ autoconf automake autoreconfHook dos2unix file perl pkg-config ]; buildInputs = [ alsa-lib coreutils freetype glib glibc gnugrep libGL libpulseaudio libtool libuuid openssl pango xorg.libX11 ]; postUnpack = '' for file in "$imageSrc"/*.{image,changes}; do gzip -c "$file" > "$sourceRoot/''${file##"$imageSrc"/}.gz" done ''; prePatch = '' dos2unix platforms/unix/plugins/*/{Makefile.inc,acinclude.m4} ''; patches = [ ./squeak-configure-version.patch ./squeak-plugins-discovery.patch ./squeak-squeaksh-nixpkgs.patch # it looks like -export-dynamic is being passed erroneously to the compiler, # as it is a linker flag and at this step the build is just compiling notice the -c flag. ./cc-no-export-dynamic.patch ]; postPatch = '' 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") vmVersionDate=$(date -u '+%a %b %-d %T %Y %z' -d "$vmVersionDate") vmVersionFiles=$(sed -n 's/^versionfiles="\(.*\)"/\1/p' ./scripts/updateSCCSVersions) vmHash=$(< "$vmHash") vmAbbrevHash=''${vmHash:0:12} printf '%s\n' "$vmAbbrevHash" for vmVersionFile in $vmVersionFiles; do substituteInPlace "$vmVersionFile" \ --replace "\$Date\$" "\$Date: ''${vmVersionDate} \$" \ --replace "\$URL\$" "\$URL: ''${vmSrcUrl} \$" \ --replace "\$Rev\$" "\$Rev: ''${vmVersionRelease} \$" \ --replace "\$CommitHash\$" "\$CommitHash: ''${vmAbbrevHash} \$" done patchShebangs --build ./"build.$vmBuild"/squeak.cog.spur ./scripts for squeaksh in ./platforms/unix/config/{,bin.}squeak.sh.in; do substituteInPlace "$squeaksh" \ --subst-var-by 'glibc' ${lib.escapeShellArg (lib.getBin glibc)} \ --subst-var-by 'gnugrep' ${lib.escapeShellArg (lib.getBin gnugrep)} done substituteInPlace ./platforms/unix/config/mkmf \ --replace '/bin/rm ' '${coreutils}/bin/rm ' ''; # Workaround build failure on -fno-common toolchains: # ld: vm/vm.a(cogit.o):spur64src/vm/cogitX64SysV.c:2552: multiple definition of # `traceStores'; vm/vm.a(gcc3x-cointerp.o):spur64src/vm/cogit.h:140: first defined here env.NIX_CFLAGS_COMPILE = toString ( [ "-fcommon" ] ++ (lib.optionals stdenv.cc.isClang [ # LLVM 16 turned these into errors (rightly, perhaps.) # Allow this package to continue to build despite this change. "-Wno-error=int-conversion" "-Wno-error=implicit-function-declaration" "-Wno-error=incompatible-function-pointer-types" ]) ); preAutoreconf = '' pushd ./platforms/unix/config > /dev/null ./mkacinc > ./acplugins.m4 ''; postAutoreconf = '' rm ./acplugins.m4 popd > /dev/null ''; preConfigure = '' if [ -z "''${dontFixLibtool:-}" ]; then local i find ./platforms/unix/config -iname "ltmain.sh" -print0 | while IFS=''' read -r -d ''' i; do echo "fixing libtool script $i" fixLibtool "$i" done fi substituteInPlace ./platforms/unix/config/configure \ --replace "/usr/bin/file" "${file}/bin/file" cd ./"build.$vmBuild"/squeak.cog.spur/build substituteInPlace ./mvm \ --replace 'read a' 'a=y' \ --replace $'if [ $# -ge 1 ]; then\n\tINSTALLDIR="$1"; shift\nfi\n' "" \ --replace 'config/configure' 'config/configure "$@"' \ --replace 'make install' '# make install' ''; configureFlags = [ "--disable-dynamicopenssl" "SQ_MAJOR=${squeakVersionMajor}" "SQ_MINOR=${squeakVersionMinor}" "SQ_UPDATE=${squeakImageVersion}" "SQ_VERSION=${squeakVersion}-${toString bits}bit" "SQ_SRC_VERSION=${squeakSourcesVersion}" "VM_MAJOR=${squeakVmVersionMajor}" "VM_MINOR=${squeakVmVersionMinor}" "VM_RELEASE=${squeakVmVersionRelease}" "VM_VERSION=${squeakVmVersion}" ]; configureScript = "./mvm"; installTargets = [ "install" "install-image" ]; postInstall = '' rm "$out/squeak" cp --no-preserve mode "$sourcesSrc" "$out"/lib/squeak/SqueakV${lib.escapeShellArg squeakSourcesVersion}.sources ''; meta = with lib; { description = "Squeak virtual machine"; homepage = "https://opensmalltalk.org/"; license = with licenses; [ asl20 mit ]; maintainers = with lib.maintainers; [ ehmry ]; platforms = [ "x86_64-linux" ]; }; }