Skip to content

build(macos): generate AetherSDR.icns at build time via CMake#2558

Merged
ten9876 merged 1 commit into
mainfrom
worktree-macos-icon-fix
May 10, 2026
Merged

build(macos): generate AetherSDR.icns at build time via CMake#2558
ten9876 merged 1 commit into
mainfrom
worktree-macos-icon-fix

Conversation

@jensenpat

Copy link
Copy Markdown
Collaborator

Summary

Local cmake builds on macOS were producing an .app bundle with no icon. The .icns was generated only by the macos-dmg.yml CI workflow and never committed, so the if(EXISTS docs/AetherSDR.icns) guard in CMakeLists silently skipped the missing file on every developer's machine.

This PR moves the sips + iconutil generation into CMake itself via add_custom_command, sourced from docs/logo-circle.png. macOS ships both tools by default, so there's no new build dependency. The redundant manual step in macos-dmg.yml is dropped, and create-dmg --volicon now points at the CMake-produced build/AetherSDR.icns.

Local and CI builds now go through the same code path.

Changes

  • CMakeLists.txt — replace the if(EXISTS .icns) guard with an add_custom_command that produces build/AetherSDR.icns from docs/logo-circle.png at build time. CMake bundles it into Contents/Resources/ via MACOSX_PACKAGE_LOCATION.
  • .github/workflows/macos-dmg.yml — remove the manual Generate .icns from PNG step (now redundant); update --volicon to reference build/AetherSDR.icns.

Verified

  • cmake -B build && cmake --build build -j10 on macOS arm64 produces:
    • build/AetherSDR.app/Contents/Resources/AetherSDR.icns (634 KB)
    • Info.plist CFBundleIconFileAetherSDR.icns
  • App launches and shows the correct icon in the Dock.

Test plan

  • CI macOS DMG workflow produces a signed/notarized DMG with both the app icon and DMG volume icon intact
  • Local cmake --build build on macOS produces an .app with the icon visible in Finder/Dock

🤖 Generated with Claude Code

Local cmake builds produced an .app bundle with no icon because the
.icns was generated only by the macos-dmg CI workflow and never
committed. The CMakeLists guard `if(EXISTS docs/AetherSDR.icns)`
silently skipped the missing file, leaving the bundle iconless on
every developer's machine.

Move the sips/iconutil generation into CMake itself via
add_custom_command, sourced from docs/logo-circle.png. macOS ships
both tools, so no new build dependency is required. Drop the now-
redundant manual step in macos-dmg.yml and point create-dmg's
--volicon at the CMake-produced build/AetherSDR.icns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jensenpat jensenpat marked this pull request as ready for review May 10, 2026 18:18
@jensenpat jensenpat requested a review from ten9876 as a code owner May 10, 2026 18:18

@ten9876 ten9876 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude here, reviewing on Jeremy's behalf.

Verdict

Solid fix for a real problem. Recommending merge.

Verified

  • The bug is real. docs/AetherSDR.icns is not committed to the repo — the .icns only ever existed inside the macos-dmg CI runner. Every local macOS dev build hit the if(EXISTS "${MACOSX_ICON}") guard, skipped the icon, and produced a generic-icon .app. Confirmed by grepping the tree.
  • The fix is wired correctly. add_custom_command(OUTPUT ICNS_PATH …) + target_sources(AetherSDR PRIVATE ICNS_PATH) + MACOSX_PACKAGE_LOCATION "Resources" is the textbook CMake pattern for generating a bundle resource at build time. CMake derives the dependency from OUTPUT → DEPENDS and only re-runs when docs/logo-circle.png changes.
  • Info.plist binding still works. MACOSX_BUNDLE_ICON_FILE "AetherSDR.icns" is already set at CMakeLists.txt:746, and packaging/macos/Info.plist.in consumes it via ${MACOSX_BUNDLE_ICON_FILE}. The new code lands the file at Contents/Resources/AetherSDR.icns with the same basename, so the existing plist reference resolves cleanly.
  • No new build dependencies. sips and iconutil are stock macOS tools shipped with every Xcode-equipped dev box.
  • Cross-platform safety. Entire block is inside if(APPLE) — can't affect Linux or Windows builds.
  • CI is fully greenbuild, analyze (cpp), check-paths, check-windows, CodeQL all SUCCESS.

Minor notes (non-blocking)

  • The add_custom_command writes to build/AetherSDR.iconset/ and never cleans up. Harmless (it's inside the build dir, gets nuked with rm -rf build), but if you wanted to be tidy a final ${CMAKE_COMMAND} -E rm -rf "${ICONSET_PATH}" step would do it. Not worth blocking on.
  • If a downstream contributor ever wants to rebuild on a non-macOS host that's hand-crafting a .app (e.g. for cross-build), the sips/iconutil calls would fail. That's not a real workflow we support — flagging only because the previous "skip if missing" guard tolerated it; the new version doesn't. The behavior change is a net win because silent fallback to no-icon was the original bug.

Thanks

Thanks to @jensenpat for the careful diagnosis and tight, minimal fix — exactly the right shape (single-purpose, deletes more than it adds, unifies CI and local paths). Appreciated.

73, Jeremy KK7GWY & Claude (AI dev partner)

@ten9876 ten9876 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — merging.

@ten9876 ten9876 merged commit af34a42 into main May 10, 2026
5 checks passed
@ten9876 ten9876 deleted the worktree-macos-icon-fix branch May 10, 2026 18:56
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.

2 participants