Alright, I got it working on NixOS, and this is now mostly reproducable. It would work better if I was able to specify a separate Disk directory, but essentialy here's what needs to be done:
Inside your project directory create the following files:
# shell.nix
{ pkgs ? import <nixpkgs> { overlays = [ (import ./nix/playdate-sdk/overlay.nix) ]; } }:
pkgs.mkShell {
nativeBuildInputs = with pkgs.buildPackages; [ cmake playdate-sdk gcc-arm-embedded ];
shellHook = ''
export PLAYDATE_NIX_PATH="${pkgs.playdate-sdk.outPath}"
export PLAYDATE_SDK_PATH="${builtins.toString ./playdate-sdk}"
export SDL_AUDIODRIVER=pulseaudio
'';
}
# nix/playdate-sdk/overlay.nix
let
# this was taken from a gist which involved cross compilation. This is probably a weird thing to do.
pkgs = import <nixpkgs> {};
in
final: prev: rec {
inherit pkgs;
playdate-sdk = prev.callPackage ./playdate-sdk.nix {};
}
# nix/playdate-sdk/playdate-sdk.nix
{
stdenv,
lib,
fetchurl,
pkgs,
wrapGAppsHook,
}: let
# Build inputs for `pdc`
pdcInputs = with pkgs; [
stdenv.cc.cc.lib
libpng
zlib
];
# Build inputs for the simulator (excluding those from pdc)
pdsInputs = with pkgs; [
udev
gtk3
pango
cairo
gdk-pixbuf
glib
webkitgtk
xorg.libX11
stdenv.cc.cc.lib
libxkbcommon
wayland
libpulseaudio
gsettings-desktop-schemas
];
dynamicLinker = "${pkgs.glibc}/lib/ld-linux-x86-64.so.2";
in
stdenv.mkDerivation rec {
pname = "playdate-sdk";
version = "2.0.3";
src = fetchurl {
url = "https://download.panic.com/playdate_sdk/Linux/PlaydateSDK-${version}.tar.gz";
sha256 = "sha256-FNzb3OjXGZpTTuR9+ox9KZD0sKlYfoA7jg48lZeQrpE=";
};
buildInputs = pdcInputs;
nativeBuildInputs = [ pkgs.makeWrapper wrapGAppsHook ];
dontFixup = true;
installPhase = ''
runHook preInstall
# Get our new root
root=$out/opt/playdate-sdk-${version}
# Everything else
mkdir -p $out/opt/playdate-sdk-${version}
cp -r ./ $out/opt/playdate-sdk-${version}
ln -s $root $out/opt/playdate-sdk
# Setup dependencies and interpreter
patchelf \
--set-interpreter "${dynamicLinker}" \
--set-rpath "${lib.makeLibraryPath pdcInputs}" \
$root/bin/pdc
patchelf \
--set-interpreter "${dynamicLinker}" \
$root/bin/pdutil
patchelf \
--set-interpreter "${dynamicLinker}" \
--set-rpath "${lib.makeLibraryPath pdsInputs}"\
$root/bin/PlaydateSimulator
# Binaries
mkdir -p $out/bin
cp $root/bin/pdc $out/bin/pdc
cp $root/bin/pdutil $out/bin/pdutil
makeWrapper $root/bin/PlaydateSimulator $out/bin/PlaydateSimulator \
--suffix XDG_DATA_DIRS : ${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}
cp -r $root/C_API $out/C_API
cp -r $root/CoreLibs $out/CoreLibs
cp -r $root/Resources $out/Resources
cp -r $root/Disk $out/Disk
runHook postInstall
'';
}
Enter a nix-shell at the root of the project directory. This will download the playdate sdk and install pdc, pdutil, and PlaydateSimulator inside the shell. It may need to rebuild a bunch of libraries. At this point pdc and pdutil both work fine, and if you only need to use those you're done. However, PlaydateSimulator needs PlaydateSDK/Disk to be writable, because the nix store is unwritable this will cause a bunch of errors. You can get around this by creating a replica of the playdate sdk folder using symlinks, with a Disk folder that isn't symlinked. You can do it using this script:
#/usr/bin/env sh
# make-symlinks.sh
rm -r playdate-sdk
mkdir -p playdate-sdk
echo $PLAYDATE_NIX_PATH
echo $PLAYDATE_SDK_PATH
# Disk is the only writable part
cp -TR $PLAYDATE_NIX_PATH/Disk $PLAYDATE_SDK_PATH/Disk
chmod -R 755 $PLAYDATE_SDK_PATH/Disk
ln -s $PLAYDATE_NIX_PATH/bin $PLAYDATE_SDK_PATH/bin
ln -s $PLAYDATE_NIX_PATH/C_API $PLAYDATE_SDK_PATH/C_API
ln -s $PLAYDATE_NIX_PATH/CoreLibs $PLAYDATE_SDK_PATH/CoreLibs
ln -s $PLAYDATE_NIX_PATH/Resources $PLAYDATE_SDK_PATH/Resources
Now this part is a little janky, I couldn't figure out why PlaydateSimulator doesn't respect $PLAYDATE_SDK_PATH you need to set it to your writable playdate-sdk location using the file picker dialog inside of the simulator under File > Set SDK Path. Also because I'm using KDE Plasma and maybe don't have it all set up 100% correctly I get
(PlaydateSimulator:42776): GLib-GIO-ERROR **: 21:12:20.549: Settings schema 'org.gtk.Settings.FileChooser' is not installed
This is almost certainly fixable inside of playdate-sdk.nix or shell.nix, but I couldn't figure it out. As a workaround, the first time you launch PlaydateSimulator do it like this
steam-run PlaydateSimulator
and the file picker will work just fine. Point it at the directory with the writable Disk, in my case it's $PROJECT_ROOT/playdate-sdk. Subsequent launches of PlaydateSimulator will just work .
Obviously only use this if you agree to the Playdate SDK EULA.