Skip to content

Add flake.nix #4328

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,10 @@ in {
|| isVersionAtLeast "2.6" value.hawkSourceInfo.version))
];
latestVersionFrag = lib.head releaseFrags;
combined = pp // asmsFromReleaseArtifacts // releasesEmuHawkInstallables // {
inherit depsForHistoricalRelease populateHawkSourceInfo releaseTagSourceInfos;
combined = let
launchScriptsForLocalBuild = launchScriptsFor emuhawk-local.assemblies true;
in (pp // asmsFromReleaseArtifacts // releasesEmuHawkInstallables // {
inherit depsForHistoricalRelease populateHawkSourceInfo releaseTagSourceInfos launchScriptsForLocalBuild;
bizhawkAssemblies = pp.buildAssembliesFor (fillTargetOSDifferences hawkSourceInfoDevBuild);
"bizhawkAssemblies-${latestVersionFrag}" = pp.buildAssembliesFor
(fillTargetOSDifferences releaseTagSourceInfos."info-${latestVersionFrag}");
Expand All @@ -184,8 +186,27 @@ in {
IDEs = {
kate = [ kate omnisharp-roslyn ];
};
launchScriptsForLocalBuild = launchScriptsFor emuhawk-local.assemblies true;
};
shellHook = drv: ''
export BIZHAWKBUILD_HOME='${builtins.toString ./.}'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait does this work in Flakes?

Copy link
Author

@SignalWalker SignalWalker May 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, when evaluating as part of a flake, that ./. gets interpreted as a nix store path, so BIZHAWKBUILD_HOME is set to something like /nix/store/1igqk0g3q3bj6zhcfmrgzirzjsqbgpx9-source instead of something like /home/tasbot/bizhawk. That's fine for reading data, but the store is (usually) read-only, so $BIZHAWK_HOME doesn't work as-is (I assume).

I'm not really sure what the best way to solve this would be (especially in the case of someone doing something like nix develop github:tasemulators/bizhawk, since that would mean that the source dir only exists in the store).

nix develop sets environment variables for each of the derivation outputs (ex. $out), which might be useful. They're relative to the directory in which you invoke nix develop, though (ex. if you invoke nix develop ./.#emuhawk-latest in BizHawk/Dist, $out is set to BizHawk/Dist/outputs/out rather than BizHawk/outputs/out).

Do builds output to $BIZHAWKBUILD_HOME/output, or do they output to $BIZHAWK_HOME? If it's the latter, does anything expect $BIZHAWKBUILD_HOME to be writable? If things only expect to be able to write to $BIZHAWK_HOME, we could add an isFlake parameter to the shellHook function and export $BIZHAWK_HOME=$out, if we don't mind that $out isn't guaranteed to be relative to the project root.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it's fine to assume nix develop will only be called from the repo root, already checked-out.

BIZHAWKBUILD_HOME is used at build-time to locate the repo root (not for the main solution though). BIZHAWK_HOME is used at run-time, and it was mainly added for NixHawk so I don't think anything expects it to be writable, BUT it can't point to ${BizHawk-source}/output since that doesn't exist.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some scripts seem to expect to be able to find (and write to) $BIZHAWKBUILD_HOME/output, ex.:

cp target/debug/libwaterboxhost.so "$BIZHAWKBUILD_HOME/output/dll"

For $BIZHAWK_HOME, could we just mkdir -p it in the launch script, since that and PathExtensions.cs seem to be the only places it gets used?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can do that, but again, it needs to exist and contain the assemblies and other assets. The launch script is essentially cd $BIZHAWK_HOME; mono ./EmuHawk.exe.

No-one is going to be using EmuHawk's dev shell to build WaterboxHost. It can get its own shell when I eventually package it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, if the only thing we care about that uses it is the launch script, and we're assuming that nix develop is only being called from the repo root, then could we just do something like:

shellHook = isFlake: drv: ''
    export BIZHAWKBUILD_HOME="${builtins.toString ./.}"
    export BIZHAWK_HOME="${if isFlake then "$(pwd -P)" else "$BIZHAWKBUILD_HOME"}/output/"
    # ...
'';

As-is, if you're in a checked-out repo root, running Dist/BuildDebug.sh in nix develop seems to work completely fine and outputs to ${repo_root}/output (as in, not $BIZHAWKBUILD_HOME/output).

(This would mean, though, that the printf later on that tells the user where the build scripts are is misleading if you're in a flake, so I'll need to fix that.)

export BIZHAWK_HOME="$BIZHAWKBUILD_HOME/output/"
ldLibPath='${lib.makeLibraryPath drv.buildInputs}' # for running tests
if [ -z "$LD_LIBRARY_PATH" ]; then
export LD_LIBRARY_PATH="$ldLibPath"
else
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$ldLibPath"
fi
alias discohawk-monort-local='${launchScriptsForLocalBuild.discohawk}'
alias emuhawk-monort-local='${launchScriptsForLocalBuild.emuhawk}'
case "$-" in *i*)
pfx="$(realpath --relative-to="$PWD" "$BIZHAWKBUILD_HOME")/"
if [ "$pfx" = "./" ]; then pfx=""; fi
printf "%s\n%s\n" \
"Run ''${pfx}Dist/Build{Debug,Release}.sh to build the solution. You may need to clean up with ''${pfx}Dist/CleanupBuildOutputDirs.sh." \
"Once built, running {discohawk,emuhawk}-monort-local will pull from ''${pfx}output/* and use Mono from Nixpkgs."
;;
esac
'';
});
in combined // lib.listToAttrs (lib.concatLists (builtins.map
(f: [
{ name = f "latest-bin"; value = combined.${f "${latestVersionFrag}-bin"}; }
Expand Down
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
description = "EmuHawk is a multi-system emulator written in C#. As well as quality-of-life features for casual players, it also has recording/playback and debugging tools, making it the first choice for TASers (Tool-Assisted Speedrunners).";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs?ref=24.05";
};
outputs =
inputs@{ self, nixpkgs, ... }:
with builtins;
let
inherit (nixpkgs) lib;
systems = [
# this is currently the only supported system, according to https://github.com/TASEmulators/BizHawk/issues/1430#issue-396452488
"x86_64-linux"
];
nixpkgsFor = lib.genAttrs systems (
system:
import nixpkgs {
localSystem = builtins.currentSystem or system;
crossSystem = system;
overlays = [ ];
}
);
# import the derivations from default.nix for the given system & package set
importDefaultDerivationsWith =
system: pkgs:
# ./default.nix outputs some non-derivation attributes, so we have to filter those out
(lib.filterAttrs (name: val: lib.isDerivation val) (import ./default.nix { inherit system pkgs; }));
in
{
packages = mapAttrs (
system: pkgs:
(importDefaultDerivationsWith system pkgs)
// {
default = self.packages.${system}.emuhawk-latest-bin;
}
) nixpkgsFor;
devShells = mapAttrs (
system: pkgs:
let
avail = import ./default.nix { inherit system pkgs; };
mkShellCustom =
drv:
pkgs.mkShell {
packages = with pkgs; [
git
powershell
];
inputsFrom = [ drv ];
shellHook = avail.shellHook drv;
};
in
{
bizhawkAssemblies-latest = mkShellCustom avail.bizhawkAssemblies-latest;
discohawk-latest = self.devShells.${system}.bizhawkAssemblies-latest;
emuhawk-latest = self.devShells.${system}.bizhawkAssemblies-latest;
default = pkgs.mkShell {
packages = [ avail.emuhawk.hawkSourceInfo.dotnet-sdk ];
inputsFrom = [ self.devShells.${system}.emuhawk-latest ];
};
}
) nixpkgsFor;
};
}
21 changes: 1 addition & 20 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,7 @@
++ lib.optionals useVSCode [] #TODO https://devblogs.microsoft.com/dotnet/csharp-dev-kit-now-generally-available/ https://learn.microsoft.com/en-us/training/modules/implement-visual-studio-code-debugging-tools/
;
inputsFrom = [ drv ];
shellHook = ''
export BIZHAWKBUILD_HOME='${builtins.toString ./.}'
export BIZHAWK_HOME="$BIZHAWKBUILD_HOME/output/"
ldLibPath='${lib.makeLibraryPath drv.buildInputs}' # for running tests
if [ -z "$LD_LIBRARY_PATH" ]; then
export LD_LIBRARY_PATH="$ldLibPath"
else
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$ldLibPath"
fi
alias discohawk-monort-local='${avail.launchScriptsForLocalBuild.discohawk}'
alias emuhawk-monort-local='${avail.launchScriptsForLocalBuild.emuhawk}'
case "$-" in *i*)
pfx="$(realpath --relative-to="$PWD" "$BIZHAWKBUILD_HOME")/"
if [ "$pfx" = "./" ]; then pfx=""; fi
printf "%s\n%s\n" \
"Run ''${pfx}Dist/Build{Debug,Release}.sh to build the solution. You may need to clean up with ''${pfx}Dist/CleanupBuildOutputDirs.sh." \
"Once built, running {discohawk,emuhawk}-monort-local will pull from ''${pfx}output/* and use Mono from Nixpkgs."
;;
esac
'';
shellHook = avail.shellHook drv;
};
shells = lib.pipe avail [
(lib.mapAttrs (name: drv: if lib.hasPrefix "bizhawkAssemblies-" name then drv else drv.assemblies or null))
Expand Down