Has anyone used Nix from within Xcode build phase shell scripts?

I’m trying to figure out right now if there’s a good solution for using Nix to provide the scripting environments used by Xcode build phase shell scripts. The big issue of course is the fact that Xcode doesn’t run my local shell setup.

I can think of various workarounds, including just having the build phase script be a bash script that sources my setup before invoking the real script elsewhere, but unfortunately all the workarounds I can think of rely on knowing where the profile setup is, and that’s different for single-user vs multi-user install. The only workarounds I can think of that don’t involve this require the user to customize their Xcode’s “Custom Paths” global preference to specify where the Nix setup script is, which is kind of an awkward thing to ask developers to do. Alternatively I could have my script run a login Bash shell (thus requiring devs to configure Bash even if they use another shell normally), but then that means the build environment is affected by the developer’s personal login shell configuration, which might not be great.

Has anyone else come up with a successful solution here that doesn’t assume single-user Nix install?

1 Like

This is an old post, and I’ve since left the company where I was working on this, but my recollection is that I solved this by by simply requiring all our devs to use a multi-user Nix install (which is to say, I told them precisely what command to run to install Nix). My build scripts then could just source a single bash file as “setup” that sourced the multi-user Nix profile, and then following that they ran other scripts that used #!/usr/bin/env nix-shell shebangs.

I did consider detecting whether we wanted single-user or multi-user, I did come up with a reasonable approach a while ago, but ultimately we wanted everyone to have the same Nix setup for ease of debugging anyway.


Thanks a lot for your solution! This is also what I came up with. For the reader without too much nix/sh-knowledge this is what how the skripts in our build-phase now start:

# Nix
if [ -e "$nixSource" ]; then
  . "$nixSource"
  (echo "The build-skript requires a multi-user nix installation. Install it as multi-user (with \`--deamon\`), then \`$nixSource\` should exist"
  echo 'If that does not work check the skripts in $ProjectName => Targets $Target => "Build Phases"') 1>&2
  exit 1
# End Nix
nix-shell ../shell.nix --run '
# Put here whatever you would normally run in the script