-
Notifications
You must be signed in to change notification settings - Fork 48
/
Cakefile
398 lines (282 loc) · 14.5 KB
/
Cakefile
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
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# https://github.com/jcampbell05/xcake
# http://www.rubydoc.info/github/jcampbell05/xcake/master/file/docs/Cakefile.md
# this is a sample Cakefile for a fictional project that is called "CakeMania"
#===
# just helper variables to use these values in a consistent way across whole file
iOSdeploymentTarget = "8.0"
currentSwiftVersion = "4.2"
companyIdentifier = "com.CakeMania"
developmentTeamId = "XYZXYZ" # for automatic debug signing in Xcode 8
testSuffix = "Tst"
testSuffixUI = "UI" + testSuffix
provProfAdHoc = "XXX"
provProfAppStore = "YYY"
#=== 3d-party integration keys (global variables)
# The values below will be used to set "user-defined" build settings
# for build configurations on target level,
# so we can reuse the same, lets say, "test" FB key
# within several "test" configurations (for example, the same test key
# would be used for "Debug" and "Staging" configurations), and can easily
# see what is the value/key we use for testing and production,
# and even update it in future if needed.
# "FACEBOOK_KEY"
facebookProdKey = "888888888888888"
facebookTestKey = "999999999999999"
#===
# lets define high level project settings
project.name = "CakeMania"
project.class_prefix = "CMN"
project.organization = "CakeMania Inc."
#===
# Below we explicitly define the list of project build configurations.
# If you do not define it explicitly, Xcake will implicitly define default ones,
# that are equivalent to this:
#
# project.debug_configuration :Debug
# project.release_configuration :Release
#
project.debug_configuration :Debug # for local development/debugging only, pointing to "test.*" API server
project.release_configuration :Staging # for alpha and beta AdHoc builds, pointing to "test.*" API server
project.release_configuration :RC # for release candidate AdHoc builds, pointing to "rc.*" API server
project.release_configuration :Production # for App Store ready AdHoc builds, pointing to "www." API server
project.release_configuration :AppStore # for App Store builds, pointing to "www." API server
# Note, that Xcake will also automatically create set of project "Schemes" -
# one for each build configuration, their names will be constructed from
# project name and configuration name, separated by dash, like this:
#
# "<project_name>-<configuration_name>"
#
# NOTE: every scheme will have the same build configiuration
# for all phases (Run, Test, Profile, Archive). If you need different build configurations
# based on phase - lets say one configuration for Run, but different one for Archive -
# consider to have different build configurations (and as result - build shemes) for these purposes
# (as proposed in this sample file).
#
# For this example, shemes will be:
#
# "CakeMania-Debug"
# "CakeMania-Staging"
# "CakeMania-RC"
# "CakeMania-Production"
# "CakeMania-AppStore"
#=== DEFAULT target settings
# Below we define "project level" build configurations.
# REMEMBER this entiire file is just an interpretable script,
# and the structure below is just a loop.
# At every iteration we have reference to one
# of the build configurations defined above explicitly or implicitly.
# In this case, we set the same build settings to each configuration,
# but, if we need to have some settings to be different for different
# configurations, then you can use "if" expression to set different build settings
# dependiong on "configuration.name" (we will see example of that in target settings below in this document).
project.all_configurations.each do |configuration|
# the settings listed below are just a copy
# of what Xcode sets explicitly in a newly created Xcode
# project file in comparison with default values
# (the values that are marked with bold font).
configuration.settings["ENABLE_BITCODE"] = "YES"
configuration.settings["SDKROOT"] = "iphoneos"
configuration.settings["GCC_DYNAMIC_NO_PIC"] = "NO"
configuration.settings["OTHER_CFLAGS"] = "$(inherited) -DNS_BLOCK_ASSERTIONS=1"
configuration.settings["GCC_C_LANGUAGE_STANDARD"] = "gnu99"
configuration.settings["CLANG_ENABLE_MODULES"] = "YES"
configuration.settings["CLANG_ENABLE_OBJC_ARC"] = "YES"
configuration.settings["ENABLE_NS_ASSERTIONS"] = "NO"
configuration.settings["ENABLE_STRICT_OBJC_MSGSEND"] = "YES"
configuration.settings["CLANG_WARN_EMPTY_BODY"] = "YES"
configuration.settings["CLANG_WARN_BOOL_CONVERSION"] = "YES"
configuration.settings["CLANG_WARN_CONSTANT_CONVERSION"] = "YES"
configuration.settings["GCC_WARN_64_TO_32_BIT_CONVERSION"] = "YES"
configuration.settings["CLANG_WARN_INT_CONVERSION"] = "YES"
configuration.settings["GCC_WARN_ABOUT_RETURN_TYPE"] = "YES_ERROR"
configuration.settings["GCC_WARN_UNINITIALIZED_AUTOS"] = "YES_AGGRESSIVE"
configuration.settings["CLANG_WARN_UNREACHABLE_CODE"] = "YES"
configuration.settings["GCC_WARN_UNUSED_FUNCTION"] = "YES"
configuration.settings["GCC_WARN_UNUSED_VARIABLE"] = "YES"
configuration.settings["CLANG_WARN_DIRECT_OBJC_ISA_USAGE"] = "YES_ERROR"
configuration.settings["CLANG_WARN__DUPLICATE_METHOD_MATCH"] = "YES"
configuration.settings["GCC_WARN_UNDECLARED_SELECTOR"] = "YES"
configuration.settings["CLANG_WARN_OBJC_ROOT_CLASS"] = "YES_ERROR"
configuration.settings["CURRENT_PROJECT_VERSION"] = "1" # just default non-empty value
configuration.settings["DEFINES_MODULE"] = "YES" # http://stackoverflow.com/a/27251979
configuration.settings["SWIFT_OPTIMIZATION_LEVEL"] = "-Onone"
configuration.settings["CLANG_WARN_INFINITE_RECURSION"] = "YES" # Xcode 8
configuration.settings["CLANG_WARN_SUSPICIOUS_MOVE"] = "YES" # Xcode 8
configuration.settings["ENABLE_STRICT_OBJC_MSGSEND"] = "YES" # Xcode 8
configuration.settings["GCC_NO_COMMON_BLOCKS"] = "YES"
configuration.settings["ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES"] = "$(inherited)" # "YES"
configuration.settings["SWIFT_VERSION"] = currentSwiftVersion
#===
if configuration.name == "RC" || configuration.name == "AppStore"
configuration.settings["DEBUG_INFORMATION_FORMAT"] = "dwarf-with-dsym"
configuration.settings["SWIFT_OPTIMIZATION_LEVEL"] = "-Owholemodule" # Xcode 8
end
end
#=== Targets
# So far, we've defined poject settings and
# project level build configuration settings
# (which define defaults for target level build configurations).
#
# Now it's time to define target-level build settings.
# Below we define "application"-type target and
# put all it's settings (including definition or related unit test targets)
# inside "application_for ... do ... end" structure.
target do |target|
target.name = project.name
target.language = :swift
target.type = :application
target.platform = :ios
target.deployment_target = iOSdeploymentTarget
#===
# Now lets set target-level build settigns.
# Again, the structure below is just a loop,
# everything between "target.all_configurations.each do |configuration|"
# and corresponding "end" (see below on the same level in the very bottom of the file)
# is body of this loop, that repeats every iteration. This loop goes through
# the list of build configurations (defined above) and on each iteration
# we have variable "configuration" that contains reference to one
# of the build configurations in CONTEXT of the TARGET. This is equivalent of setting
# build settings on target-level in Xcode (you can access it if you choose to
# see build settigns by "Levels", not "Combined").
# Imagine we have project folder structure like this:
#
# - Cakefile
# - Info/
# | - CakeMania.plist
# | - CakeManiaTst.plist
# | - CakeManiaUITst.plist
# - Lib/
# | - ...
# - Res/
# | - CakeMania.entitlements
# | - CakeMania-test.entitlements
# | - ...
# | - CakeMania.xcassets/
# | - ...
# | - AppIcon.appiconset/
# | - ...
# | - ...
# - Src/
# | - ...
# | - ObjC/
# | - Prefix.pch
# | - CakeMania-Bridging-Header.h
# | - ...
# - Tst/
# | - ...
# - UITst/
# | - ...
#
target.all_configurations.each do |configuration|
#=== Build Settings - Core
configuration.product_bundle_identifier = companyIdentifier + "." + target.name
configuration.supported_devices = :universal
configuration.settings["INFOPLIST_FILE"] = "Info/" + target.name + ".plist"
configuration.settings["PRODUCT_NAME"] = "$(TARGET_NAME)"
configuration.settings["CODE_SIGN_ENTITLEMENTS"] = "Res/CakeMania.entitlements"
configuration.settings["GCC_PREFIX_HEADER"] = "Src/ObjC/Prefix.pch"
# configuration.settings["FRAMEWORK_SEARCH_PATHS"] = "$(inherited)"
configuration.settings["LIBRARY_SEARCH_PATHS"] = "$(inherited) $(SRCROOT)/Lib/**"
configuration.settings["ASSETCATALOG_COMPILER_APPICON_NAME"] = "AppIcon"
# configuration.settings["ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME"] = "Brand Assets"
configuration.settings["SWIFT_OBJC_BRIDGING_HEADER"] = "Src/ObjC/CakeMania-Bridging-Header.h"
configuration.settings["OTHER_LDFLAGS"] = "$(inherited) -ObjC"
# make configuration name available in run time:
configNameFlag = "CONFIG_" + configuration.name.upcase
configuration.settings["GCC_PREPROCESSOR_DEFINITIONS"] = "$(inherited) " + configNameFlag + "=1" # Obj-C support
configuration.settings["OTHER_SWIFT_FLAGS"] = "$(inherited) -D" + configNameFlag # Swift support
# This will show "Automatic" in Xcode,
# relies on proper/valid "PROVISIONING_PROFILE" value:
# configuration.settings["CODE_SIGN_IDENTITY[sdk=iphoneos*]"] = nil # DEPRECATED
# Xcode 8 automati c signing support
configuration.settings["CODE_SIGN_IDENTITY[sdk=iphoneos*]"] = "iPhone Developer"
configuration.settings["DEVELOPMENT_TEAM"] = developmentTeamId
#=== Build Settings - Per-configuration
# NOTE: any configuration-specific settings below will override
# common settings that you already applied above inside this
# "target.all_configurations.each do |configuration|" block
if configuration.name == "Debug"
#=== Config
configuration.settings["CODE_SIGN_ENTITLEMENTS"] = "Res/CakeMania-test.entitlements"
#=== Config - User Defined Build Settings
configuration.settings["FACEBOOK_KEY"] = facebookTestKey
end
#===
if configuration.name == "Staging"
#=== Config
configuration.settings["PROVISIONING_PROFILE"] = provProfAdHoc
configuration.settings["CODE_SIGN_ENTITLEMENTS"] = "Res/CakeMania-test.entitlements"
#=== Config - User Defined Build Settings
configuration.settings["FACEBOOK_KEY"] = facebookTestKey
end
#===
if configuration.name == "RC"
#=== Config
configuration.settings["PROVISIONING_PROFILE"] = provProfAdHoc
configuration.settings["CODE_SIGN_ENTITLEMENTS"] = "Res/CakeMania-test.entitlements"
#=== Config - User Defined Build Settings
configuration.settings["FACEBOOK_KEY"] = facebookTestKey
end
#===
if configuration.name == "Production"
#=== Config
configuration.settings["PROVISIONING_PROFILE"] = provProfAdHoc # AdHoc
#=== Config - User Defined Build Settings
configuration.settings["FACEBOOK_KEY"] = facebookProdKey
end
#===
if configuration.name == "AppStore"
#=== Config
configuration.settings["PROVISIONING_PROFILE"] = provProfAppStore
#=== Config - User Defined Build Settings
configuration.settings["FACEBOOK_KEY"] = facebookProdKey
end
end
#=== Extra System Frameworks
# Here is how we tell Xcake to include Apple system framework
# into the target.
# NOTE: "target.system_frameworks" is an array, that always have at least
# "Foundation" and "UIKit", os it's always non-empty and we should not initialize it
# before adding something there, so we jsut add values, one at a time (one per each line below).
target.system_frameworks << "AdSupport"
target.system_frameworks << "QuartzCore"
#=== Source Files
# Here is how we tell Xcake where to look for source files
# which need to be added into the target. Moreover, the folder struture
# will be re-created with Xcode groups.
# NOTE: "target.include_files" is an array, that is empty by default
# (no source files will be added to the target). So it's our responsibility
# to initialize this array (with "=" operand) before adding values/elements
# into it (with "<<" operand). Remember, this file is a Ruby script, and
# that's just how Ruby works.
target.include_files = ["Src/**/*.*"] # initialize array with 1 element
target.include_files << "Lib/**/*.*" # add value into already non-empty array
target.include_files << "Res/**/*.*" # add another value
#=== Tests
# Below we define unit tests target for the application target.
# "unit_tests_for" is a reserved word, then you put variable that contains reference
# to the application target that you want to create unit tests for, it's "target" in our case.
# The "test_target" is reference to the newly created unit test target
# so we can configure it as we want - set name, build configurations (at least info plist file)
# and its source files, or course. The rules of how we work with test target (set its settings)
# are the same, as we work with application target.
unit_tests_for target do |test_target|
test_target.name = target.name + testSuffix
test_target.all_configurations.each do |configuration|
configuration.settings["INFOPLIST_FILE"] = "Info/" + test_target.name + ".plist"
end
#=== Source Files
test_target.include_files = [testSuffix + "/**/*.*"] # we set array with 1 element here!
end
#===
# Below we define UI tests target for the application target.
# See https://github.com/jcampbell05/xcake/issues/44
ui_tests_for target do |test_target|
test_target.name = target.name + testSuffixUI
test_target.all_configurations.each do |configuration|
configuration.settings["INFOPLIST_FILE"] = "Info/" + test_target.name + ".plist"
end
#=== Source Files
test_target.include_files = [testSuffixUI + "/**/*.*"] # we set array with 1 element here!
end
end