Skip to content

Fix the macOS release plugin failing to load - #16

Merged
keithlostracco merged 1 commit into
mainfrom
fix/macos-release-plugin-loading
Sep 8, 2026
Merged

Fix the macOS release plugin failing to load#16
keithlostracco merged 1 commit into
mainfrom
fix/macos-release-plugin-loading

Conversation

@keithlostracco

@keithlostracco keithlostracco commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Summary

The v0.4.0 AsyncioDAT-macos.zip fails in TouchDesigner with "plugin is corrupted". Two build-configuration defects and one distribution limitation, the same class of problem fixed in AnimationCHOP#18:

  1. Minimum macOS 26, arm64 only. Nothing set a deployment target or architectures, so the bundle inherited the macos-26-arm64 runner's. TouchDesigner 2025 itself runs on macOS 13 and later and ships universal.
  2. Incomplete signature. Only the linker's implicit ad-hoc signature on the Mach-O; codesign --verify --deep --strict rejects the bundle ("code has no resources but signature indicates they must be present").
  3. Quarantine. Without notarization, macOS refuses any quarantined copy regardless of the above. The README install steps already cover xattr -dr com.apple.quarantine.

Unlike AnimationCHOP, this plugin already linked no Python library: it uses Python3::Module from Development.Module, which on macOS is -undefined dynamic_lookup. The new verify step still guards that property so it cannot regress.

Changes

  • CMakeLists.txt: CMAKE_OSX_DEPLOYMENT_TARGET 13.3 (the status messages use std::format, which libc++ only provides from 13.3; TouchDesigner's own minimum is 13.0) and CMAKE_OSX_ARCHITECTURES arm64;x86_64, both set before project(). A POST_BUILD ad-hoc codesign of the whole bundle, placed before the copy to tests/td/Plugins so the copy carries the signature. Version bumped to 0.4.1.
  • ci.yml / release.yml: a "Verify macOS plugin" step after Build fails the job if the plugin links any Python library, is not universal, has a minimum OS other than 13.3, or fails codesign --verify --deep --strict.
  • README.md: requirements now say macOS 13.3 or newer, universal (the previous "arm64 only, matching TouchDesigner" was wrong; TouchDesigner is universal). Build notes explain the no-libpython link and the two cache variables.
  • CHANGELOG.md: 0.4.1 entry.

Verification

Fresh build directory, -DASYNCIODAT_BUILD_TESTS=ON, macOS 26.6 / Xcode 26.6 / CMake 4.0.1:

  • lipo -archs: x86_64 arm64; minos 13.3; otool -L shows only libc++ and libSystem; codesign --verify --deep --strict passes on build/bin/AsyncioDAT.plugin and on the copy in tests/td/Plugins.
  • ctest: 16/16 (Catch2 + pytest bindings).
  • ./run_td_tests.sh --no-build in TouchDesigner 2025.33230: 25 passed, 0 failed.
  • Release workflow dry run on this branch (run 34266785473): both platforms green, package-macOS and package-Windows present, release job skipped as designed. The package-macOS bundle downloaded from that run: x86_64 arm64, minos 13.3, no Python link, codesign --verify --deep --strict passes, CFBundleShortVersionString 0.4.1.
  • That same CI-built bundle, copied into tests/td/Plugins with the quarantine attribute cleared, loads in TouchDesigner 2025.33230 and passes the integration suite 25/25.

Reviewer notes

  • Universal vs arm64-only is a product decision. This PR goes universal because TouchDesigner itself is, and Intel Macs on macOS 13+ can run it. To stay arm64-only, set CMAKE_OSX_ARCHITECTURES to arm64 and change the verify step's arch check.
  • Removing the quarantine step entirely needs a Developer ID certificate and notarization in the release workflow; that is separate work.

🤖 Generated with Claude Code

The v0.4.0 AsyncioDAT.plugin was reported by TouchDesigner as corrupted.
The release runner is macOS 26 on Apple silicon, and nothing in the build
pinned a deployment target or an architecture, so the bundle inherited the
runner's macOS 26 as its minimum OS and arm64 as its only architecture,
while TouchDesigner itself runs on macOS 13 and later, universal. The
bundle also carried only the linker's partial ad-hoc signature, which
covers the Mach-O but not the bundle, so codesign rejected it.

The plugin already linked no Python library (Python3::Module resolves the
symbols from the host process), so that part of the AnimationCHOP fix did
not apply here. Deployment target is now 13.3 (std::format needs libc++
from 13.3), architectures are arm64 and x86_64, and the bundle is ad-hoc
signed as a whole post-build, before the copy to tests/td/Plugins so the
copy carries the signature. CI and the release gate now verify all four
properties: no Python link, universal, minos 13.3, valid bundle signature.

Gatekeeper still refuses a quarantined copy without notarization; the
README's install steps already cover clearing the flag. Verified locally
from a fresh build directory: the checklist passes on the bundle and on
its copy, ctest 16/16, and the TouchDesigner integration suite 25/25 in
TouchDesigner 2025.33230.

Bumps the version to 0.4.1 and adds the CHANGELOG entry.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@keithlostracco
keithlostracco merged commit 9466032 into main Sep 8, 2026
5 checks passed
@keithlostracco
keithlostracco deleted the fix/macos-release-plugin-loading branch September 8, 2026 22:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant