Warning
macOS is not fully supported. The build process may not work on some machines. We try to upload pre-build installer in each release.
Important
If you're on M1 or newer mac, you also have to enable Rosetta virtualization on Terminal application. That has to be done before you start the build process or install dependencies. You might have to reinstall dependencies if you've already had installed them.
To build AYON you will need some tools and libraries. We do not provide any of these tools. You have to install them yourself.
- Terminal
- Homebrew
- git
- uv
- Python 3.11
- CMake
- XCode Command Line Tools (or some other build system).
Easy way of installing everything necessary is to use Homebrew.
-
Install Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -
Install cmake and create-dmg:
brew install cmake create-dmg
-
Install uv:
brew install uv
-
Pull in required Python version 3.11.x:
# install Python build dependences brew install openssl readline sqlite3 xz zlib # replace with up-to-date 3.11.x version uv python install 3.11.9
git clone --recurse-submodules git@github.com:ynput/ayon-launcher.gitCreate virtual environment in ./.venv and install python runtime dependencies like PySide, Pillow..
./tools/make.sh create-env
./tools/make.sh install-runtime-dependencies
Build AYON in ./build/.
./tools/make.sh build
Build should create ./build/AYON {version}.app file.
Create installer that can be distributed to server and workstations.
./tools/make.sh make-installer
Output installer is in ./build/installer/ directory. You should find .dmg and .json file. JSON file contains metadata required for server.
For distributing AYON outside the Mac App Store (as a standalone application), code signing and notarization are required for modern macOS security policies.
- Apple Developer Account - Register at developer.apple.com
- Developer ID Certificate - Obtained from Apple Developer portal
- Team ID - Your 10-character team identifier (found in Apple Developer portal)
See tools/macos/SIGNING_CONFIG.md for detailed setup instructions, including:
- Creating Apple Developer certificates
- Setting up notarization credentials
- Configuring environment variables
- Troubleshooting common issues
export AYON_APPLE_CODESIGN="1"
export AYON_APPLE_SIGN_IDENTITY="Developer ID Application: Your Name (XXXXXXXXXX)"
./tools/make.sh build-make-installerNote
Using the certificate's hash instead of name is recommended for CI environments
export AYON_APPLE_CODESIGN="1"
export AYON_APPLE_SIGN_IDENTITY="Developer ID Application: Your Name (XXXXXXXXXX)"
export AYON_APPLE_TEAM_ID="XXXXXXXXXX"
export AYON_APPLE_NOTARIZE="1"
export AYON_APPLE_NOTARIZE_KEYCHAIN_PROFILE="ayon-notarize"
./tools/make.sh build-make-installerNote
Using the certificate's hash instead of name is recommended for CI environments
export AYON_APPLE_CODESIGN="0"
export AYON_APPLE_NOTARIZE="0"
./tools/make.sh build-make-installerexport AYON_APPLE_SIGN_IDENTITY="Developer ID Application: Your Name (XXXXXXXXXX)"
export AYON_APPLE_DRY_RUN="1"
./tools/make.sh build-make-installerAfter building, verify the code signatures and notarization:
# Check app bundle signature
codesign -v -v build/AYON\ *.app
# Check DMG signature (if notarized and stapled)
xcrun stapler validate build/installer/AYON-*.dmg
# Run Gatekeeper assessment
spctl --assess --verbose build/installer/AYON-*.dmg| Variable | Required | Description |
|---|---|---|
AYON_APPLE_CODESIGN |
No | Set to 1 to enable code signing, or 0 to skip signing entirely (default) |
AYON_APPLE_SIGN_IDENTITY |
Yes (for signing) | Certificate identity (name or hash) |
AYON_APPLE_TEAM_ID |
No | Team ID for hardened runtime (10 chars) |
AYON_APPLE_ENTITLEMENTS |
No | Path to entitlements file (defaults to tools/macos/ayon.entitlements) |
AYON_APPLE_NOTARIZE |
No | Set to 1 to enable notarization submission (only applied when AYON_APPLE_CODESIGN=1) |
AYON_APPLE_NOTARIZE_KEYCHAIN_PROFILE |
No (if using Apple ID) | Keychain profile name for notarization |
AYON_APPLE_NOTARIZE_APPLE_ID |
No (if using profile) | Apple ID email for notarization |
AYON_APPLE_NOTARIZE_PASSWORD |
No (if using profile) | Apple ID app-specific password |
AYON_APPLE_NOTARIZE_TEAM_ID |
No (if using profile) | Team ID for notarization auth |
AYON_APPLE_BUNDLE_ID |
No | Main app bundle ID (defaults to com.ayon.launcher) |
AYON_APPLE_SHIM_BUNDLE_ID |
No | Shim app bundle ID (defaults to com.ayon.launcher.shim) |
AYON_APPLE_DRY_RUN |
No | Set to 1 for dry-run (print commands) |
AYON_APPLE_VERBOSE |
No | Set to 1 for verbose logging |
The AYON launcher uses deterministic multi-stage code signing to ensure valid signatures for all nested content:
Pre-step: Strip Extended Attributes
- Removes resource forks, Finder info, quarantine flags, and other extended attributes
- macOS
codesignrefuses to seal bundles containing these
Step 0: Strip Spurious +x Bits
- Removes executable permission from files that are not Mach-O binaries
- Prevents signing errors on non-code files with stray executable bits
Step 1: Relocate Non-Code to Resources
- Moves Python scripts, configs, and data files from
Contents/MacOS/toContents/Resources/ - Creates relative symlinks in
MacOS/to preserve runtime path resolution - macOS
codesigntreats everything underMacOS/as code that must be individually signed
Step 2: Sign Nested Bundles (Deepest-First)
- Discovers all
.appand.frameworkbundles in the tree - Signs them inside-out: deepest bundles first, same-depth in parallel
- Each bundle: sign loose Mach-O files, then seal the bundle itself
Step 3: Sign Loose Mach-O Binaries
- Signs remaining executable files at the top level
- Excludes the main
CFBundleExecutable(signed during bundle sealing)
Step 4: Seal Top-Level App Bundle
- Signs the main executable and seals the entire
.appbundle - Applies entitlements and hardened runtime flags
This inside-out ordering ensures child bundles are valid before their parents, meeting Apple's hardened runtime requirements.
Two entitlements files are provided:
tools/macos/ayon.entitlements- Main launcher (full capabilities)tools/macos/ayon_helper.entitlements- Helper executables (restricted)
These enable:
- Python JIT compilation (required for Python runtime)
- Unsigned executable memory loading
- Dynamic library loading for Python extensions
- Network client/server connections
- File access via user dialogs
- Keychain access for credential storage
When both AYON_APPLE_CODESIGN=1 and AYON_APPLE_NOTARIZE=1 are set:
- After DMG creation, the installer is submitted to Apple's notarization service
- Notarization status is polled (typically 2-10 minutes)
- If successful, the notarization ticket is stapled to the DMG
- Stapling embeds the ticket, allowing offline verification
Signature verification fails:
# Re-verify with verbose output
codesign -d -vv build/AYON\ *.appNotarization rejected:
# Check detailed rejection reason
xcrun notarytool history --keychain-profile <profile>"Codesign not found":
# Install Xcode command-line tools
xcode-select --installFor more troubleshooting, see tools/macos/SIGNING_CONFIG.md.
For automated building and signing in CI/CD pipelines (e.g., GitHub Actions):
- Store certificate as base64-encoded GitHub secret:
APPLE_DEVELOPER_ID_CERTIFICATE - Store certificate password as secret:
APPLE_DEVELOPER_ID_PASSWORD - Store notarization credentials as secrets (app-specific password or API key)
- Configure workflow to export certificate and set environment variables
- Run
./tools/make.sh build-make-installer
Example GitHub Actions snippet:
- name: Import Code Signing Certificate
uses: apple-actions/import-codesign-certs@v2
with:
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_ID_CERTIFICATE }}
p12-password: ${{ secrets.APPLE_DEVELOPER_ID_PASSWORD }}
- name: Build and Sign AYON
env:
AYON_APPLE_CODESIGN: '1'
AYON_APPLE_SIGN_IDENTITY: ${{ secrets.APPLE_SIGN_IDENTITY }}
AYON_APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
AYON_APPLE_NOTARIZE: '1'
AYON_APPLE_NOTARIZE_KEYCHAIN_PROFILE: ayon-notarize-ci
run: ./tools/make.sh build-make-installerFor non-release CI builds, set AYON_APPLE_CODESIGN: '0' and AYON_APPLE_NOTARIZE: '0'.