summary refs log tree commit diff
path: root/pkgs/development/pharo
diff options
context:
space:
mode:
authorLuke Gorrie <luke@snabb.co>2017-04-17 17:00:23 +0000
committerLuke Gorrie <luke@snabb.co>2017-06-28 09:26:59 +0000
commitfdb90f6df720b44f0475e42657a2f6c09797b42a (patch)
tree54dbaf8e1348b4443e21795e024f7245b57d50b8 /pkgs/development/pharo
parent71e495e10f363c91475f82683e6df3b49a5b3e7c (diff)
downloadnixpkgs-fdb90f6df720b44f0475e42657a2f6c09797b42a.tar
nixpkgs-fdb90f6df720b44f0475e42657a2f6c09797b42a.tar.gz
nixpkgs-fdb90f6df720b44f0475e42657a2f6c09797b42a.tar.bz2
nixpkgs-fdb90f6df720b44f0475e42657a2f6c09797b42a.tar.lz
nixpkgs-fdb90f6df720b44f0475e42657a2f6c09797b42a.tar.xz
nixpkgs-fdb90f6df720b44f0475e42657a2f6c09797b42a.tar.zst
nixpkgs-fdb90f6df720b44f0475e42657a2f6c09797b42a.zip
pharo: 5.0 -> 6.0
Create a new set of VM packages to keep up with changes in the
upstream Pharo project.
Diffstat (limited to 'pkgs/development/pharo')
-rw-r--r--pkgs/development/pharo/launcher/default.nix19
-rw-r--r--pkgs/development/pharo/vm/build-vm-legacy.nix72
-rw-r--r--pkgs/development/pharo/vm/build-vm.nix137
-rw-r--r--pkgs/development/pharo/vm/default.nix34
-rw-r--r--pkgs/development/pharo/vm/wrapper.sh62
-rw-r--r--pkgs/development/pharo/wrapper/default.nix58
-rw-r--r--pkgs/development/pharo/wrapper/magic37
-rw-r--r--pkgs/development/pharo/wrapper/pharo-vm.sh57
8 files changed, 388 insertions, 88 deletions
diff --git a/pkgs/development/pharo/launcher/default.nix b/pkgs/development/pharo/launcher/default.nix
index 911680b1eb8..a54a6671d7f 100644
--- a/pkgs/development/pharo/launcher/default.nix
+++ b/pkgs/development/pharo/launcher/default.nix
@@ -1,11 +1,11 @@
-{ stdenv, fetchurl, bash, pharo-vm, unzip, makeDesktopItem }:
+{ stdenv, fetchurl, bash, pharo, unzip, makeDesktopItem }:
 
 stdenv.mkDerivation rec {
-  version = "0.2.9-2016.01.14";
+  version = "2017.02.28";
   name = "pharo-launcher-${version}";
   src = fetchurl {
-    url = "http://files.pharo.org/platform/launcher/blessed/PharoLauncher-user-${version}.zip";
-    sha256 = "0lzdnaw7l1rrzbrq53xsy38aiz6id5x7s78ds1dhb31vqc241yy8";
+    url = "http://files.pharo.org/platform/launcher/PharoLauncher-user-stable-${version}.zip";
+    sha256 = "1hfwjyx0c47s6ivc1zr2sf5mk1xw2zspsv0ns8mj3kcaglzqwiq0";
   };
 
   executable-name = "pharo-launcher";
@@ -23,7 +23,7 @@ stdenv.mkDerivation rec {
   # because upstream tarball has no top-level directory.
   sourceRoot = ".";
 
-  buildInputs = [ bash pharo-vm unzip ];
+  buildInputs = [ bash pharo unzip ];
 
   installPhase = ''
     mkdir -p $prefix/share/pharo-launcher
@@ -37,8 +37,7 @@ stdenv.mkDerivation rec {
 
     cat > $prefix/bin/${executable-name} <<EOF
     #!${bash}/bin/bash
-
-    exec ${pharo-vm}/bin/pharo-vm-x $prefix/share/pharo-launcher/pharo-launcher.image
+    exec ${pharo}/bin/pharo $prefix/share/pharo-launcher/pharo-launcher.image
     EOF
     chmod +x $prefix/bin/${executable-name}
   '';
@@ -52,7 +51,7 @@ stdenv.mkDerivation rec {
      secs=5
      echo -n "Running headless Pharo for $secs seconds to check for a crash... "
      timeout $secs \
-       ${pharo-vm}/bin/pharo-vm-nox PharoLauncher.image --no-quit eval 'true'
+       ${pharo}/bin/pharo -nodisplay PharoLauncher.image --no-quit eval 'true'
      test "$?" == 124 && echo "ok")
   '';
 
@@ -78,7 +77,7 @@ stdenv.mkDerivation rec {
     '';
     homepage = http://pharo.org;
     license = stdenv.lib.licenses.mit;
-    maintainers = [ stdenv.lib.maintainers.lukego ];
-    platforms = pharo-vm.meta.platforms;
+    maintainers = [ ];
+    platforms = pharo.meta.platforms;
   };
 }
diff --git a/pkgs/development/pharo/vm/build-vm-legacy.nix b/pkgs/development/pharo/vm/build-vm-legacy.nix
new file mode 100644
index 00000000000..111b985bdb3
--- /dev/null
+++ b/pkgs/development/pharo/vm/build-vm-legacy.nix
@@ -0,0 +1,72 @@
+{ stdenv, fetchurl, cmake, bash, unzip, glibc, openssl, gcc, mesa, freetype, xorg, alsaLib, cairo, ... }:
+
+{ name, src, ... }:
+
+stdenv.mkDerivation rec {
+
+  inherit name src;
+
+  pharo-share = import ./share.nix { inherit stdenv fetchurl unzip; };
+
+  hardeningDisable = [ "format" "pic" ];
+
+  # Building
+  preConfigure = ''
+    cd build/
+  '';
+  resources = ./resources;
+  installPhase = ''
+    mkdir -p "$prefix/lib/$name"
+
+    cd ../../results
+
+    mv vm-display-null vm-display-null.so
+    mv vm-display-X11 vm-display-X11.so
+    mv vm-sound-null vm-sound-null.so
+    mv vm-sound-ALSA vm-sound-ALSA.so
+    mv pharo pharo-vm
+
+    cp * "$prefix/lib/$name"
+
+    mkdir $prefix/bin
+
+    chmod u+w $prefix/bin
+    cat > $prefix/bin/pharo-cog <<EOF
+    #!${bash}/bin/bash
+    # disable parameter expansion to forward all arguments unprocessed to the VM
+    set -f
+    exec $prefix/lib/$name/pharo-vm "\$@"
+    EOF
+
+    chmod +x $prefix/bin/pharo-cog
+
+    ln -s "${pharo-share}/lib/"*.sources $prefix/lib/$name
+  '';
+
+  buildInputs = [ bash unzip cmake glibc openssl gcc mesa freetype xorg.libX11 xorg.libICE xorg.libSM alsaLib cairo pharo-share ];
+
+  meta = {
+    description = "Clean and innovative Smalltalk-inspired environment";
+    longDescription = ''
+      Pharo's goal is to deliver a clean, innovative, free open-source
+      Smalltalk-inspired environment. By providing a stable and small core
+      system, excellent dev tools, and maintained releases, Pharo is an
+      attractive platform to build and deploy mission critical applications.
+
+      This package provides the executable VM. You should probably not care
+      about this package (which represents a packaging detail) and have a
+      look at the pharo-vm-core package instead.
+
+      Please fill bug reports on http://bugs.pharo.org under the 'Ubuntu
+      packaging (ppa:pharo/stable)' project.
+    '';
+    homepage = http://pharo.org;
+    license = stdenv.lib.licenses.mit;
+    maintainers = [ stdenv.lib.maintainers.lukego ];
+    # Pharo VM sources are packaged separately for darwin (OS X)
+    platforms = with stdenv.lib;
+                  intersectLists
+                    platforms.mesaPlatforms
+                    (subtractLists platforms.darwin platforms.unix);
+  };
+}
diff --git a/pkgs/development/pharo/vm/build-vm.nix b/pkgs/development/pharo/vm/build-vm.nix
index 1f9e82f866e..02399ecb9c2 100644
--- a/pkgs/development/pharo/vm/build-vm.nix
+++ b/pkgs/development/pharo/vm/build-vm.nix
@@ -1,76 +1,103 @@
-{ stdenv, fetchurl, cmake, bash, unzip, glibc, openssl, gcc, mesa, freetype, xorg, alsaLib, cairo, makeDesktopItem }:
+{ stdenv, fetchurl, bash, unzip, glibc, openssl, gcc, mesa, freetype, xorg, alsaLib, cairo, libuuid, autoreconfHook, gcc6, ... }:
 
-{ name, src, binary-basename, ... }:
+{ name, src, version, source-date, source-url, ... }:
 
+# Build the Pharo VM
 stdenv.mkDerivation rec {
+  inherit name src;
 
-  inherit name src binary-basename;
+  # Command line invocation name.
+  # Distinct name for 64-bit builds because they only work with 64-bit images.
+  cmd = if stdenv.is64bit then "pharo-spur64" else "pharo-spur";
 
-  pharo-share = import ./share.nix { inherit stdenv fetchurl unzip; };
+  # Choose desired VM sources. Separate for 32-bit and 64-bit VM.
+  # (Could extent to building more VM variants e.g. SpurV3, Sista, etc.)
+  vm = if stdenv.is64bit then "spur64src" else "spursrc";
 
-  desktopItem = makeDesktopItem {
-    inherit name;
-    desktopName = "Pharo VM";
-    genericName = "Pharo Virtual Machine";
-    exec = "${binary-basename}-x %F";
-    icon = "pharo";
-    terminal = "false";
-    type="Application";
-    startupNotify = "false";
-    categories = "Development;";
-    mimeType = "application/x-pharo-image";
-  };
+  # Choose target platform name in the format used by the vm.
+  flavor =
+    if      stdenv.isLinux && stdenv.isi686    then "linux32x86"
+    else if stdenv.isLinux && stdenv.isx86_64  then "linux64x64"
+    else if stdenv.isDarwin && stdenv.isi686   then "macos32x86"
+    else if stdenv.isDarwin && stdenv.isx86_64 then "macos64x64"
+    else abort "Unsupported platform: only Linux/Darwin x86/x64 are supported.";
+
+  # Shared data (for the sources file)
+  pharo-share = import ./share.nix { inherit stdenv fetchurl unzip; };
 
+  # Note: -fPIC causes the VM to segfault.
   hardeningDisable = [ "format" "pic" ];
 
-  # Building
-  preConfigure = ''
-    cd build/
+  # Regenerate the configure script.
+  # Unnecessary? But the build breaks without this.
+  autoreconfPhase = ''
+    (cd opensmalltalk-vm/platforms/unix/config && make)
   '';
-  resources = ./resources;
-  installPhase = ''
-    mkdir -p "$prefix/lib/$name"
-
-    cd ../../results
-
-    mv vm-display-null vm-display-null.so
-    mv vm-display-X11 vm-display-X11.so
-    mv vm-sound-null vm-sound-null.so
-    mv vm-sound-ALSA vm-sound-ALSA.so
-    mv pharo pharo-vm
-
-    cp * "$prefix/lib/$name"
-
-    mkdir -p "$prefix/share/applications"
-    cp "${desktopItem}/share/applications/"* $prefix/share/applications
-
-    mkdir $prefix/bin
 
-    chmod u+w $prefix/bin
-    cat > $prefix/bin/${binary-basename}-x <<EOF
-    #!${bash}/bin/bash
-
-    # disable parameter expansion to forward all arguments unprocessed to the VM
-    set -f
+  # Configure with options modeled on the 'mvm' build script from the vm.
+  configureScript = "platforms/unix/config/configure";
+  configureFlags = [ "--without-npsqueak"
+                     "--with-vmversion=5.0"
+                     "--with-src=${vm}" ];
+  CFLAGS = "-msse2 -D_GNU_SOURCE -DCOGMTVM=0 -g -O2 -DNDEBUG -DDEBUGVM=0";
+  LDFLAGS = "-Wl,-z,now";
+
+  # VM sources require some patching before build.
+  prePatch = ''
+    patchShebangs opensmalltalk-vm/build.${flavor}
+    # Fix hard-coded path to /bin/rm in a script
+    sed -i -e 's:/bin/rm:rm:' opensmalltalk-vm/platforms/unix/config/mkmf
+    # Fill in mandatory metadata about the VM source version
+    sed -i -e 's!\$Date\$!$Date: ${source-date} $!' \
+           -e 's!\$Rev\$!$Rev: ${version} $!' \
+           -e 's!\$URL\$!$URL: ${source-url} $!' \
+           opensmalltalk-vm/platforms/Cross/vm/sqSCCSVersion.h
+  '';
 
-    exec $prefix/lib/$name/pharo-vm "\$@"
-    EOF
+  # Note: --with-vmcfg configure option is broken so copy plugin specs to ./
+  preConfigure = ''
+    cd opensmalltalk-vm
+    cp build.${flavor}/pharo.cog.spur/plugins.{ext,int} .
+  '';
 
-    cat > $prefix/bin/${binary-basename}-nox <<EOF
-    #!${bash}/bin/bash
+  # (No special build phase.)
 
-    # disable parameter expansion to forward all arguments unprocessed to the VM
+  installPhase = ''
+    # Install in working directory and then copy
+    make install-squeak install-plugins prefix=$(pwd)/products
+
+    # Copy binaries & rename from 'squeak' to 'pharo'
+    mkdir -p $out
+    cp    products/lib/squeak/5.0-*/squeak $out/pharo
+
+    cp -r products/lib/squeak/5.0-*/*.so $out
+    ln -s "${pharo-share}/lib/"*.sources $out
+
+    # Create a shell script to run the VM in the proper environment.
+    # 
+    # These wrapper puts all relevant libraries into the
+    # LD_LIBRARY_PATH. This is important because various C code in the VM
+    # and Smalltalk code in the image will search for them there.
+    mkdir -p $out/bin
+    chmod u+w $out/bin
+
+    # Note: include ELF rpath in LD_LIBRARY_PATH for finding libc.
+    libs=$out:$(patchelf --print-rpath $out/pharo):${cairo}/lib:${mesa}/lib:${freetype}/lib:${openssl}/lib:${libuuid}/lib:${alsaLib}/lib:${xorg.libICE}/lib:${xorg.libSM}/lib
+
+    # Create the script
+    cat > $out/bin/${cmd} <<EOF
+    #!/bin/sh
     set -f
-
-    exec $prefix/lib/$name/pharo-vm -vm-display-null "\$@"
+    LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:$libs" exec $out/pharo "\$@"
     EOF
+    chmod +x $prefix/bin/${cmd}
+  '';
 
-    chmod +x $prefix/bin/${binary-basename}-x $prefix/bin/${binary-basename}-nox
+  enableParallelBuilding = true;
 
-    ln -s "${pharo-share}/lib/"*.sources $prefix/lib/$name
-  '';
+  # Note: Force gcc6 because gcc5 crashes when compiling the VM.
+  buildInputs = [ bash unzip glibc openssl gcc6 mesa freetype xorg.libX11 xorg.libICE xorg.libSM alsaLib cairo pharo-share libuuid autoreconfHook ];
 
-  buildInputs = [ bash unzip cmake glibc openssl gcc mesa freetype xorg.libX11 xorg.libICE xorg.libSM alsaLib cairo pharo-share ];
 
   meta = {
     description = "Clean and innovative Smalltalk-inspired environment";
@@ -89,7 +116,7 @@ stdenv.mkDerivation rec {
     '';
     homepage = http://pharo.org;
     license = stdenv.lib.licenses.mit;
-    maintainers = [ ];
+    maintainers = [ stdenv.lib.maintainers.lukego ];
     # Pharo VM sources are packaged separately for darwin (OS X)
     platforms = with stdenv.lib;
                   intersectLists
diff --git a/pkgs/development/pharo/vm/default.nix b/pkgs/development/pharo/vm/default.nix
index aca5c37d265..6d84981e7ad 100644
--- a/pkgs/development/pharo/vm/default.nix
+++ b/pkgs/development/pharo/vm/default.nix
@@ -1,27 +1,15 @@
-{ stdenv, fetchurl, cmake, bash, unzip, glibc, openssl, gcc, mesa, freetype, xorg, alsaLib, cairo, makeDesktopItem } @args:
+{ stdenv, callPackage, callPackage_i686, ...} @pkgs:
 
-rec {
-  pharo-vm-build = import ./build-vm.nix args;
+let
+  i686    = callPackage_i686 ./vms.nix {};
+  native  = callPackage ./vms.nix {};
+in
 
-  base-url = http://files.pharo.org/vm/src/vm-unix-sources/blessed;
+rec {
+  cog32 = i686.cog;
+  spur32 = i686.spur;
+  spur64 = if stdenv.is64bit then native.spur else "none";
+  multi-vm-wrapper  = callPackage ../wrapper { inherit cog32 spur32 spur64; };
+}
 
-  pharo-no-spur = pharo-vm-build rec {
-    version = "2016.02.18";
-    name = "pharo-vm-i386-${version}";
-    binary-basename = "pharo-vm";
-    src = fetchurl {
-      url = "${base-url}/pharo-vm-${version}.tar.bz2";
-      sha256 = "16n2zg7v2s1ml0vvpbhkw6khmgn637sr0d7n2b28qm5yc8pfhcj4";
-    };
-  };
 
-  pharo-spur = pharo-vm-build rec {
-    version = "2016.07.16";
-    name = "pharo-vm-spur-i386-${version}";
-    binary-basename = "pharo-spur-vm";
-    src = fetchurl {
-      url = "${base-url}/pharo-vm-spur-${version}.tar.bz2";
-      sha256 = "07nk4w5wh7gcf27cch5paqp9zdlshnknpv4y7imxlkjd76viac2b";
-    };
-  };
-}
diff --git a/pkgs/development/pharo/vm/wrapper.sh b/pkgs/development/pharo/vm/wrapper.sh
new file mode 100644
index 00000000000..b08a1a6d128
--- /dev/null
+++ b/pkgs/development/pharo/vm/wrapper.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+# This is based on the script by David T. Lewis posted here:
+#  http://lists.squeakfoundation.org/pipermail/vm-dev/2017-April/024836.html
+#
+# VM run utility script
+# usage: run <myimage>
+#
+# Select a VM and run an image based on the image format number
+
+# Search for the image filename in the command line arguments
+for arg in $*; do
+    case ${arg} in
+        -*) # ignore
+        ;;
+        *) # either an option argument or the image name
+            if test -f ${arg}; then
+                magic=$(file -m @share@/magic "$arg")
+                case "$magic" in
+                    'Smalltalk image V3 32b*')
+                        image=${arg}
+                        vm=@cog-vm@/bin/pharo-cog
+                        ;;
+                    'Smalltalk image Spur 32b*')
+                        image=${arg}
+                        vm=@spur-vm@/bin/pharo-spur
+                        ;;
+                    'Smalltalk image Spur 64b*')
+                        if "@spur64-vm@" == "none"; then
+                            echo "error: detected 64-bit image but 64-bit VM is not available" >&2
+                            exit 1
+                        fi
+                        image=${arg}
+                        vm=@spur64-vm@/bin/pharo-spur64
+                        ;;
+                esac
+            fi
+            ;;
+    esac
+done
+
+# Extra arguments to pass to the VM
+args=""
+
+# Print a message to explain our DWIM'ery.
+if -n "$image"; then
+    echo "using VM selected by image type."
+    echo "  image: $image"
+    echo "  type:  $magic"
+    echo "  vm:    $vm"
+elif test "$#" == 0; then
+    echo "using default vm and image; none specified on command line"
+    args="@default-image@"
+    # XXX Just assume this is the right VM (for pharo launcher)
+    vm=@cog-vm@/bin/pharo-cog
+else
+    echo "using default vm; image type not detected"
+fi
+
+# Run the VM
+set -f
+exec ${vm} $args "$@"
+
diff --git a/pkgs/development/pharo/wrapper/default.nix b/pkgs/development/pharo/wrapper/default.nix
new file mode 100644
index 00000000000..bd37c31df6a
--- /dev/null
+++ b/pkgs/development/pharo/wrapper/default.nix
@@ -0,0 +1,58 @@
+{ stdenv, file, makeDesktopItem, cog32, spur32, spur64 ? "none" }:
+
+stdenv.mkDerivation rec {
+  name = "pharo-vm";
+  src = ./.;
+  inherit cog32 spur32 spur64 file;
+  magic = ./magic;
+  desktopItem = makeDesktopItem {
+    inherit name;
+    desktopName = "Pharo VM";
+    genericName = "Pharo Virtual Machine";
+    exec = "pharo %F";
+    icon = "pharo";
+    terminal = "false";
+    type="Application";
+    startupNotify = "false";
+    categories = "Development;";
+    mimeType = "application/x-pharo-image";
+  };
+  buildPhase = ''
+    substituteAllInPlace ./pharo-vm.sh
+  '';
+  installPhase = ''
+    mkdir -p $out/bin
+    cp pharo-vm.sh $out/bin/pharo
+    chmod +x $out/bin/pharo
+  '';
+  meta = {
+    description = "Pharo virtual machine (multiple variants)";
+
+    longDescription = ''
+      Pharo's goal is to deliver a clean, innovative, free open-source
+      Smalltalk-inspired environment. By providing a stable and small core
+      system, excellent dev tools, and maintained releases, Pharo is an
+      attractive platform to build and deploy mission critical applications.
+
+      This package provides a front-end for starting the virtual
+      machine. The command 'pharo-vm' automatically detects the type
+      of image and executes a suitable virtual machine: CogV3, Spur,
+      or Spur64. This makes it easy to open Pharo images because you
+      do not have to worry about which virtual machine variant is
+      required.
+
+      More about the Cog family of virtual machines:
+        http://www.mirandabanda.org/cogblog/about-cog/
+    '';
+
+    homepage = http://pharo.org;
+    license = stdenv.lib.licenses.mit;
+    maintainers = [ stdenv.lib.maintainers.lukego ];
+    # Pharo VM sources are packaged separately for darwin (OS X)
+    platforms = with stdenv.lib;
+                  intersectLists
+                    platforms.mesaPlatforms
+                    (subtractLists platforms.darwin platforms.unix);
+  };
+}
+
diff --git a/pkgs/development/pharo/wrapper/magic b/pkgs/development/pharo/wrapper/magic
new file mode 100644
index 00000000000..3870ef2dd01
--- /dev/null
+++ b/pkgs/development/pharo/wrapper/magic
@@ -0,0 +1,37 @@
+# Smalltalk image file formats
+0 lelong    6502  Smalltalk image V3 32b  (%d)
+!:mime application/squeak-image
+0      belong   6502    Smalltalk image V3 32b  (%d)
+!:mime application/squeak-image
+0      lelong   6504    Smalltalk image V3 32b +C (%d)
+!:mime application/cog-image
+0      belong   6504    Smalltalk image V3 32b +C (%d)
+!:mime application/cog-image
+0      lelong   68000   Smalltalk image V3 64b  (%d)
+!:mime application/squeak64-image
+4      belong   68000   Smalltalk image V3 64b  (%d)
+!:mime application/squeak64-image
+0      lelong   68002   Smalltalk image V3 64b +C (%d)
+!:mime application/cog64-image
+4      belong   68002   Smalltalk image V3 64b +C (%d)
+!:mime application/cog64-image
+0      lelong   6505    Smalltalk image V3 32b +C+NF (%d)
+!:mime application/cog-image
+0      belong   6505    Smalltalk image V3 32b +C+NF (%d)
+!:mime application/cog-image
+0      lelong   68003   Smalltalk image V3 64b +C+NF (%d)
+!:mime application/cog64-image
+4      belong   68003   Smalltalk image V3 64b +C+NF (%d)
+!:mime application/cog64-image
+0      lelong   6521    Smalltalk image Spur 32b +C+NF (%d)
+!:mime application/spur-image
+0      belong   6521    Smalltalk image Spur 32b +C+NF (%d)
+!:mime application/spur-image
+0      lelong   68019   Smalltalk image Spur 64b +C+NF (%d)
+!:mime application/spur64-image
+4      belong   68019   Smalltalk image Spur 64b +C+NF (%d)
+!:mime application/spur64-image
+0      lelong   68021   Smalltalk image Spur 64b +C+NF+Tag (%d)
+!:mime application/spur64-image
+4      belong   68021   Smalltalk image Spur 64b +C+NF+Tag (%d)
+!:mime application/spur64-image
diff --git a/pkgs/development/pharo/wrapper/pharo-vm.sh b/pkgs/development/pharo/wrapper/pharo-vm.sh
new file mode 100644
index 00000000000..7ccab99cd76
--- /dev/null
+++ b/pkgs/development/pharo/wrapper/pharo-vm.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+# This is based on the script by David T. Lewis posted here:
+#  http://lists.squeakfoundation.org/pipermail/vm-dev/2017-April/024836.html
+#
+# VM run utility script
+# usage: run <myimage>
+#
+# Select a VM and run an image based on the image format number
+
+PATH=$PATH:@file@/bin
+
+# Search for the image filename in the command line arguments
+for arg in $* $SQUEAK_IMAGE; do
+    case ${arg} in
+        -*) # ignore
+        ;;
+        *) # either an option argument or the image name
+            if test -e ${arg}; then
+                magic=$(file -L -b -m @magic@ "$arg")
+                case "$magic" in
+                    "Smalltalk image V3 32b"*)
+                        image=${arg}
+                        vm=@cog32@/bin/pharo-cog
+                        ;;
+                    "Smalltalk image Spur 32b"*)
+                        image=${arg}
+                        vm=@spur32@/bin/pharo-spur
+                        ;;
+                    "Smalltalk image Spur 64b"*)
+                        if [ "@spur64vm@" == "none" ]; then
+                            echo "error: detected 64-bit image but 64-bit VM is not available" >&2
+                            exit 1
+                        fi
+                        image=${arg}
+                        vm=@spur64@/bin/pharo-spur64
+                        ;;
+                esac
+            fi
+            ;;
+    esac
+done
+
+# Print a message to explain our DWIM'ery.
+if [ -n "$image" ]; then
+    echo "using VM selected by image type."
+    echo "  image: $image"
+    echo "  type:  $magic"
+    echo "  vm:    $vm"
+else
+    echo "using default vm; image type not detected"
+    vm=@cog32@/bin/pharo-cog
+fi
+
+# Run the VM
+set -f
+exec -- ${vm} $@
+