forked from mapbox/mapbox-maps-ios
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
295 lines (252 loc) · 9.52 KB
/
Makefile
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# ----------------------------------------------------------------------------------------------------------------------
# Configurable varibles
ifneq ($(XCODE_WORKSPACE),)
XCODE_PROJECT := -workspace $(XCODE_WORKSPACE)
else
XCODE_PROJECT ?= -project MapboxMaps.xcodeproj
endif
XCODE_PROJECT_FILE := MapboxMaps.xcodeproj/project.pbxproj
# Default to Debug since Release will require testability. (See #157)
CONFIGURATION ?= Debug
BUILD_DIR ?= $(CURDIR)/build
JOBS ?= $(shell sysctl -n hw.ncpu)
APP_NAME ?= $(SCHEME)
# Circle
CIRCLE_CI_CLI ?= /tmp/circleci
# Derived variables
BUILT_DEVICE_PRODUCTS_DIR := $(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos
TEST_ROOT := $(BUILD_DIR)/test-root
PAYLOAD_DIR := $(BUILD_DIR)/Payload
# Netrc
NETRC_FILE=~/.netrc
# See https://stackoverflow.com/a/7377522
define NETRC
machine api.mapbox.com
login mapbox
password $(SDK_REGISTRY_TOKEN)
endef
export NETRC
# Disabled optional code signing for the time-being. Currently with the setup below,
# when build-for-testing unit tests on device **locally** (i.e. you need code-signing),
# the build can fail with
#
# error: Cycle inside MapboxMapsTests; building could produce unreliable results.
#
# This can be fixed by adding MapboxMapTestHost as a dependency to the Test targets,
# but this isn't the appropriate a solution here (these originate as simulator unit
# tests).
#
# The probable solution is to keep code signing disabled (during build), but then
# re-sign prior to running with the xctestrun file. The app, xctest, dylibs and
# frameworks need to be recursively signed. Something along the lines of:
#
# find build -name \*.framework -print0 | xargs -0 -I{} codesign --force --sign <identity> --preserve-metadata=identifier,entitlements,flags --timestamp=none {}
ENABLE_CODE_SIGNING ?= 0
# Disable code signing by default
ifeq (1,$(ENABLE_CODE_SIGNING))
CODE_SIGNING :=
else
CODE_SIGNING := CODE_SIGN_IDENTITY="" \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGNING_ALLOWED=NO
endif
# ----------------------------------------------------------------------------------------------------------------------
# House keeping
.PHONY: clean
clean:
-rm -rf $(BUILD_DIR)
.PHONY: distclean
distclean: clean
-rm Package.resolved
-rm Apps/Apps.xcworkspace/xcshareddata/swiftpm/Package.resolved
-rm MapboxMaps.xcodeproj
$(PAYLOAD_DIR) $(TEST_ROOT):
-mkdir -p $@
# ----------------------------------------------------------------------------------------------------------------------
# Simulators - SDK
XCODE_BUILD_SIM_SDK = set -o pipefail && xcodebuild \
-scheme MapboxMaps \
-sdk iphonesimulator \
-configuration $(CONFIGURATION) \
-jobs $(JOBS)
.PHONY: build-sdk-for-simulator
build-sdk-for-simulator:
$(XCODE_BUILD_SIM_SDK) \
-destination 'platform=iOS Simulator,OS=latest,name=iPhone 11' \
build \
ONLY_ACTIVE_ARCH=NO
.PHONY: build-sdk-for-testing-simulator
build-sdk-for-testing-simulator:
$(XCODE_BUILD_SIM_SDK) \
-destination 'platform=iOS Simulator,OS=latest,name=iPhone 11' \
-enableCodeCoverage YES \
build-for-testing \
ENABLE_TESTABILITY=YES \
ONLY_ACTIVE_ARCH=YES
.PHONY: test-sdk-without-building-simulator
test-sdk-without-building-simulator:
$(XCODE_BUILD_SIM_SDK) \
-destination 'platform=iOS Simulator,OS=latest,name=iPhone 11' \
-enableCodeCoverage YES \
test-without-building \
-resultBundlePath MapboxMapsTests.xcresult \
ONLY_ACTIVE_ARCH=YES
# ----------------------------------------------------------------------------------------------------------------------
# Simulators - Apps
.PHONY: build-app-for-simulator
build-app-for-simulator:
set -o pipefail && xcodebuild \
-workspace Apps/Apps.xcworkspace \
-scheme '$(SCHEME)' \
-sdk iphonesimulator \
-destination 'platform=iOS Simulator,OS=latest,name=iPhone 11' \
-configuration $(CONFIGURATION) \
-jobs $(JOBS) \
build \
ONLY_ACTIVE_ARCH=NO
# ----------------------------------------------------------------------------------------------------------------------
# Devices - SDK
# Xcode build command for building for device. The CODE_SIGNING_* variables are so that no code signing occurs on CI -
# this is because AWS Device Farm re-signs the applications. This may need to change if a different provider is used.
XCODE_BUILD_DEVICE = xcodebuild \
$(XCODE_PROJECT) \
-sdk iphoneos \
-configuration $(CONFIGURATION) \
-derivedDataPath $(BUILD_DIR) \
-jobs $(JOBS) \
$(CODE_SIGNING)
.PHONY: build-sdk-for-device
build-sdk-for-device:
set -o pipefail && xcodebuild \
-scheme MapboxMaps \
-sdk iphoneos \
-destination 'generic/platform=iOS' \
-configuration $(CONFIGURATION) \
-jobs $(JOBS) \
build \
ONLY_ACTIVE_ARCH=NO \
$(CODE_SIGNING)
$(XCODE_PROJECT_FILE): project.yml
xcodegen
# ----------------------------------------------------------------------------------------------------------------------
# Devices - Apps
XCODE_BUILD_DEVICE_APPS = xcodebuild \
ONLY_ACTIVE_ARCH=NO \
-workspace Apps/Apps.xcworkspace \
-sdk iphoneos \
-configuration $(CONFIGURATION) \
-jobs $(JOBS) \
$(CODE_SIGNING)
.PHONY: build-app-for-device
build-app-for-device:
set -o pipefail && $(XCODE_BUILD_DEVICE_APPS) -scheme '$(SCHEME)' build
# ----------------------------------------------------------------------------------------------------------------------
# Symbolication
.PHONY: symbolicate
symbolicate:
@echo Symbolicating crash reports
@export DEVELOPER_DIR=$$(xcode-select -p); \
CRASHES=`find $(BUILD_DIR) -name *.ips` ; \
echo "crashes: $${CRASHES}"; \
for CRASH in $${CRASHES[@]} ; \
do \
if [ ! -f $${CRASH}.symbolicated.txt ]; then \
echo "Symbolicating $${CRASH}" ; \
$${DEVELOPER_DIR}/Platforms/MacOSX.platform/Developer/iOSSupport/Library/PrivateFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash \
$${CRASH} \
$(BUILT_DEVICE_PRODUCTS_DIR)/$(APP_NAME).app/ \
$(BUILT_DEVICE_PRODUCTS_DIR)/$(APP_NAME).app/Frameworks/ \
$(BUILT_DEVICE_PRODUCTS_DIR)/$(APP_NAME).app/Plugins/ \
-o $${CRASH}.symbolicated.txt ; \
cat $${CRASH}.symbolicated.txt ; \
fi ; \
done
# Codecov.io appears to struggle with the raw coverage data from Xcode (in this Device Farm testing scenario).
# Explicitly converting it to an lcov format helps.
#
# However, the following conversion of the profdata has failed once. If this continues to be an
# issue, it will be worth trying the following first:
#
# xcrun llvm-profdata merge -o dest.profdata source.profraw
#
# Root directory in which to search for "profdata" coverage files, from which we generate
# the lcov data (both lcov and json formats)
COVERAGE_ROOT_DIR ?= $(BUILD_DIR)/Build/ProfileData
COVERAGE_MAPBOX_MAPS ?= $(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphonesimulator/MapboxMaps.o
COVERAGE_ARCH ?= x86_64
# .PHONY: update-codecov-with-profdata
# update-codecov-with-profdata:
# curl -sSfL --retry 5 --connect-timeout 5 https://codecov.io/bash > /tmp/codecov.sh
# @PROF_DATA=`find $(COVERAGE_ROOT_DIR) -regex '.*\.profraw'` ; \
# for RESULT in $${PROF_DATA[@]} ; \
# do \
# echo "Generating $${RESULT}.lcov" ; \
# xcrun llvm-profdata merge -o $${RESULT}.profdata $${RESULT} ; \
# xcrun llvm-cov export \
# $(COVERAGE_MAPBOX_MAPS) \
# -instr-profile=$${RESULT}.profdata \
# -arch=$(COVERAGE_ARCH) \
# -format=lcov > $${RESULT}.lcov ; \
# echo "Uploading $${RESULT}.lcov to CodeCov.io" ; \
# bash /tmp/codecov.sh \
# -f $${RESULT}.lcov \
# -t $(CODECOV_TOKEN) \
# -J '^MapboxMaps$$' \
# -n $${RESULT}.lcov \
# -F "$$(echo '$(SCHEME)' | sed 's/[[:upper:]]/_&/g;s/^_//' | tr '[:upper:]' '[:lower:]')" ; \
# echo "Generating lcov JSON" ; \
# xcrun llvm-cov export \
# $(COVERAGE_MAPBOX_MAPS) \
# -instr-profile=$${RESULT}.profdata \
# -arch=$(COVERAGE_ARCH) \
# -format=text | python3 -m json.tool > $${RESULT}.json ; \
# echo "Uploading to S3" ; \
# python3 ./scripts/code-coverage/parse-code-coverage.py \
# -g . \
# -c MapboxMaps \
# --scheme $(SCHEME) \
# --report $${RESULT}.json ; \
# done
# @echo "Done"
.PHONY: update-codecov-with-profdata
update-codecov-with-profdata:
@PROF_DATA=`find $(COVERAGE_ROOT_DIR) -regex '.*\.profdata'` ; \
for RESULT in $${PROF_DATA[@]} ; \
do \
echo "Generating lcov JSON" ; \
xcrun llvm-cov export \
$(COVERAGE_MAPBOX_MAPS) \
-instr-profile=$${RESULT} \
-arch=$(COVERAGE_ARCH) \
-format=text | python3 -m json.tool > $${RESULT}.json ; \
echo "Uploading to S3" ; \
python3 ./scripts/code-coverage/parse-code-coverage.py \
-g . \
-c MapboxMaps \
--scheme $(SCHEME) \
--report $${RESULT}.json ; \
done
@echo "Done"
.PHONY: device-update-codecov-with-profdata
device-update-codecov-with-profdata:
make update-codecov-with-profdata \
COVERAGE_ARCH=arm64 \
COVERAGE_ROOT_DIR=$(BUILD_DIR)/ \
COVERAGE_MAPBOX_MAPS='$(BUILT_DEVICE_PRODUCTS_DIR)/MapboxMaps.o'
# ----------------------------------------------------------------------------------------------------------------------
# Dependencies
$(NETRC_FILE):
ifndef SDK_REGISTRY_TOKEN
@echo SDK_REGISTRY_TOKEN not set.
exit 1
endif
@echo "$$NETRC" > $(NETRC_FILE)
# ----------------------------------------------------------------------------------------------------------------------
# Validation
# See https://circleci.com/blog/circleci-hacks-validate-circleci-config-on-every-commit-with-a-git-hook/ for installing
# a pre commit hook to validate the CircleCI config. Call `make validate` from the pre-commit script.
.PHONY: validate
validate: $(CIRCLE_CI_CLI)
$(CIRCLE_CI_CLI) config validate -c .circleci/config.yml
$(CIRCLE_CI_CLI):
curl -fLSs https://circle.ci/cli | DESTDIR=/tmp bash