# Platform Notes {#chap-platform-notes}
## Darwin (macOS) {#sec-darwin}
The Darwin `stdenv` differs from most other ones in Nixpkgs in a few key ways.
These differences reflect the default assumptions for building software on that platform.
In many cases, you can ignore these differences because the software you are packaging is already written with them in mind.
When you do that, write your derivation as normal. You don’t have to include any Darwin-specific special cases.
The easiest way to know whether your derivation requires special handling for Darwin is to write it as if it doesn’t and see if it works.
If it does, you’re done; skip the rest of this.
- Darwin uses Clang by default instead of GCC. Packages that refer to `$CC` or `cc` should just work in most cases.
Some packages may hardcode `gcc` or `g++`. You can usually fix that by setting `makeFlags = [ "CC=cc" "CXX=C++" ]`.
If that does not work, you will have to patch the build scripts yourself to use the correct compiler for Darwin.
- Darwin needs an SDK to build software.
The SDK provides a default set of frameworks and libraries to build software, most of which are specific to Darwin.
There are multiple versions of the SDK packages in Nixpkgs, but one is included by default in the `stdenv`.
Usually, you don’t have to change or pick a different SDK. When in doubt, use the default.
- The SDK used by your build can be found using the `DEVELOPER_DIR` environment variable.
There are also versions of this variable available when cross-compiling depending on the SDK’s role.
The `SDKROOT` variable is also set with the path to the SDK’s libraries and frameworks.
`SDKROOT` is always a sub-folder of `DEVELOPER_DIR`.
- Darwin includes a platform-specific tool called `xcrun` to help builds locate binaries they need.
A version of `xcrun` is part of the `stdenv` on Darwin.
If your package invokes `xcrun` via an absolute path (such as `/usr/bin/xcrun`), you will need to patch the build scripts to use `xcrun` instead.
To reiterate: you usually don’t have to worry about this stuff.
Start with writing your derivation as if everything is already set up for you (because in most cases it already is).
If you run into issues or failures, continue reading below for how to deal with the most common issues you may encounter.
### Darwin Issue Troubleshooting {#sec-darwin-troubleshooting}
#### Package requires a non-default SDK or fails to build due to missing frameworks or symbols {#sec-darwin-troubleshooting-using-sdks}
In some cases, you may have to use a non-default SDK.
This can happen when a package requires APIs that are not present in the default SDK.
For example, Metal Performance Shaders were added in macOS 12.
If the default SDK is 11.3, then a package that requires Metal Performance Shaders will fail to build due to missing frameworks and symbols.
To use a non-default SDK, add it to your derivation’s `buildInputs`.
It is not necessary to override the SDK in the `stdenv` nor is it necessary to override the SDK used by your dependencies.
If your derivation needs a non-default SDK at build time (e.g., for a `depsBuildBuild` compiler), see the cross-compilation documentation for which input you should use.
When determining whether to use a non-default SDK, consider the following:
- Try building your derivation with the default SDK. If it works, you’re done.
- If the package specifies a specific version, use that. See below for how to map Xcode version to SDK version.
- If the package’s documentation indicates it supports optional features on newer SDKs, consider using the SDK that enables those features.
If you’re not sure, use the default SDK.
Note: It is possible to have multiple, different SDK versions in your inputs.
When that happens, the one with the highest version is always used.
```nix
stdenv.mkDerivation {
name = "libfoo-1.2.3";
# ...
buildInputs = [ apple-sdk_14 ];
}
```
#### What is a “deployment target” (or minimum version)? {#sec-darwin-troubleshooting-using-deployment-targets}