Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
157 lines (134 loc) · 6.54 KB
/
Copy pathMakefile
File metadata and controls
157 lines (134 loc) · 6.54 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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
BOLD := \033[1m
CYAN := \033[36m
RESET := \033[0m
.DEFAULT_GOAL := help
APP_NAME = MacMusicPlayer
BUILD_DIR = build
DMG_VOLUME_NAME = "$(APP_NAME) (Apple Silicon)"
MACOS_MIN = 13.0
ICON_SRC = $(APP_NAME)/Assets.xcassets/AppIcon.appiconset
ICONSET = $(BUILD_DIR)/AppIcon.iconset
BUILT_APP_PATH = $(BUILD_DIR)/$(APP_NAME).app
DMG_PATH = $(BUILD_DIR)/$(APP_NAME)-arm64.dmg
SDK_PATH := $(shell xcrun --show-sdk-path)
SDK_VERSION := $(shell xcrun --show-sdk-version)
SWIFT_BUILD = swift build -c release --triple arm64-apple-macosx$(MACOS_MIN) \
-Xswiftc -Xclang-linker -Xswiftc -isysroot -Xswiftc -Xclang-linker -Xswiftc "$(SDK_PATH)"
USER_APPLICATIONS = $(HOME)/Applications
INSTALL_PATH = $(USER_APPLICATIONS)/$(APP_NAME).app
GIT_COMMIT := $(shell git rev-parse --short HEAD)
# Prefer tagged versions; fall back to the nearest tag or commit hash automatically.
ifndef VERSION
VERSION := $(shell git describe --tags --always)
endif
ifndef MARKETING_SEMVER
MARKETING_SEMVER := $(shell \
VERSION_STR="$(VERSION)"; \
CLEAN=$$(echo $$VERSION_STR | sed -E 's/^v//; s/-.*//'); \
if echo $$CLEAN | grep -Eq '^[0-9]+(\.[0-9]+){0,2}$$'; then \
echo $$CLEAN; \
else \
echo 0.0.0; \
fi)
endif
ifndef BUILD_NUMBER
BUILD_NUMBER := $(shell git rev-list --count HEAD)
endif
INFO_PLIST_KEYS = \
CFBundleExecutable=$(APP_NAME) \
CFBundleName=$(APP_NAME) \
CFBundlePackageType=APPL \
CFBundleInfoDictionaryVersion=6.0 \
CFBundleDevelopmentRegion=en \
LSApplicationCategoryType=public.app-category.music \
NSPrincipalClass=NSApplication \
CFBundleShortVersionString=$(MARKETING_SEMVER) \
CFBundleVersion=$(BUILD_NUMBER) \
GitCommit=$(GIT_COMMIT)
# ── Build ────────────────────────────────────────────────────────────────────
.PHONY: build install-app menubar-guard
menubar-guard: ## Fail if the app could ever show a Dock icon
@if [ "$$(plutil -extract LSUIElement raw $(APP_NAME)/Info.plist)" != "true" ]; then \
echo "❌ $(APP_NAME)/Info.plist must keep LSUIElement=true: the app is menu bar only (see AGENTS.md)."; \
exit 1; \
fi
@if grep -rnE 'setActivationPolicy|TransformProcessType' --include='*.swift' $(APP_NAME); then \
echo "❌ The app must never change its activation policy: it is menu bar only (see AGENTS.md)."; \
exit 1; \
fi
build: menubar-guard ## Build the Release app into build/
@echo "==> Build $(APP_NAME)..."
$(SWIFT_BUILD)
rm -rf "$(BUILT_APP_PATH)" "$(ICONSET)"
mkdir -p "$(BUILT_APP_PATH)/Contents/MacOS" "$(BUILT_APP_PATH)/Contents/Resources" "$(ICONSET)"
cp "$$($(SWIFT_BUILD) --show-bin-path)/$(APP_NAME)" "$(BUILT_APP_PATH)/Contents/MacOS/"
@linked=$$(vtool -show-build "$(BUILT_APP_PATH)/Contents/MacOS/$(APP_NAME)" | awk '$$1 == "sdk" {print $$2}'); \
if [ "$$linked" != "$(SDK_VERSION)" ]; then \
echo "❌ Binary records SDK $$linked, expected $(SDK_VERSION); macOS would run it in legacy appearance mode."; \
exit 1; \
fi
cp $(APP_NAME)/Info.plist "$(BUILT_APP_PATH)/Contents/Info.plist"
sed -i '' 's/\$${PRODUCT_NAME}/$(APP_NAME)/' "$(BUILT_APP_PATH)/Contents/Info.plist"
for kv in $(INFO_PLIST_KEYS); do plutil -replace "$${kv%%=*}" -string "$${kv#*=}" "$(BUILT_APP_PATH)/Contents/Info.plist"; done
for f in $(ICON_SRC)/icon_*_1x.png; do \
name=$$(basename "$$f" _1x.png); \
cp "$$f" "$(ICONSET)/$$name.png"; \
cp "$${f%_1x.png}_2x.png" "$(ICONSET)/$$name@2x.png"; \
done
iconutil -c icns "$(ICONSET)" -o "$(BUILT_APP_PATH)/Contents/Resources/AppIcon.icns"
cp -R $(APP_NAME)/Resources/Localization/*.lproj "$(BUILT_APP_PATH)/Contents/Resources/"
codesign --force --sign - "$(BUILT_APP_PATH)"
@echo "✅ Build completed!"
@echo "📍 Application location: $(BUILT_APP_PATH)"
install-app: ## Quit, rebuild, install to ~/Applications, and launch
@echo "⏹️ Force quitting any running $(APP_NAME) instances..."
@if pgrep -x "$(APP_NAME)" >/dev/null 2>&1; then \
pkill -KILL -x "$(APP_NAME)" >/dev/null 2>&1; \
echo "✅ $(APP_NAME) has been force quit."; \
else \
echo "ℹ️ $(APP_NAME) is not currently running."; \
fi
@$(MAKE) --no-print-directory build
@echo "📦 Install $(APP_NAME) to ~/Applications..."
@if [ -d "$(INSTALL_PATH)" ]; then \
echo "⚠️ Found installed version, deleting..."; \
rm -rf "$(INSTALL_PATH)"; \
fi
@if [ -d "$(BUILT_APP_PATH)" ]; then \
cp -R "$(BUILT_APP_PATH)" "$(USER_APPLICATIONS)/"; \
echo "✅ $(APP_NAME) has been successfully installed to ~/Applications!"; \
echo "🚀 Launching $(APP_NAME)..."; \
open "$(INSTALL_PATH)"; \
echo "✅ $(APP_NAME) launched."; \
else \
echo "❌ Error: Unable to find the built application file $(BUILT_APP_PATH)"; \
echo "💡 Please rerun 'make install-app' to rebuild and install"; \
exit 1; \
fi
# ── Release ──────────────────────────────────────────────────────────────────
.PHONY: dmg version
dmg: build ## Build and package a self-signed arm64 DMG
rm -rf $(BUILD_DIR)/dmg
mkdir -p $(BUILD_DIR)/dmg
cp -R "$(BUILT_APP_PATH)" $(BUILD_DIR)/dmg/
ln -s /Applications $(BUILD_DIR)/dmg/Applications
hdiutil create -volname $(DMG_VOLUME_NAME) -srcfolder $(BUILD_DIR)/dmg -ov -format UDZO "$(DMG_PATH)"
rm -rf $(BUILD_DIR)/dmg
@echo "==> DMG created: $(DMG_PATH)"
@echo "Note: This DMG is self-signed; users may need to approve it in System Settings."
version: ## Print version info (override VERSION, MARKETING_SEMVER, BUILD_NUMBER)
@echo "Version: $(VERSION)"
@echo "Git Commit: $(GIT_COMMIT)"
@echo "Marketing: $(MARKETING_SEMVER)"
@echo "Build Number: $(BUILD_NUMBER)"
# ── Maintenance ──────────────────────────────────────────────────────────────
.PHONY: clean
clean: ## Remove build artifacts
rm -rf $(BUILD_DIR) .build
# ── Help ─────────────────────────────────────────────────────────────────────
.PHONY: help
help: ## Show available targets
@awk 'BEGIN {FS = ":.*## "; printf "\n$(BOLD)MacMusicPlayer$(RESET) — menu bar music player for macOS\n"} \
/^# ── / {n = $$0; gsub(/(^# ── | (─)+$$)/, "", n); printf "\n$(BOLD)%s$(RESET)\n", n} \
/^[a-zA-Z_-]+:.*## / {printf " $(CYAN)make %-16s$(RESET) %s\n", $$1, $$2} \
END {printf "\n"}' $(MAKEFILE_LIST)