summary refs log tree commit diff
path: root/pkgs/development/pharo
diff options
context:
space:
mode:
authorJoachim Fasting <joachifm@fastmail.fm>2017-08-26 15:17:21 +0200
committerJoachim Fasting <joachifm@fastmail.fm>2017-08-26 15:17:33 +0200
commit5ddacdc3a89e609db13a7cd47839edc4ac8cfaba (patch)
tree1fc6b526add4c6cd9b1a0047008104614de4b6d1 /pkgs/development/pharo
parent66b42344f31b5c6a9cd58caa358d944eb1cf5f58 (diff)
parent2b3dcfab041ec7413e456f4f6a3ae0af69f3b255 (diff)
downloadnixpkgs-5ddacdc3a89e609db13a7cd47839edc4ac8cfaba.tar
nixpkgs-5ddacdc3a89e609db13a7cd47839edc4ac8cfaba.tar.gz
nixpkgs-5ddacdc3a89e609db13a7cd47839edc4ac8cfaba.tar.bz2
nixpkgs-5ddacdc3a89e609db13a7cd47839edc4ac8cfaba.tar.lz
nixpkgs-5ddacdc3a89e609db13a7cd47839edc4ac8cfaba.tar.xz
nixpkgs-5ddacdc3a89e609db13a7cd47839edc4ac8cfaba.tar.zst
nixpkgs-5ddacdc3a89e609db13a7cd47839edc4ac8cfaba.zip
Merge remote-tracking branch 'lukego/pharo6-for-nixpkgs'
Closes https://github.com/NixOS/nixpkgs/pull/26924
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.nix78
-rw-r--r--pkgs/development/pharo/vm/build-vm.nix147
-rw-r--r--pkgs/development/pharo/vm/default.nix34
-rw-r--r--pkgs/development/pharo/vm/share.nix6
-rw-r--r--pkgs/development/pharo/vm/vms.nix46
-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
9 files changed, 392 insertions, 90 deletions
diff --git a/pkgs/development/pharo/launcher/default.nix b/pkgs/development/pharo/launcher/default.nix
index 911680b1eb8..9cec6e81ae6 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..b2e37344afc
--- /dev/null
+++ b/pkgs/development/pharo/vm/build-vm-legacy.nix
@@ -0,0 +1,78 @@
+{ stdenv, fetchurl, cmake, bash, unzip, glibc, openssl, gcc, mesa, freetype, xorg, alsaLib, cairo, libuuid, makeWrapper, ... }:
+
+{ 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
+
+    # Add cairo library to the library path.
+    wrapProgram $prefix/bin/pharo-cog --prefix LD_LIBRARY_PATH : ${LD_LIBRARY_PATH}
+
+    ln -s "${pharo-share}/lib/"*.sources $prefix/lib/$name
+  '';
+
+  LD_LIBRARY_PATH = stdenv.lib.makeLibraryPath [ cairo mesa freetype openssl libuuid alsaLib xorg.libICE xorg.libSM ];
+  nativeBuildInputs = [ unzip cmake gcc makeWrapper ];
+  buildInputs = [ bash glibc openssl 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 c855919f802..378c89d8d90 100644
--- a/pkgs/development/pharo/vm/build-vm.nix
+++ b/pkgs/development/pharo/vm/build-vm.nix
@@ -1,76 +1,109 @@
-{ 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, gcc48, ... }:
 
-{ 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.";
 
-  hardeningDisable = [ "format" "pic" ];
+  # Shared data (for the sources file)
+  pharo-share = import ./share.nix { inherit stdenv fetchurl unzip; };
 
-  # Building
-  preConfigure = ''
-    cd build/
+  # Note: -fPIC causes the VM to segfault.
+  hardeningDisable = [ "format" "pic"
+                       # while the VM depends on <= gcc48:
+                       "stackprotector" ];
+
+  # Regenerate the configure script.
+  # Unnecessary? But the build breaks without this.
+  autoreconfPhase = ''
+    pushd platforms/unix/config
+    make
+    popd
   '';
-  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 = "-DPharoVM -DIMMUTABILITY=1 -msse2 -D_GNU_SOURCE -DCOGMTVM=0 -g -O2 -DNDEBUG -DDEBUGVM=0";
+  LDFLAGS = "-Wl,-z,now";
+
+  # VM sources require some patching before build.
+  prePatch = ''
+    patchShebangs build.${flavor}
+    # Fix hard-coded path to /bin/rm in a script
+    sed -i -e 's:/bin/rm:rm:' 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} $!' \
+           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 = ''
+    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"
+
+    # 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/${binary-basename}-x $prefix/bin/${binary-basename}-nox
-
-    ln -s "${pharo-share}/lib/"*.sources $prefix/lib/$name
+    chmod +x "$out/bin/${cmd}"
   '';
 
-  buildInputs = [ bash unzip cmake glibc openssl gcc mesa freetype xorg.libX11 xorg.libICE xorg.libSM alsaLib cairo pharo-share ];
+  enableParallelBuilding = true;
+
+  # gcc 4.8 used for the build:
+  #
+  # gcc5 crashes during compilation; gcc >= 4.9 produces a
+  # binary that crashes when forking a child process. See:
+  # http://forum.world.st/OSProcess-fork-issue-with-Debian-built-VM-td4947326.html
+  #
+  # (stack protection is disabled above for gcc 4.8 compatibility.)
+  buildInputs = [ bash unzip glibc openssl gcc48 mesa freetype xorg.libX11 xorg.libICE xorg.libSM alsaLib cairo pharo-share libuuid autoreconfHook ];
 
   meta = {
     description = "Clean and innovative Smalltalk-inspired environment";
@@ -89,7 +122,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 (macOS)
     platforms = with stdenv.lib;
                   intersectLists
diff --git a/pkgs/development/pharo/vm/default.nix b/pkgs/development/pharo/vm/default.nix
index aca5c37d265..e6269503a4c 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, makeWrapper, ...} @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/share.nix b/pkgs/development/pharo/vm/share.nix
index aba42e3981c..54e686c82fe 100644
--- a/pkgs/development/pharo/vm/share.nix
+++ b/pkgs/development/pharo/vm/share.nix
@@ -31,6 +31,11 @@ stdenv.mkDerivation rec {
     sha256 = "0ykl1y0a4yy5qn8fwz0wkl8fcn4pqv9q0w0r2llhzdz3jdg1k69g";
   };
 
+  sources60Zip = fetchurl {
+    url = http://files.pharo.org/sources/PharoV60.sources.zip;
+    sha256 = "0xbdi679ryb2zg412xy6zkh22l20pmbl92m3qhfgzjvgybna8z2a";
+  };
+
   buildInputs = [ unzip ];
 
   installPhase = ''
@@ -43,6 +48,7 @@ stdenv.mkDerivation rec {
     unzip ${sources30Zip} -d $prefix/lib/
     unzip ${sources40Zip} -d $prefix/lib/
     unzip ${sources50Zip} -d $prefix/lib/
+    unzip ${sources60Zip} -d $prefix/lib/
   '';
 
   meta = {
diff --git a/pkgs/development/pharo/vm/vms.nix b/pkgs/development/pharo/vm/vms.nix
new file mode 100644
index 00000000000..5258f4f6e77
--- /dev/null
+++ b/pkgs/development/pharo/vm/vms.nix
@@ -0,0 +1,46 @@
+{ cmake, stdenv, fetchurl, bash, unzip, glibc, openssl, gcc, mesa, freetype, xorg, alsaLib, cairo, libuuid, autoreconfHook, gcc48, fetchFromGitHub, makeWrapper} @args:
+
+let
+  pharo-vm-build = import ./build-vm.nix args;
+  pharo-vm-build-legacy = import ./build-vm-legacy.nix args;
+in
+
+let suffix = if stdenv.is64bit then "64" else "32"; in
+
+rec {
+  # Build the latest VM
+  spur = pharo-vm-build rec {
+    name = "pharo-spur${suffix}";
+    version = "git.${revision}";
+    src = fetchFromGitHub {
+      owner = "pharo-project";
+      repo = "pharo-vm";
+      rev = revision;
+      sha256 = "0dkiy5fq1xn2n93cwf767xz24c01ic0wfw94jk9nvn7pmcfj7m62";
+    };
+    # This metadata will be compiled into the VM and introspectable
+    # from Smalltalk. This has been manually extracted from 'git log'.
+    #
+    # The build would usually generate this automatically using
+    # opensmalltalk-vm/.git_filters/RevDateURL.smudge but that script
+    # is too impure to run from nix.
+    revision = "6a63f68a3dd4deb7c17dd2c7ac6e4dd4b0b6d937";
+    source-date = "Tue May 30 19:41:27 2017 -0700";
+    source-url  = "https://github.com/pharo-project/pharo-vm";
+  };
+
+  # Build an old ("legacy") CogV3 VM for running pre-spur images.
+  # (Could be nicer to build the latest VM in CogV3 mode but this is
+  # not supported on the Pharo VM variant at the moment.)
+  cog = pharo-vm-build-legacy rec {
+    version = "2016.02.18";
+    name = "pharo-cog${suffix}";
+    base-url = http://files.pharo.org/vm/src/vm-unix-sources/blessed;
+    src = fetchurl {
+      url = "${base-url}/pharo-vm-${version}.tar.bz2";
+      sha256 = "16n2zg7v2s1ml0vvpbhkw6khmgn637sr0d7n2b28qm5yc8pfhcj4";
+    };
+  };
+
+}
+
diff --git a/pkgs/development/pharo/wrapper/default.nix b/pkgs/development/pharo/wrapper/default.nix
new file mode 100644
index 00000000000..f60b8a6d203
--- /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";
+  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..d5bd1a2d801
--- /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}" "$@"
+