Skip to content

Commit 38f026d

Browse files
committed
add swift 2 build script back
1 parent 54d119b commit 38f026d

File tree

1 file changed

+236
-0
lines changed

1 file changed

+236
-0
lines changed

build-2.2.swift

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
#!/usr/bin/env xcrun swift
2+
3+
// This script builds and lipos dynamic frameworks
4+
// built by Xcode. Requires Swift 2.2 or higher.
5+
6+
import Foundation
7+
8+
/// Map from scheme names to framework names.
9+
/// Hopefully can avoid hard-coding this in the future
10+
let schemes = [
11+
"FirebaseDatabaseUI",
12+
"FirebaseAuthUI",
13+
"FirebaseFacebookAuthUI",
14+
"FirebaseGoogleAuthUI",
15+
"FirebaseTwitterAuthUI",
16+
]
17+
18+
let staticLibs = [
19+
"Database": "FirebaseDatabaseUI",
20+
"Auth" : "FirebaseAuthUI",
21+
"Facebook": "FirebaseFacebookAuthUI",
22+
"Google" : "FirebaseGoogleAuthUI",
23+
"Twitter" : "FirebaseTwitterAuthUI",
24+
]
25+
26+
// TODO: Use NSFileManager instead of all these awful
27+
// manual path appendings and mkdir/mv/cp
28+
29+
let DerivedDataDir = "artifacts/"
30+
let BuiltProductsDir = "FirebaseUIFrameworks/"
31+
32+
// TODO: DRY out these Task functions
33+
34+
func mkdir(dirname: String) -> Void {
35+
let task = NSTask()
36+
task.launchPath = "/bin/mkdir"
37+
task.arguments = ["-p", dirname]
38+
task.launch()
39+
task.waitUntilExit()
40+
}
41+
42+
func mv(from source: String, to destination: String) -> Void {
43+
let task = NSTask()
44+
task.launchPath = "/bin/mv"
45+
task.arguments = ["-n", "-v", source, destination]
46+
task.launch()
47+
task.waitUntilExit()
48+
guard task.terminationStatus == 0 else { exit(task.terminationStatus) }
49+
}
50+
51+
func cp(from source: String, to destination: String) -> Void {
52+
let task = NSTask()
53+
task.launchPath = "/bin/cp"
54+
task.arguments = ["-R", "-n", source, destination]
55+
task.launch()
56+
task.waitUntilExit()
57+
guard task.terminationStatus == 0 else { exit(task.terminationStatus) }
58+
}
59+
60+
mkdir(DerivedDataDir)
61+
mkdir(BuiltProductsDir)
62+
63+
// Build
64+
65+
// TODO: use xcrun to invoke dev tool commands
66+
67+
func buildTask(args: [String] = []) -> NSTask {
68+
let task = NSTask()
69+
task.launchPath = "/usr/bin/xcodebuild"
70+
task.arguments = args
71+
return task
72+
}
73+
74+
/// A value type representing an xcodebuild call.
75+
/// param keys are parameters and expect leading dashes,
76+
/// i.e. `-workspace`
77+
struct Build {
78+
79+
var params: [String: String]
80+
81+
init(_ params: [String: String]) {
82+
self.params = params
83+
}
84+
85+
var args: [String] {
86+
var params: [String] = []
87+
let keys = self.params.keys
88+
for key in keys {
89+
params.append(key)
90+
let value = self.params[key]
91+
if let value = value {
92+
params.append(value)
93+
}
94+
}
95+
// hard code bitcode so cocoapods dummy
96+
// files are built with bitcode, hope for
97+
// no consequences later
98+
params.append("BITCODE_GENERATION_MODE=bitcode")
99+
return params
100+
}
101+
102+
func launch() {
103+
let task = buildTask(self.args)
104+
task.launch()
105+
task.waitUntilExit()
106+
guard task.terminationStatus == 0 else {
107+
exit(task.terminationStatus)
108+
}
109+
}
110+
}
111+
112+
let sdks = ["iphoneos", "iphonesimulator"]
113+
114+
// make folder structure for built products
115+
schemes.forEach { scheme in
116+
let schemeDir = BuiltProductsDir + scheme
117+
mkdir(schemeDir)
118+
mkdir(schemeDir + "/Frameworks")
119+
}
120+
121+
// Invoke xcodebuild, building each scheme in
122+
// release for each target sdk. Building
123+
// dynamic frameworks so we don't have to do
124+
// the asset bundling and folder structures manually,
125+
// at the costs of lots of duplication. Not sure if ideal.
126+
let builds = schemes.map { scheme in
127+
return Build([
128+
"-workspace" : "FirebaseUI.xcworkspace",
129+
"-scheme" : scheme,
130+
"-configuration" : "Release",
131+
"-sdk" : sdks[0],
132+
"-derivedDataPath": DerivedDataDir,
133+
])
134+
}
135+
136+
let staticBuilds: [Build] = sdks.flatMap { sdk -> [Build] in
137+
let schemeNames = Array(staticLibs.keys)
138+
return schemeNames.map { scheme -> Build in
139+
return Build([
140+
"-workspace" : "FirebaseUI.xcworkspace",
141+
"-scheme" : scheme,
142+
"-configuration" : "Release",
143+
"-sdk" : sdk,
144+
"-derivedDataPath": DerivedDataDir,
145+
])
146+
}
147+
}
148+
149+
builds.forEach { $0.launch() }
150+
staticBuilds.forEach { $0.launch() }
151+
152+
// Copy frameworks into built products dir. Don't really
153+
// care about sdk here since we're gonna lipo everything later
154+
schemes.forEach { scheme in
155+
let sdk = sdks[0] // arbitrary sdk, just need folder structure
156+
let frameworkDir = BuiltProductsDir + scheme + "/Frameworks"
157+
let framework = scheme
158+
let frameworkPath = "\(DerivedDataDir)Build/Products/Release-\(sdk)/\(framework).framework"
159+
cp(from: frameworkPath, to: frameworkDir)
160+
}
161+
162+
// Lipo
163+
164+
/// A value type representing an invocation of `lipo -create`.
165+
struct Lipo {
166+
var inputs: [String]
167+
var output: String
168+
169+
func launch() {
170+
print("lipo \(output)")
171+
let task = NSTask()
172+
task.launchPath = "/usr/bin/lipo"
173+
task.arguments = ["-create"] + self.inputs
174+
+ ["-output"] + [output]
175+
task.launch()
176+
task.waitUntilExit()
177+
guard task.terminationStatus == 0 else {
178+
exit(task.terminationStatus)
179+
}
180+
}
181+
}
182+
183+
let productsPaths = sdks.map {
184+
return DerivedDataDir + "Build/Products/Release-" + $0 + "/"
185+
}
186+
187+
// create lipo tasks from built products
188+
let lipos: [Lipo] = Array(staticLibs.keys).map { scheme in
189+
let product = staticLibs[scheme]!
190+
let framework = "\(product).framework"
191+
let binary = "lib\(scheme).a"
192+
193+
let chunks = productsPaths.map { path in
194+
return path + binary
195+
}
196+
197+
let output = "\(BuiltProductsDir)\(product)/Frameworks/\(framework)/\(product)"
198+
return Lipo(inputs: chunks, output: output)
199+
}
200+
201+
// lipo everything
202+
lipos.forEach { $0.launch() }
203+
204+
// copy license file
205+
cp(from: "LICENSE", to: BuiltProductsDir)
206+
207+
// clean up build artifacts afterward
208+
209+
/// Moves files to trash
210+
func rm(path: String, isDirectory: Bool) -> Void {
211+
let url = NSURL(fileURLWithPath: path, isDirectory: isDirectory)
212+
let fileManager = NSFileManager()
213+
do {
214+
try fileManager.trashItemAtURL(url, resultingItemURL: nil)
215+
} catch (let error) {
216+
print(fileManager.currentDirectoryPath)
217+
print(error)
218+
exit(1)
219+
}
220+
}
221+
222+
func zip(input: String, output: String) -> Void {
223+
let task = NSTask()
224+
task.launchPath = "/usr/bin/zip"
225+
task.arguments = ["-r", "-9", output, input]
226+
task.launch()
227+
task.waitUntilExit()
228+
guard task.terminationStatus == 0 else { exit(task.terminationStatus) }
229+
}
230+
231+
zip("FirebaseUIFrameworks", output: "FirebaseUIFrameworks.zip")
232+
233+
rm(DerivedDataDir, isDirectory: true)
234+
rm(BuiltProductsDir, isDirectory: true)
235+
236+
exit(0)

0 commit comments

Comments
 (0)