16
16
and serialization to .xcodeproj plists. There is no consistency checking to
17
17
ensure, for example, that build settings have valid values, dependency cycles
18
18
are not created, etc.
19
-
19
+
20
20
Everything here is geared toward supporting project generation. The intended
21
21
usage model is for custom logic to build up a project using Xcode terminology
22
22
(e.g. "group", "reference", "target", "build phase"), but there is almost no
23
23
provision for modifying the model after it has been built up. The intent is
24
24
to create it as desired from the start.
25
-
25
+
26
26
Rather than try to represent everything that Xcode's project model supports,
27
27
the approach is to start small and to add functionality as needed.
28
-
28
+
29
29
Note that this API represents only the project model — there is no notion of
30
30
workspaces, schemes, etc (although schemes are represented individually in a
31
31
separate API). The notion of build settings is also somewhat different from
37
37
configuration of the settings, since most values are the same between Debug
38
38
and Release. Also, the build settings themselves are represented as structs
39
39
of named fields, instead of dictionaries with arbitrary name strings as keys.
40
-
40
+
41
41
It is expected that some of these simplifications will need to be lifted over
42
42
time, based on need. That should be done carefully, however, to avoid ending
43
43
up with an overly complicated model.
44
-
44
+
45
45
Some things that are incomplete in even this first model:
46
46
- copy files build phases are incomplete
47
47
- shell script build phases are incomplete
57
57
*/
58
58
59
59
public struct Xcode {
60
-
60
+
61
61
/// An Xcode project, consisting of a tree of groups and file references,
62
62
/// a list of targets, and some additional information. Note that schemes
63
63
/// are outside of the project data model.
@@ -74,7 +74,7 @@ public struct Xcode {
74
74
self . projectDir = " "
75
75
self . targets = [ ]
76
76
}
77
-
77
+
78
78
/// Creates and adds a new target (which does not initially have any
79
79
/// build phases).
80
80
public func addTarget( objectID: String ? = nil , productType: Target . ProductType ? = nil , name: String ) -> Target {
@@ -94,7 +94,7 @@ public struct Xcode {
94
94
/// Name of the reference, if different from the last path component
95
95
/// (if not set, Xcode will use the last path component as the name).
96
96
public var name : String ?
97
-
97
+
98
98
/// Determines the base path for a reference's relative path (this is
99
99
/// what for some reason is called a "source tree" in Xcode).
100
100
public enum RefPathBase : String {
@@ -111,13 +111,13 @@ public struct Xcode {
111
111
/// destination, or even an overridden build setting.
112
112
case buildDir = " BUILT_PRODUCTS_DIR "
113
113
}
114
-
114
+
115
115
init ( path: String , pathBase: RefPathBase = . groupDir, name: String ? = nil ) {
116
116
self . path = path
117
117
self . pathBase = pathBase
118
118
self . name = name
119
119
}
120
-
120
+
121
121
/// Whether this is either a group or directory reference (blue folder).
122
122
public var isDirectoryLike : Bool {
123
123
if self is Xcode . Group {
@@ -129,7 +129,7 @@ public struct Xcode {
129
129
return false
130
130
}
131
131
}
132
-
132
+
133
133
/// A reference to a file system entity (a file, folder, etc).
134
134
public final class FileReference : Reference {
135
135
public var objectID : String ?
@@ -153,7 +153,7 @@ public struct Xcode {
153
153
/// references whose source tree type is GroupRelative.
154
154
public final class Group : Reference {
155
155
public var subitems = [ Reference] ( )
156
-
156
+
157
157
/// Creates and appends a new Group to the list of subitems.
158
158
/// The new group is returned so that it can be configured.
159
159
@discardableResult
@@ -166,7 +166,7 @@ public struct Xcode {
166
166
subitems. append ( group)
167
167
return group
168
168
}
169
-
169
+
170
170
/// Creates and appends a new FileReference to the list of subitems.
171
171
@discardableResult
172
172
public func addFileReference(
@@ -212,11 +212,11 @@ public struct Xcode {
212
212
self . dependencies = [ ]
213
213
self . buildableFolders = [ ]
214
214
}
215
-
215
+
216
216
// FIXME: There's a lot repetition in these methods; using generics to
217
217
// try to avoid that raised other issues in terms of requirements on
218
218
// the Reference class, though.
219
-
219
+
220
220
/// Adds a "headers" build phase, i.e. one that copies headers into a
221
221
/// directory of the product, after suitable processing.
222
222
@discardableResult
@@ -225,7 +225,7 @@ public struct Xcode {
225
225
buildPhases. append ( phase)
226
226
return phase
227
227
}
228
-
228
+
229
229
/// Adds a "sources" build phase, i.e. one that compiles sources and
230
230
/// provides them to be linked into the executable code of the product.
231
231
@discardableResult
@@ -234,7 +234,7 @@ public struct Xcode {
234
234
buildPhases. append ( phase)
235
235
return phase
236
236
}
237
-
237
+
238
238
/// Adds a "frameworks" build phase, i.e. one that links compiled code
239
239
/// and libraries into the executable of the product.
240
240
@discardableResult
@@ -243,7 +243,7 @@ public struct Xcode {
243
243
buildPhases. append ( phase)
244
244
return phase
245
245
}
246
-
246
+
247
247
/// Adds a "copy files" build phase, i.e. one that copies files to an
248
248
/// arbitrary location relative to the product.
249
249
@discardableResult
@@ -252,7 +252,7 @@ public struct Xcode {
252
252
buildPhases. append ( phase)
253
253
return phase
254
254
}
255
-
255
+
256
256
/// Adds a "shell script" build phase, i.e. one that runs a custom
257
257
/// shell script as part of the build.
258
258
@discardableResult
@@ -265,7 +265,7 @@ public struct Xcode {
265
265
buildPhases. append ( phase)
266
266
return phase
267
267
}
268
-
268
+
269
269
/// Adds a dependency on another target.
270
270
/// FIXME: We do not check for cycles. Should we? This is an extremely
271
271
/// minimal API so it's not clear that we should.
@@ -286,11 +286,11 @@ public struct Xcode {
286
286
public unowned var target : Target
287
287
}
288
288
}
289
-
289
+
290
290
/// Abstract base class for all build phases in a target.
291
291
public class BuildPhase {
292
292
public var files : [ BuildFile ] = [ ]
293
-
293
+
294
294
/// Adds a new build file that refers to `fileRef`.
295
295
@discardableResult
296
296
public func addBuildFile( fileRef: FileReference ) -> BuildFile {
@@ -299,25 +299,25 @@ public struct Xcode {
299
299
return buildFile
300
300
}
301
301
}
302
-
302
+
303
303
/// A "headers" build phase, i.e. one that copies headers into a directory
304
304
/// of the product, after suitable processing.
305
305
public final class HeadersBuildPhase : BuildPhase {
306
306
// Nothing extra yet.
307
307
}
308
-
308
+
309
309
/// A "sources" build phase, i.e. one that compiles sources and provides
310
310
/// them to be linked into the executable code of the product.
311
311
public final class SourcesBuildPhase : BuildPhase {
312
312
// Nothing extra yet.
313
313
}
314
-
314
+
315
315
/// A "frameworks" build phase, i.e. one that links compiled code and
316
316
/// libraries into the executable of the product.
317
317
public final class FrameworksBuildPhase : BuildPhase {
318
318
// Nothing extra yet.
319
319
}
320
-
320
+
321
321
/// A "copy files" build phase, i.e. one that copies files to an arbitrary
322
322
/// location relative to the product.
323
323
public final class CopyFilesBuildPhase : BuildPhase {
@@ -326,7 +326,7 @@ public struct Xcode {
326
326
self . dstDir = dstDir
327
327
}
328
328
}
329
-
329
+
330
330
/// A "shell script" build phase, i.e. one that runs a custom shell script.
331
331
public final class ShellScriptBuildPhase : BuildPhase {
332
332
public var script : String
@@ -340,27 +340,27 @@ public struct Xcode {
340
340
self . alwaysRun = alwaysRun
341
341
}
342
342
}
343
-
343
+
344
344
/// A build file, representing the membership of a file reference in a
345
345
/// build phase of a target.
346
346
public final class BuildFile {
347
347
public var fileRef : FileReference ?
348
348
init ( fileRef: FileReference ) {
349
349
self . fileRef = fileRef
350
350
}
351
-
351
+
352
352
public var settings = Settings ( )
353
-
353
+
354
354
/// A set of file settings.
355
355
public struct Settings : Encodable {
356
356
public var ATTRIBUTES : [ String ] ?
357
357
public var COMPILER_FLAGS : String ?
358
-
358
+
359
359
public init ( ) {
360
360
}
361
361
}
362
362
}
363
-
363
+
364
364
/// A table of build settings, which for the sake of simplicity consists
365
365
/// (in this simplified model) of a set of common settings, and a set of
366
366
/// overlay settings for Debug and Release builds. There can also be a
@@ -369,21 +369,21 @@ public struct Xcode {
369
369
/// Common build settings are in both generated configurations (Debug
370
370
/// and Release).
371
371
public var common = BuildSettings ( )
372
-
372
+
373
373
/// Debug build settings are overlaid over the common settings in the
374
374
/// generated Debug configuration.
375
375
public var debug = BuildSettings ( )
376
-
376
+
377
377
/// Release build settings are overlaid over the common settings in the
378
378
/// generated Release configuration.
379
379
public var release = BuildSettings ( )
380
-
380
+
381
381
/// An optional file reference to an .xcconfig file.
382
382
public var xcconfigFileRef : FileReference ?
383
-
383
+
384
384
public init ( ) {
385
385
}
386
-
386
+
387
387
/// A set of build settings, which is represented as a struct of optional
388
388
/// build settings. This is not optimally efficient, but it is great for
389
389
/// code completion and type-checking.
0 commit comments