Skip to content

fix(mac): compile each icon asset catalog only once for universal builds#1922

Open
claude[bot] wants to merge 1 commit into
mainfrom
fix/actool-reuse-asset-catalog-universal
Open

fix(mac): compile each icon asset catalog only once for universal builds#1922
claude[bot] wants to merge 1 commit into
mainfrom
fix/actool-reuse-asset-catalog-universal

Conversation

@claude

@claude claude Bot commented Jun 25, 2026

Copy link
Copy Markdown

Requested by Samuel Attard · Slack thread

Before

When packaging a universal macOS app whose icon is a macOS 26 Icon Composer .icon asset, packager builds the x64 and arm64 slices separately and runs actool once per slice to compile Assets.car. actool does not produce a byte-identical Assets.car across invocations, so the two slices ended up with differing Assets.car files and the @electron/universal stitching step failed (the files are neither identical nor mergeable as Mach-O).

After

actool is invoked exactly once per .icon and both architecture slices reuse the identical compiled buffer, so the universal stitch sees byte-identical Assets.car files and succeeds. macOS 26 .icon universal builds now package successfully.

How

generateAssetCatalogForIcon in src/icon-composer.ts now memoizes the compiled asset catalog in a module-level Map keyed by the resolved input .icon path. The actual compilation moved into a private compileAssetCatalogForIcon helper. Because a universal build compiles both arch slices within the same Node process (see the Promise.all over ['x64', 'arm64'] in src/universal.ts), the cache guarantees actool runs once and both slices reuse the result. Failed compilations are evicted from the cache so a transient actool error can be retried. A unit test in test/icon-composer.spec.ts mocks actool and asserts the catalog is compiled only once per unique icon (including across relative/absolute path forms) and recompiled for a distinct icon.

This is the root-cause fix preferred over adding a nonBinaryFilesToIgnore escape hatch to @electron/universal (see the review on electron/universal#208). It mirrors the approach in electron-userland/electron-builder#9279, which compiled the asset catalog once and reused it across architectures. Related: #1843.

Fixes #1843

🤖 Generated with Claude Code

https://claude.ai/code/session_015bvEKdt4wjCAjmWj4rQpfB


Generated by Claude Code

`actool` is not guaranteed to produce a byte-identical `Assets.car` across
invocations. Universal builds compile the x64 and arm64 slices in the same
process, each invoking `actool` independently, so their `Assets.car` files
could differ and fail the `@electron/universal` stitch.

Memoize the compiled asset catalog by the resolved `.icon` input path so
`actool` runs exactly once per icon and both arch slices reuse the identical
buffer. Failures are not cached so a transient `actool` error can be retried.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015bvEKdt4wjCAjmWj4rQpfB
@MarshallOfSound MarshallOfSound marked this pull request as ready for review June 25, 2026 14:07
@MarshallOfSound MarshallOfSound requested a review from a team as a code owner June 25, 2026 14:07
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.

macOS universal build fails when using Icon Composer icon

2 participants