-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
134 lines (119 loc) · 5.83 KB
/
Copy pathMakefile
File metadata and controls
134 lines (119 loc) · 5.83 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
PROJECT = Veil.xcodeproj
SCHEME = Veil
# Single-arch destination for fast local builds on Apple Silicon.
# Specifying arch keeps xcodebuild from matching multiple "My Mac" entries.
DEST = platform=macOS,arch=arm64
# Generic destination for universal binary builds (no specific machine).
DEST_UNIVERSAL = generic/platform=macOS
DERIVED = .build
APP = $(DERIVED)/Build/Products/Release/Veil.app
INSTALL_DIR = /Applications
UNIVERSAL = ONLY_ACTIVE_ARCH=NO
NO_PROFILING = CLANG_ENABLE_CODE_COVERAGE=NO CLANG_COVERAGE_MAPPING=NO
# Match CI behavior so locally-built zips have the same linker-applied
# ad-hoc signature as what ships on Releases. Without this, xcodebuild
# falls back to "Sign to Run Locally" and produces a binary with
# hardened runtime and a CFBundleIdentifier-derived code identity,
# which diverges from the released artifact.
NO_SIGNING = CODE_SIGNING_ALLOWED=NO
XCODEBUILD = xcodebuild -project $(PROJECT) -scheme $(SCHEME) -destination '$(DEST)'
XCODEBUILD_UNIVERSAL = xcodebuild -project $(PROJECT) -scheme $(SCHEME) -destination '$(DEST_UNIVERSAL)'
.PHONY: build build-universal cli debug test test-verbose clean install install-polite zip zip-polite release lsp
build:
$(XCODEBUILD) -configuration Release -derivedDataPath $(DERIVED) $(NO_PROFILING) $(NO_SIGNING) -quiet
@echo "Built: $(APP)"
build-universal:
$(XCODEBUILD_UNIVERSAL) -configuration Release -derivedDataPath $(DERIVED) $(UNIVERSAL) $(NO_PROFILING) $(NO_SIGNING) -quiet
@echo "Built (universal): $(APP)"
cli:
swift build --package-path Packages/veil -c release --product veil
@echo "Built: Packages/veil/.build/release/veil"
debug:
$(XCODEBUILD) -configuration Debug -derivedDataPath $(DERIVED) -quiet
# Apple's xcodebuild emits per-test "Test case ... passed/failed" lines but
# no aggregate summary, so we synthesize one. The "no tests ran" branch is
# a sanity check: if xcodebuild changes its prefix again (it has before),
# the count would silently drop to 0 and look like success without it.
# Assertion details aren't in the stdout log; open the .xcresult bundle in
# Xcode or use xcrun xcresulttool to inspect them.
test:
@swift test --package-path Packages/VeilCore --quiet
@out=$(DERIVED)/test.log; mkdir -p $(DERIVED); \
$(XCODEBUILD) -derivedDataPath $(DERIVED) -only-testing:VeilTests $(NO_SIGNING) test -quiet > $$out 2>&1; \
status=$$?; \
passed=$$(grep -cE "^Test case .* passed" $$out || true); \
failed=$$(grep -cE "^Test case .* failed" $$out || true); \
if [ $$failed -gt 0 ]; then \
echo "FAIL: $$failed failed, $$passed passed"; \
grep -E "^Test case .* failed" $$out | sed -E "s/^Test case '([^']+)' failed.*/ ✖ \1/"; \
echo " (full log: $$out)"; \
exit 1; \
elif [ $$status -ne 0 ]; then \
echo "FAIL: build or infrastructure error"; \
grep -E "error: " $$out | head -10; \
echo " (full log: $$out)"; \
exit $$status; \
elif [ $$passed -eq 0 ]; then \
echo "WARN: no tests ran — xcodebuild output format may have changed"; \
echo " (full log: $$out)"; \
exit 1; \
else \
echo "PASS: $$passed tests"; \
fi
test-verbose:
swift test --package-path Packages/VeilCore
$(XCODEBUILD) -derivedDataPath $(DERIVED) -only-testing:VeilTests $(NO_SIGNING) test -quiet
clean:
$(XCODEBUILD) clean -quiet
/System/Library/Frameworks/CoreServices.framework/Versions/Current/Frameworks/LaunchServices.framework/Versions/Current/Support/lsregister -u $(APP) 2>/dev/null || true
rm -rf $(DERIVED) Packages/VeilCore/.build Packages/veil/.build
rm -f Veil.zip Veil-default-editor.zip
install: build
rsync -a "$(APP)/" "$(INSTALL_DIR)/Veil.app/"
@echo "Installed to $(INSTALL_DIR)/Veil.app"
install-polite: build
Tools/make-bundle-polite.sh "$(APP)"
rsync -a "$(APP)/" "$(INSTALL_DIR)/Veil.app/"
@echo "Installed polite variant to $(INSTALL_DIR)/Veil.app"
zip: build-universal
ditto -c -k --keepParent --norsrc --noextattr --noacl "$(APP)" Veil-default-editor.zip
@echo "Packaged: Veil-default-editor.zip"
zip-polite: build-universal
WORK=$$(mktemp -d) && \
ditto "$(APP)" "$$WORK/Veil.app" && \
Tools/make-bundle-polite.sh "$$WORK/Veil.app" && \
ditto -c -k --keepParent --norsrc --noextattr --noacl "$$WORK/Veil.app" Veil.zip && \
rm -rf "$$WORK"
@echo "Packaged: Veil.zip"
lsp:
xcode-build-server config -project $(PROJECT) -scheme $(SCHEME) --build_root $(DERIVED)
# Usage: make release V=0.2 NOTES_FILE=/path/to/notes.md
# Bumps MARKETING_VERSION, commits, and creates an annotated tag in one
# atomic step so the tag commit physically carries the matching pbxproj
# value. Verifies the sed actually landed before committing — if pbxproj's
# format ever changes and the substitution silently no-ops, the build
# would otherwise ship with the old version stamped into Info.plist.
release:
ifndef V
$(error Usage: make release V=x.y NOTES_FILE=/path/to/notes.md)
endif
ifndef NOTES_FILE
$(error Usage: make release V=x.y NOTES_FILE=/path/to/notes.md)
endif
@test -f "$(NOTES_FILE)" || { echo "ERROR: NOTES_FILE not found: $(NOTES_FILE)"; exit 1; }
sed -i '' 's/MARKETING_VERSION = [^;]*/MARKETING_VERSION = $(V)/' $(PROJECT)/project.pbxproj
@total=$$(grep -cE 'MARKETING_VERSION = ' $(PROJECT)/project.pbxproj); \
ok=$$(grep -cE 'MARKETING_VERSION = $(V);' $(PROJECT)/project.pbxproj); \
if [ "$$total" != "$$ok" ] || [ "$$total" -eq 0 ]; then \
echo "ERROR: sed left $$ok of $$total MARKETING_VERSION lines at $(V); reverting pbxproj"; \
git checkout -- $(PROJECT)/project.pbxproj; \
exit 1; \
fi
git add $(PROJECT)/project.pbxproj
git commit -m "Release v$(V)"
# --cleanup=verbatim preserves Markdown section headers like `## Features`
# in the tag annotation. Git's default cleanup mode treats `#` as a comment
# leader and strips those lines, which would silently drop the section
# structure that the GitHub Release body inherits from the tag.
git tag -a v$(V) -F "$(NOTES_FILE)" --cleanup=verbatim
@echo "Tagged v$(V). To publish: git push origin master --tags"