Skip to content

Building and Signing

Aleksandr Shabelnikov edited this page Aug 8, 2026 · 1 revision

Building and signing ASFireWire yourself

For installing a prebuilt release instead, see Installing.

Prerequisites

  • Xcode with the macOS 26 (Tahoe) SDK
  • Homebrew
  • XcodeGen: brew install xcodegen
  • Free Apple Developer account

ASFW.xcodeproj is generated from project.yml and is ignored by git. Do not edit the generated project or hand-tune settings in Xcode; change project.yml and let build.sh regenerate it.

Build

For an installable local build:

./build.sh --config Release

The script regenerates the Xcode project, refreshes the generated version metadata, and builds with code signing disabled (CODE_SIGNING_ALLOWED=NO). The resulting app is normally at:

build/DerivedData/Build/Products/Release/ASFW.app

The default configuration is Debug. Useful variants include:

./build.sh --verbose --config Release
./build.sh --no-bump --config Debug
./build.sh --test-only
./build.sh --swift-test-only

Each normal installable build increments CFBundleVersion through bump.sh. Use --no-bump when you are not going to install the result. For an installed extension, a higher build number is still the safest replacement workflow. The app's Require a newer build guard is now off by default and can be enabled in Overview → Driver Management when you want the app itself to reject equal or older replacements.

Or use Xcode to build ASFW.xcodeproj

Entitlements and Apple accounts

DriverKit entitlements are policy-controlled by Apple. A paid Apple Developer membership alone does not guarantee access to restricted entitlements.

The repository's local and test-release workflow does not use a provisioning profile. build.sh produces an unsigned bundle, and sign.sh ad-hoc signs it with the entitlement plists stored in the repository. This is separate from Apple's provisioned-signing path. The ad-hoc workflow is intended for experimental testing and requires SIP to remain disabled together with system-extension developer mode.

Sign the build

If you are building from Xcode — it will sign for you.

Run the signer against the default Release output:

./sign.sh

For a Debug build or a custom DerivedData directory, pass the same values through the environment or provide the app path explicitly:

CONFIGURATION=Debug ./sign.sh
./build.sh --config Release --derived ./build/DerivedDataRelease
DERIVED=./build/DerivedDataRelease CONFIGURATION=Release ./sign.sh
./sign.sh /absolute/path/to/ASFW.app

sign.sh:

  1. finds the dext inside Contents/Library/SystemExtensions;
  2. signs the dext first with ASFWDriver/ASFWDriver.entitlements;
  3. signs the enclosing app with ASFW/App.entitlements; and
  4. verifies that the app contains com.apple.developer.system-extension.install and the dext contains DriverKit entitlements.

If the embedded entitlement dump is empty, the script fails instead of producing an app that later reports Missing entitlement com.apple.developer.system-extension.install. Use this script for the bundle signing step so the inner and outer signatures stay in sync.

Load a local build

See Installing for the complete procedure and recovery warnings. The short version is:

csrutil disable                    # run from macOS Recovery
systemextensionsctl developer on   # run after SIP is disabled

Move the signed ASFW.app to /Applications, open it, and use Install. Confirm the result with:

systemextensionsctl list

Uninstall the extension before re-enabling SIP. Do not delete files from /Library/SystemExtensions manually.

Running the tests

The C++ suite runs host-side with no hardware or DriverKit:

./build.sh --test-only                        # all C++ tests
./build.sh --test-only --test-filter Pattern  # a subset
./build.sh --swift-test-only                  # Swift/XCTest tests

Clone this wiki locally