Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
125 lines (109 loc) · 5.03 KB
/
Copy pathMakefile
File metadata and controls
125 lines (109 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# MadReader — build helpers (works with Command Line Tools, no Xcode needed)
APP := MadReader
CONFIG ?= Debug
BUILDDIR ?= build
APPBUNDLE := $(BUILDDIR)/$(APP).app
DMG := $(BUILDDIR)/MadReader.dmg
# Source layout
SRC := MadReader
RESOURCES := $(SRC)/Resources
ASSETS := $(SRC)/Assets.xcassets
# Toolchain
SDK := $(shell xcrun --sdk macosx --show-sdk-path)
SWIFTC := swiftc
# CLT's macOS 26+ SDK implements SwiftUI property wrappers as macros, but CLT
# doesn't ship the SwiftUIMacros plugin (full Xcode does) → build fails with
# "plugin for module 'SwiftUIMacros' not found". The 15.2 SDK still has plain
# property wrappers, so prefer it when present.
LEGACY_SDK := /Library/Developer/CommandLineTools/SDKs/MacOSX15.2.sdk
ifneq ($(wildcard $(LEGACY_SDK)),)
SDK := $(LEGACY_SDK)
endif
# All Swift sources
SWIFTSRC := $(shell find $(SRC) -name '*.swift')
# Signed installers (fill in your own identity names; see APP_STORE_CN.md)
DIST_SIGN ?= Apple Distribution
INST_SIGN ?= 3rd Party Mac Developer Installer
PROFILE ?= MadReader.provisionprofile
ENTITLEMENTS := MadReader.entitlements
MASPKG := $(BUILDDIR)/MadReader-mas.pkg
.PHONY: all gen build run dmg mas clean resources help probe
all: gen build
# Generate the Xcode project (for editing in Xcode; not required to build here)
gen:
@if command -v xcodegen >/dev/null 2>&1; then xcodegen generate; \
else echo "xcodegen not installed — skipping (not required for direct build)"; fi
# Probe: list framework availability (diagnostic)
probe:
@echo "SDK: $(SDK)"; \
ls "$(SDK)/System/Library/Frameworks/SwiftUI.framework" >/dev/null 2>&1 && echo "SwiftUI: YES" || echo "SwiftUI: NO"
# Compile the Swift sources and assemble a .app bundle directly via swiftc.
build: resources
@mkdir -p $(BUILDDIR)
@echo "==> Compiling $(words $(SWIFTSRC)) Swift files ($(CONFIG))…"
@OPT=$$(if [ "$(CONFIG)" = "Release" ]; then echo "-O"; else echo "-Onone"; fi); \
$(SWIFTC) \
-target arm64-apple-macos14 \
-sdk "$(SDK)" \
-parse-as-library \
-module-name $(APP) \
$$OPT \
$(SWIFTSRC) \
-o $(BUILDDIR)/$(APP) \
-framework SwiftUI -framework WebKit -framework AppKit \
-Xlinker -rpath -Xlinker @executable_path/../Frameworks
@echo "==> Assembling $(APPBUNDLE)"
@mkdir -p "$(APPBUNDLE)/Contents/MacOS" "$(APPBUNDLE)/Contents/Resources"
@cp $(BUILDDIR)/$(APP) "$(APPBUNDLE)/Contents/MacOS/$(APP)"
@# Resolve Xcode build-variable placeholders in Info.plist (we bypass xcodebuild).
@sed -e 's/$$(EXECUTABLE_NAME)/$(APP)/g' \
-e 's/$$(PRODUCT_BUNDLE_IDENTIFIER)/com.madreader.app/g' \
-e 's/$$(CURRENT_PROJECT_VERSION)/1/g' \
-e 's/$$(MARKETING_VERSION)/1.0.0/g' \
-e 's/$$(MACOSX_DEPLOYMENT_TARGET)/14.0/g' \
"$(SRC)/Info.plist" > "$(APPBUNDLE)/Contents/Info.plist"
@# Copy JS/CSS resources into the bundle
@cp $(RESOURCES)/js/*.js "$(APPBUNDLE)/Contents/Resources/" 2>/dev/null || true
@cp $(RESOURCES)/css/*.css "$(APPBUNDLE)/Contents/Resources/" 2>/dev/null || true
@echo "Built: $(APPBUNDLE)"
# Compile assets to .car (best-effort; needs full Xcode's actool — skip if unavailable).
resources:
@if actool --version >/dev/null 2>&1; then \
mkdir -p $(BUILDDIR)/assets; \
actool --output-format human-readable-text --notices --warnings \
--platform macosx --target-device mac \
--minimum-deployment-target 14.0 \
--output-partial-info-plist $(BUILDDIR)/assets.plist \
--compile $(BUILDDIR)/assets "$(ASSETS)" || \
echo "(actool failed — skipping Assets.car; app still runs)"; \
else echo "(actool unavailable — skipping Assets.car; app still runs)"; fi
# Open the built app
run: build
@open "$(APPBUNDLE)"
# Package a distributable .dmg
dmg: build
@rm -f $(DMG)
@hdiutil create -volname "$(APP)" -srcfolder "$(APPBUNDLE)" -ov -format UDZO $(DMG) 2>/dev/null
@echo "Built: $(DMG)"
# Sign + package for Mac App Store. Prerequisites (see APP_STORE_CN.md):
# - Apple Distribution & 3rd Party Mac Developer Installer certificates in keychain
# - $(PROFILE) downloaded from the developer portal (Mac App Store profile)
# make mas DIST_SIGN="Apple Distribution: YOUR NAME (TEAMID)" \
# INST_SIGN="3rd Party Mac Developer Installer: YOUR NAME (TEAMID)"
mas: build
@test -f "$(PROFILE)" || { echo "Missing $(PROFILE) — download the Mac App Store provisioning profile first."; exit 1; }
@cp "$(PROFILE)" "$(APPBUNDLE)/Contents/embedded.provisionprofile"
codesign -f -s "$(DIST_SIGN)" --entitlements "$(ENTITLEMENTS)" --timestamp "$(APPBUNDLE)"
codesign --verify --verbose=2 "$(APPBUNDLE)"
productbuild --component "$(APPBUNDLE)" /Applications \
--sign "$(INST_SIGN)" "$(MASPKG)"
@echo "Built: $(MASPKG) — upload via Transporter."
clean:
@rm -rf $(BUILDDIR) $(APP).xcodeproj *.xcworkspace
@echo "cleaned"
help:
@echo "Targets: gen | build | run | dmg | mas | clean | probe"
@echo " build — compile via swiftc into $(APPBUNDLE) (no Xcode required)"
@echo " run — build + open"
@echo " dmg — build + package .dmg (direct distribution)"
@echo " mas — build + sign + package .pkg for Mac App Store (see APP_STORE_CN.md)"