Files
OrcaSlicer-KX/BUILD_MAC_KX.md
Walter Almada B 6cc082f02e fix(macos): stable local codesign to stop repeated permission prompts
Local arm64 builds are only ad-hoc/linker-signed, so macOS identifies the
app by its cdhash. That hash changes on every rebuild, invalidating TCC
(folder access) grants and Keychain ACLs, so macOS re-prompts for folder
access and the keychain password on every launch/redeploy.

Add scripts/macos_codesign_local.sh: creates a stable, machine-local,
self-signed code-signing identity in the user's login keychain (idempotent,
no admin password) and re-signs the app top-level. The Designated Requirement
becomes certificate-based ("... and certificate leaf = H\"...\"") instead of
cdhash, so it is identical across rebuilds and permissions granted once
persist. Document the workflow in BUILD_MAC_KX.md.

The certificate/private key are per-machine and never leave the login
keychain; only the script is shared.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 10:05:49 -07:00

6.7 KiB

BUILD_MAC_KX.md — building OrcaSlicer-KX on macOS (Apple Silicon)

macOS build guide for this fork. Upstream (viewit) ships only Linux & Windows binaries; this fork exists to add the macOS build (see Releases for the .app). The upstream CLAUDE.md/AGENTS.md are left untouched.

Verified recipe: run as-is on 2026-07-02 on a Mac M2 (arm64, macOS 25.x). It produced a working .app that launches. Timings below are real, measured.


What this is

Fork of OrcaSlicer-KX (https://gitea.it-drui.de/viewit/OrcaSlicer-KX), itself a fork of SoftFever/OrcaSlicer with patches for the Anycubic Kobra X. Current checkout: tag v2.4.1-kx1.

The fork's changes vs upstream are branding (logo/icon/splash/about), redirecting the updater to Gitea, and bugfix backports. They do not touch anything platform-specific (no CMake, no build scripts, no src/platform, no *.mm, no Info.plist). The macOS icon (resources/Icon.icns, resources/images/OrcaSlicer.icns) already ships regenerated with KX branding. So building on Mac is not a port, it's a recompile using upstream's own build_release_macos.sh.

Upstream only publishes Linux (AppImage) and Windows (zip) — there is no official .dmg. This clone is for producing the Mac build yourself.


Requirements (one time)

  • Xcode Command Line Tools (NOT full Xcode.app — see the -x note). Check: xcode-select -p prints a path.
  • Homebrew with:
brew install cmake ninja automake texinfo libtool pkg-config

(automake texinfo libtool are needed by the deps stage; cmake+ninja by the build.)

Why -x (Ninja) and not the default

build_release_macos.sh defaults to the Xcode CMake generator, which requires full Xcode.app (~15 GB from the App Store). The -x flag switches to Ninja, which works with just the Command Line Tools. Always use it here.


Build (arm64 / Apple Silicon)

Two stages, run from the repo root (~/Developer/OrcaSlicer-KX):

# Stage 1 — dependencies (Boost, wxWidgets, TBB, OCCT, OpenCV, ...)
#           202 static libs → deps/build/arm64/OrcaSlicer_dep
./build_release_macos.sh -d -x -a arm64      # measured: ~14.5 min

# Stage 2 — the slicer itself → build/arm64/OrcaSlicer/OrcaSlicer.app
./build_release_macos.sh -s -x -a arm64      # measured: ~18 min

Flags: -d deps only · -s slicer only · -x Ninja · -a arch. On an M2 with 16 GB, -1 (single job) is not needed; if a Mac with less RAM OOMs while linking, add -1.

Output: build/arm64/OrcaSlicer/OrcaSlicer.app (native arm64, ~367 MB, version 2.4.1-kx1).

Normal output that is NOT an error

  • "CMake Deprecation" warnings and Performing Test ... - Failed lines in the deps stage are compiler feature detection, not failures. The build still finishes with exit 0 and [202/202] Completed.
  • The signature is ad-hoc / linker-signed. Strict codesign -v and spctl complain ("code has no resources but signature indicates they must be present"). This is harmless for launching: a local build is not quarantined, so it opens with a double-click, no Gatekeeper block. It does, however, make macOS re-ask for folder and keychain permissions on every rebuild — see Stop the repeated folder / keychain permission prompts below to fix that.

Install into /Applications

There is usually an official /Applications/OrcaSlicer.app. To avoid overwriting it, copy under a different name:

ditto build/arm64/OrcaSlicer/OrcaSlicer.app /Applications/OrcaSlicer-KX.app
./scripts/macos_codesign_local.sh             # stable local signature — stops repeated permission prompts (see below)
open /Applications/OrcaSlicer-KX.app          # verify it boots

(ditto preserves the bundle + signature better than cp -R.)


Because a local build is only ad-hoc / linker-signed, macOS identifies the app by its content hash (cdhash). That hash changes on every rebuild, so macOS treats each build as a brand-new app and re-asks for folder access (TCC) and the keychain password every time — the grants never stick.

Fix it by signing the app with a stable, machine-local, self-signed identity, so its Designated Requirement becomes certificate-based (identical across rebuilds):

./scripts/macos_codesign_local.sh          # run AFTER copying the app to /Applications

On first run the script creates the identity OrcaSlicer Local Codesign in your login keychain (no admin password needed) and re-signs the installed app + local build output. Re-run it after every build/redeploy — it reuses the same identity. The Designated Requirement changes from cdhash H"…" to identifier "com.orcaslicer.OrcaSlicer" and certificate leaf = H"…", which is stable.

On the next launch only, allow the folder prompts and click "Always Allow" on the keychain prompt once; macOS then remembers them across future rebuilds.

Per-machine — share the script, never the cert. The certificate and its private key are generated locally and live only in your login keychain; they are never written to the repo. Each developer runs the script once on their own Mac to create their own local identity. Commit and share the script, not the certificate.


Update to a new tag (e.g. kx2)

git fetch --tags
git checkout <new-tag>
./build_release_macos.sh -s -x -a arm64       # deps are cached ⇒ only the slicer recompiles (~18 min)

If the new tag changes a dependency, run the -d stage again first.


Publishing the macOS release

The distributable is a zip of the .app (matching how upstream ships Windows):

ditto -c -k --keepParent build/arm64/OrcaSlicer/OrcaSlicer.app \
  OrcaSlicer-KX-v2.4.1-kx1-macOS-arm64.zip

Attach it to a Gitea Release on this fork. Gotcha: a freshly created Gitea fork may have the Releases unit disabled (has_releases:false), which makes asset downloads return 404 even though the upload succeeded. Enable it once: PATCH /api/v1/repos/<owner>/<repo> with {"has_releases": true}.


Gotchas

  • Updater points to Gitea, not upstream — commit 7ed0173 hardcodes https://gitea.it-drui.de/api/v1/repos/viewit/OrcaSlicer-KX/releases/latest. There is no macOS artifact there, so "check for updates" won't find a macOS build. Harmless; updating = recompiling (above).
  • Universal / Intel: -a x86_64 (Intel), -a universal (fat binary; requires prior arm64 and x86_64 builds). On Apple Silicon, arm64 is the right choice.
  • Not notarized — distributing to third parties would need an Apple Developer account ($99/yr) + notarization. Not needed for local use.