Skip to content
Merged
Changes from 1 commit
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
22 changes: 20 additions & 2 deletions assets/nix/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ abs_path() {
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}

# Set executable path and the extension to use for the libdoorstop shared object
# Set executable path and the extension to use for the libdoorstop shared object as well as check whether we're running on Apple Silicon
os_type="$(uname -s)"
case ${os_type} in
Linux*)
Expand All @@ -148,6 +148,14 @@ case ${os_type} in
;;
esac
lib_extension="dylib"

# CPUs for Apple Silicon are in the format "Apple M.."
cpu_type="$(sysctl -n machdep.cpu.brand_string)"
case "${cpu_type}" in
Apple*)
is_apple_silicon=1
;;
esac
Comment on lines +152 to +158
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

My understanding is that on Intel Macs this would be something like Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz.

I don't have an Intel Mac to test this but I've reached out to a mate with one to check the output as a sanity check

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe uname -m would work? Is there a world where this matches on Linux?

Copy link
Copy Markdown
Contributor Author

@nskobelevs nskobelevs Sep 24, 2025

Choose a reason for hiding this comment

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

The uname shipped with MacOS is also a universal binary so it falls into the same pitfalls where it'll just run it via Rosetta and return x86_64.

Could run it via arch and ARCHPREFERENCES like the main executable but I'm not actually sure if the arch command shipped on Intel Macs behaves the same without throwing a fit. Will have someone who has an Intel Mac check this.

Is there a world where this matches on Linux?

My understanding is that machdep is an Apple only namespace, plus this is in the *Darwin*) branch so linux wouldn't reach here.

;;
*)
# alright whos running games on freebsd
Expand Down Expand Up @@ -309,4 +317,14 @@ else
export DYLD_INSERT_LIBRARIES="${doorstop_name}:${DYLD_INSERT_LIBRARIES}"
fi

exec "$executable_path" "$@"
if [ -n "${is_apple_silicon}" ]; then
export ARCHPREFERENCE="arm64,x86_64"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

From man arch:

ENVIRONMENT
     The environment variable ARCHPREFERENCE can be used to provide architecture order preferences.  It is checked before looking for the
     corresponding property list file.

...

ARCHPREFERENCE Values
  i386,x86_64,x86_64h,arm64,arm64e
    A specifier that matches any name.

This tells arch to prefer arm64 and only fallback to x86_64 if arm64 is not suitable for this executable.
This works as expected regardless of whether the executable is universal, arm64 or solely x86_64.


# We need to use arch for Apple Silicon to allow the executable to be run natively as otherwise if
# the executable is universal, supporting both x86_64 and arm64, MacOs will still run it as x86_64
# if the parent process is running as x86.
# arch also strips the DYLD_INSERT_LIBRARIES env var so we have to pass that in manually
arch -e DYLD_INSERT_LIBRARIES=$DYLD_INSERT_LIBRARIES "$executable_path" "$@"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I wasn't able to find concrete docs on DYLD_INSERT_LIBRARIES being stripped here but my guess it's done so that you don't try to run an arm64 process with a x86_64 preload so the setting has to be explicit.

Without this the env var is null in the main exec and the dylib doesn't get loaded at all.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Shouldn't $DYLD_INSERT_LIBRARIES be in quotes, or is there no chance of it having a space? Also I couldn't find docs on the -e switch from a quick search, is this macos-only?

Copy link
Copy Markdown
Contributor Author

@nskobelevs nskobelevs Sep 24, 2025

Choose a reason for hiding this comment

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

Good catch, fixed: d4b21af

And yeah looks like -e is macOS only - the macOS arch version seems to have a bunch of other functionality. Here's the full dump of the man page.

From man arch:

     -e envname=value	     Assigns the given value to the named environment
			     variable in the environment that will be passed
			     to the command to be run.	Any existing
			     environment variable with the same name will be
			     replaced.

else
exec "$executable_path" "$@"
fi
Loading