xcode-select, xcrun & Friends

Published on

macOS Developer Directory

macOS has the notion of a system-wide active developer directory for Xcode and BSD tools. It contains necessary programs to be able build applications and perform supporting functions.

Inside /usr/bin, you will find many programs like a compiler ( /usr/bin/clang) or a linker ( /usr/bin/ld) but those are just shims. When you execute them, they will invoke the respective tool inside the active developer directory.

Interaction with the active developer directory is usually performed with two tools: xcode-select and xcrun. xcode-select is used to get and set the active path, while xcrun is used to execute tools and find their paths from within the developer directory.

An undocumented aspect (or an implementation detail) is the /var/db/xcode_select_link symlink which points to the active developer directory. This provides an alternative way to access the active path.

Use Cases

You might be wondering what situations require the usage of symlink rather than using xcode-select -p. There’s at least one interesting use case.

Imagine you want to link against a library inside the toolchain: e.g., libswiftDemangle.dylib, libclang.dylib or libtapi.dylib. You must provide a path at link time but you do not it in advance, as it can change dynamically, by definition.

As the aforementioned libraries use rpath-relative install names, you can just pass -rpath /var/db/xcode_select_link/Toolchains/XcodeDefault.xctoolchain/usr/lib at link time (remember to use -Xlinker or -Wl if using the Clang driver).

The above technique is used by the zld linker.

A word of caution: the ABI of any such libraries can change in-between major Xcode versions, so your tools might mysteriously end up crashing or corrupting memory.

References

← Back to Writings