Skip to content

Commit 213299d

Browse files
authored
Merge pull request #13 from handsomecode/develop
Develop
2 parents 84c82e0 + 39a0e18 commit 213299d

File tree

11 files changed

+162
-40
lines changed

11 files changed

+162
-40
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
TOOL_NAME = UnityBuildKit
2-
VERSION = 1.1.1
2+
VERSION = 1.1.2
33

44
PREFIX = /usr/local
55
INSTALL_PATH = $(PREFIX)/bin/$(TOOL_NAME)

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<img src="Assets/ubk_logo.png">
33
</p>
44
<p align="center">
5-
<img src="https://img.shields.io/badge/version-1.1.1-blue.svg?style=flat-square" />
5+
<img src="https://img.shields.io/badge/version-1.1.2-blue.svg?style=flat-square" />
66
<a href="https://github.com/handsomecode/UnityBuildKit/blob/master/LICENSE">
77
<img src="https://img.shields.io/github/license/mashape/apistatus.svg?style=flat-square"/>
88
</a>
@@ -44,12 +44,12 @@ mkdir ExampleProject
4444
cd ExampleProject
4545
```
4646

47-
2. Run the following to generate the `ubconfig.json` file where you can specify project information
47+
2. Run the following to generate the `ubconfig.json` file where you can specify project information (see more information [here](https://github.com/handsomecode/UnityBuildKit/wiki/Configuration-File))
4848
```
4949
UnityBuildKit config
5050
```
5151

52-
3. After filling out the config file information, run
52+
3. After filling out the config file, run
5353
```
5454
$ UnityBuildKit generate
5555
```

Sources/UBKit/Files/Config/configFile.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ extension File {
3131
"ios": {
3232
"projectName": "ExampleProject",
3333
"bundleId": "com.example.ExampleProject",
34-
"projectPath": "" // Defaults to iOS/
34+
"projectPath": "" // e.g. iOS/
3535
},
3636
"unity": {
3737
"projectName": "ExampleProject",
38-
"applicationPath": "", // e.g /Applications/Unity/Unity.app/Contents/MacOS/Unity
39-
"version": "", // e.g. 2017.1.f1
40-
"projectPath": "", // Defaults to Unity/
38+
"applicationPath": "", // e.g. /Applications/Unity/Unity.app/Contents/MacOS/Unity
39+
"version": "", // e.g. 2017.2.1.f1
40+
"projectPath": "", // e.g. Unity/
4141
"sceneNames": [
4242
"ExampleScene"
4343
]
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//
2+
// UnityProjectScript.swift
3+
// UnityBuildKitPackageDescription
4+
//
5+
// Copyright (c) 2017 Handsome
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in all
15+
// copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
// SOFTWARE.
24+
25+
import Foundation
26+
27+
extension File {
28+
29+
class func unityFrameworksScriptFile(projectName: String, iOSProjectPath: String) -> Data? {
30+
let file = """
31+
using System.Collections;
32+
using System.IO;
33+
using UnityEngine;
34+
using UnityEditor;
35+
using UnityEditor.SceneManagement;
36+
using UnityEngine.SceneManagement;
37+
using UnityEditor.iOS.Xcode;
38+
39+
public class XcodeFrameworks: MonoBehaviour {
40+
41+
private const string iOSProjectRoot = \"\(iOSProjectPath)\";
42+
private const string iOSProjectName = \"\(projectName)\";
43+
private const string PbxFilePath = iOSProjectName + ".xcodeproj/project.pbxproj";
44+
45+
public static void Perform () {
46+
var pbx = new PBXProject();
47+
var pbxPath = Path.Combine(iOSProjectRoot, PbxFilePath);
48+
pbx.ReadFromFile(pbxPath);
49+
50+
var targetGuid = pbx.TargetGuidByName(iOSProjectName);
51+
pbx.AddFrameworkToProject(targetGuid, "GameKit.framework", true);
52+
pbx.AddFrameworkToProject(targetGuid, "CoreGraphics.framework", false);
53+
pbx.AddFrameworkToProject(targetGuid, "AVFoundation.framework", false);
54+
pbx.AddFrameworkToProject(targetGuid, "CoreVideo.framework", false);
55+
pbx.AddFrameworkToProject(targetGuid, "CoreMedia.framework", false);
56+
pbx.AddFrameworkToProject(targetGuid, "SystemConfiguration.framework", false);
57+
pbx.AddFrameworkToProject(targetGuid, "CoreLocation.framework", false);
58+
pbx.AddFrameworkToProject(targetGuid, "MediaPlayer.framework", false);
59+
pbx.AddFrameworkToProject(targetGuid, "CFNetwork.framework", false);
60+
pbx.AddFrameworkToProject(targetGuid, "AudioToolbox.framework", false);
61+
pbx.AddFrameworkToProject(targetGuid, "OpenAL.framework", false);
62+
pbx.AddFrameworkToProject(targetGuid, "QuartzCore.framework", false);
63+
pbx.AddFrameworkToProject(targetGuid, "Foundation.framework", false);
64+
pbx.AddFrameworkToProject(targetGuid, "MediaToolbox.framework", false);
65+
66+
pbx.WriteToFile(pbxPath);
67+
}
68+
}
69+
""".data(using: .utf8)
70+
return file
71+
}
72+
}

Sources/UBKit/Files/Xcode/SpecFile.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extension File {
5151
UNITY_SCRIPTING_BACKEND: il2cpp
5252
UNITY_IOS_EXPORT_PATH: ${SRCROOT}/../Unity/\(projectName)/ios_build
5353
GCC_PREFIX_HEADER: $(UNITY_IOS_EXPORT_PATH)/Classes/Prefix.pch
54-
OTHER_LDFLAGS: -weak-lSystem -weak_framework CoreMotion -weak_framework GameKit -weak_framework iAd -framework CoreGraphics -framework AVFoundation -framework CoreVideo -framework CoreMedia -framework SystemConfiguration -framework CoreLocation -framework MediaPlayer -framework CFNetwork -framework AudioToolbox -framework OpenAL -framework QuartzCore -framework OpenGLES -framework UIKit -framework Foundation -framework MediaToolbox -liconv.2 -liPhone-lib
54+
OTHER_LDFLAGS: -weak-lSystem -liconv.2 -liPhone-lib -weak_framework CoreMotion -weak_framework iAd -framework OpenGLES
5555
HEADER_SEARCH_PATHS: $(UNITY_IOS_EXPORT_PATH)/Classes $(UNITY_IOS_EXPORT_PATH)/Classes/Native $(UNITY_IOS_EXPORT_PATH)/Libraries/libil2cpp/include
5656
LIBRARY_SEARCH_PATHS: $(UNITY_IOS_EXPORT_PATH)/Libraries $(UNITY_IOS_EXPORT_PATH)/Libraries/libil2cpp/include
5757
ENABLE_BITCODE: NO

Sources/UBKit/Models/Config.swift

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,18 @@ struct iOSConfig: Decodable {
6464
}
6565

6666
let projectPath: String
67-
if let path = try? container.decode(String.self, forKey: .projectPath), !path.isEmpty {
68-
projectPath = path
69-
} else {
70-
projectPath = FileManager.default.currentDirectoryPath.appending("/iOS/")
67+
do {
68+
let path = try container.decode(String.self, forKey: .projectPath)
69+
if path.isEmpty {
70+
throw UBKitError.invalidConfigArgument(Keys.projectPath.rawValue)
71+
}
72+
projectPath = FileManager.default.currentDirectoryPath.appending("/").appending(path)
73+
} catch {
74+
throw UBKitError.invalidConfigArgument(Keys.projectPath.rawValue)
75+
}
76+
77+
if !projectPath.hasSuffix("/") {
78+
throw UBKitError.invalidConfigArgument("Project Path must end with a \"/\"")
7179
}
7280

7381
self.projectName = projectName
@@ -113,10 +121,18 @@ struct UnityConfig {
113121
}
114122

115123
let projectPath: String
116-
if let path = try? container.decode(String.self, forKey: .projectPath), !path.isEmpty {
117-
projectPath = path
118-
} else {
119-
projectPath = FileManager.default.currentDirectoryPath.appending("/Unity/")
124+
do {
125+
let path = try container.decode(String.self, forKey: .projectPath)
126+
if path.isEmpty {
127+
throw UBKitError.invalidConfigArgument(Keys.projectPath.rawValue)
128+
}
129+
projectPath = FileManager.default.currentDirectoryPath.appending("/").appending(path)
130+
} catch {
131+
throw UBKitError.invalidConfigArgument(Keys.projectPath.rawValue)
132+
}
133+
134+
if !projectPath.hasSuffix("/") {
135+
throw UBKitError.invalidConfigArgument("Project Path must end with a \"/\"")
120136
}
121137

122138
let sceneNames = try container.decode([String].self, forKey: .sceneNames)

Sources/UBKit/Models/UnityCommandLine.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import Foundation
2929
struct UnityCommandLine {
3030
static let buildAction = "iOSBuilder.Perform"
3131
static let refreshAction = "XcodeRefresher.Refresh"
32+
static let frameworksAction = "XcodeFrameworks.Perform"
3233

3334
struct Arguments {
3435
static let projectPath = "-projectPath"

Sources/UBKit/Workers/FileCopier.swift

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ class FileCopier {
8080
return unityFilesResult
8181
}
8282

83+
let addFrameworksResult = addXcodeFrameworks()
84+
guard addFrameworksResult == .success else {
85+
return addFrameworksResult
86+
}
87+
8388
return .success
8489
}
8590
}
@@ -113,25 +118,6 @@ private extension FileCopier {
113118
return .success
114119
}
115120

116-
func x() -> Result {
117-
guard let project = project else {
118-
return .failure(UBKitError.invalidXcodeProject("Failed to find project file"))
119-
}
120-
121-
guard let mainTarget = project.pbxproj.objects.nativeTargets.filter({ $0.value.name == config.iOS.projectName }).first else {
122-
return .failure(UBKitError.invalidXcodeProject("Missing main target"))
123-
}
124-
125-
for phase in mainTarget.value.buildPhases {
126-
if phase.starts(with: "RBP_") {
127-
128-
break
129-
}
130-
}
131-
132-
return .success
133-
}
134-
135121
func changeUnityFiles() -> Result {
136122
let mainFilePath = workingPath.appending(config.unity.projectName).appending("/ios_build/Classes/main.mm")
137123
guard fileManager.fileExists(atPath: mainFilePath) else {
@@ -165,12 +151,13 @@ private extension FileCopier {
165151
func addUnityFiles() -> Result {
166152
let semaphore = DispatchSemaphore(value: 0)
167153
var statusCode: Int32 = 999
154+
let projectPath = workingPath.appending(config.unity.projectName).appending("/ios_build")
168155

169156
shell.perform(
170157
config.unity.applicationPath,
171158
UnityCommandLine.Arguments.batchmode,
172159
UnityCommandLine.Arguments.buildPath,
173-
workingPath.appending(config.unity.projectName).appending("/ios_build"),
160+
projectPath,
174161
UnityCommandLine.Arguments.executeMethod,
175162
UnityCommandLine.refreshAction,
176163
UnityCommandLine.Arguments.quit,
@@ -192,6 +179,37 @@ private extension FileCopier {
192179
}
193180
}
194181

182+
func addXcodeFrameworks() -> Result {
183+
let semaphore = DispatchSemaphore(value: 0)
184+
var statusCode: Int32 = 999
185+
let projectPath = workingPath.appending(config.unity.projectName)
186+
187+
shell.perform(
188+
config.unity.applicationPath,
189+
UnityCommandLine.Arguments.batchmode,
190+
UnityCommandLine.Arguments.projectPath,
191+
projectPath,
192+
UnityCommandLine.Arguments.executeMethod,
193+
UnityCommandLine.frameworksAction,
194+
UnityCommandLine.Arguments.quit,
195+
terminationHandler: { (process) in
196+
statusCode = process.terminationStatus
197+
semaphore.signal()
198+
})
199+
200+
let timeout = semaphore.wait(timeout: DispatchTime.now()+60.0)
201+
switch timeout {
202+
case .success:
203+
if statusCode == 0 {
204+
return .success
205+
} else {
206+
return .failure(UBKitError.shellCommand("Initializing Unity Project"))
207+
}
208+
case .timedOut:
209+
return .failure(UBKitError.waitTimedOut)
210+
}
211+
}
212+
195213
func saveProject() -> Result {
196214
guard let project = project else {
197215
return .failure(UBKitError.invalidXcodeProject("Failed to find project file"))

Sources/UBKit/Workers/UnityProject.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class UnityProject {
4747
return .failure(UBKitError.invalidFolder(unityAppPath))
4848
}
4949

50+
print("Unity Project Path: \(workingPath)\n")
5051
let unityFolderResult = createUnityFolder()
5152
guard unityFolderResult == .success else {
5253
return unityFolderResult
@@ -59,7 +60,7 @@ class UnityProject {
5960
return projectGenerationResult
6061
}
6162

62-
print("\nGenerating Unity Editor scripts")
63+
print("Generating Unity Editor scripts")
6364
let editorScriptsResult = createUnityEditorScripts()
6465
guard editorScriptsResult == .success else {
6566
return editorScriptsResult
@@ -144,12 +145,19 @@ private extension UnityProject {
144145
}
145146

146147
guard fileManager.createFile(
147-
atPath: editorFilePath.appending("ProjectScript.cs"),
148+
atPath: editorFilePath.appending("XcodeProjectRefresher.cs"),
148149
contents: File.unityProjectScriptFile(projectName: projectName, iOSProjectPath: config.iOS.projectPath),
149150
attributes: nil) else {
150151
return .failure(UBKitError.unableToCreateFile("Unity Project Script"))
151152
}
152153

154+
guard fileManager.createFile(
155+
atPath: editorFilePath.appending("XcodeFrameworks.cs"),
156+
contents: File.unityFrameworksScriptFile(projectName: projectName, iOSProjectPath: config.iOS.projectPath),
157+
attributes: nil) else {
158+
return .failure(UBKitError.unableToCreateFile("Xcode Frameworks Script"))
159+
}
160+
153161
return .success
154162
}
155163

@@ -185,7 +193,7 @@ private extension UnityProject {
185193
if statusCode == 0 {
186194
return .success
187195
} else {
188-
return .failure(UBKitError.shellCommand("Initializing Unity Project"))
196+
return .failure(UBKitError.shellCommand("Initializing Unity Project: \(statusCode)"))
189197
}
190198
case .timedOut:
191199
return .failure(UBKitError.waitTimedOut)

Sources/UBKit/Workers/XcodeProject.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class XcodeProject {
5454
}
5555

5656
func create() -> Result {
57+
print("iOS Project Path: \(workingPath)")
5758
let iOSFolderResult = createiOSFolder()
5859
guard iOSFolderResult == .success else {
5960
return iOSFolderResult

0 commit comments

Comments
 (0)