# # Makefile # Zyquo Atlas # # Author: Simon-Pierre Boucher # Mail: contact@spboucher.ai # # make / make dev → release build, assemble dist/Zyquo Atlas.app, ad-hoc sign (fast local iteration) # make run → make dev, then launch the app # make release → universal binary, Developer ID sign, notarize, staple (Phase 8) # make icon → regenerate AppIcon.icns from assets/icon/zyquo-atlas.svg (Phase 5) # make verify → Phase 7 API verification with real keys (source .env.keys) # make test → swift test # make clean → remove build products # # CLT-only toolchain: the default SDK (macOS 27 beta) declares @State & co. as # macros whose SwiftUIMacros plugin ships only with Xcode, so every SwiftUI # build fails. SDK 26 keeps the property-wrapper forms — pin all builds to it. export SDKROOT := /Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk APP_NAME := Zyquo Atlas EXEC_NAME := ZyquoAtlas BUNDLE_ID := com.zyquo.atlas VERSION := 1.0.0 BUILD_NUM := 1 MIN_MACOS := 13.0 DIST := dist APP_DIR := $(DIST)/$(APP_NAME).app DMG_PATH := $(DIST)/ZyquoAtlas.dmg IDENTITY := Developer ID Application: Simon-Pierre Boucher (3YM54G49SN) NOTARY_PROFILE:= MacLustr-Notarize ENTITLEMENTS := Resources/ZyquoAtlas.entitlements VERIFY_ARGS ?= .PHONY: dev build bundle release universal dmg icon test clean run verify dev: build bundle @echo "=== Ad-hoc signing (dev) ===" codesign --force --deep --sign - "$(APP_DIR)" codesign --verify --deep --strict "$(APP_DIR)" @echo "Packaged: $(APP_DIR) — launch with: open \"$(APP_DIR)\"" build: swift build -c release test: scripts/test.sh run: dev open "$(APP_DIR)" bundle: @echo "=== Assembling $(APP_DIR) ===" rm -rf "$(APP_DIR)" mkdir -p "$(APP_DIR)/Contents/MacOS" "$(APP_DIR)/Contents/Resources" cp .build/release/$(EXEC_NAME) "$(APP_DIR)/Contents/MacOS/$(EXEC_NAME)" @for b in .build/release/*.bundle; do [ -e "$$b" ] && cp -R "$$b" "$(APP_DIR)/Contents/Resources/" || true; done @if [ -f Resources/AppIcon.icns ]; then cp Resources/AppIcon.icns "$(APP_DIR)/Contents/Resources/AppIcon.icns"; fi @for r in Resources/MenuBarIcon.png Resources/MenuBarIcon@2x.png; do [ -f "$$r" ] && cp "$$r" "$(APP_DIR)/Contents/Resources/" || true; done scripts/write-info-plist.sh "$(APP_DIR)" "$(APP_NAME)" "$(EXEC_NAME)" "$(BUNDLE_ID)" "$(VERSION)" "$(BUILD_NUM)" "$(MIN_MACOS)" # SwiftPM builds a fat binary in one command (arm64 + x86_64); products land in # .build/apple/Products/Release. Verifies the slices with lipo. PRODUCTS := .build/apple/Products/Release universal: @echo "=== Building universal binary (arm64 + x86_64) ===" swift build -c release --arch arm64 --arch x86_64 lipo -archs "$(PRODUCTS)/$(EXEC_NAME)" release: universal @echo "=== Assembling $(APP_DIR) (universal) ===" rm -rf "$(APP_DIR)" mkdir -p "$(APP_DIR)/Contents/MacOS" "$(APP_DIR)/Contents/Resources" cp "$(PRODUCTS)/$(EXEC_NAME)" "$(APP_DIR)/Contents/MacOS/$(EXEC_NAME)" @for b in "$(PRODUCTS)"/*.bundle; do [ -e "$$b" ] && cp -R "$$b" "$(APP_DIR)/Contents/Resources/" || true; done @if [ -f Resources/AppIcon.icns ]; then cp Resources/AppIcon.icns "$(APP_DIR)/Contents/Resources/AppIcon.icns"; fi @for r in Resources/MenuBarIcon.png Resources/MenuBarIcon@2x.png; do [ -f "$$r" ] && cp "$$r" "$(APP_DIR)/Contents/Resources/" || true; done scripts/write-info-plist.sh "$(APP_DIR)" "$(APP_NAME)" "$(EXEC_NAME)" "$(BUNDLE_ID)" "$(VERSION)" "$(BUILD_NUM)" "$(MIN_MACOS)" scripts/notarize.sh "$(APP_DIR)" "$(IDENTITY)" "$(NOTARY_PROFILE)" "$(ENTITLEMENTS)" # Signed + notarized distribution DMG from the notarized app (run `make release` first). dmg: scripts/make-dmg.sh "$(APP_DIR)" "$(IDENTITY)" "$(NOTARY_PROFILE)" "$(DMG_PATH)" icon: scripts/generate-icon.sh # Full API verification with real keys (source .env.keys first, or let make do it). verify: swift build -c release @if [ -f .env.keys ]; then set -a && . ./.env.keys && set +a && .build/release/zyquo-verify $(VERIFY_ARGS); \ else .build/release/zyquo-verify $(VERIFY_ARGS); fi clean: rm -rf .build $(DIST)