diff --git a/Makefile b/Makefile index baad4d8..3b14ea6 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ TOOL_NAME = UnityBuildKit -VERSION = 1.1.1 +VERSION = 1.1.2 PREFIX = /usr/local INSTALL_PATH = $(PREFIX)/bin/$(TOOL_NAME) diff --git a/README.md b/README.md index f5aa855..af357b6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
-
+
@@ -44,12 +44,12 @@ mkdir ExampleProject
cd ExampleProject
```
-2. Run the following to generate the `ubconfig.json` file where you can specify project information
+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))
```
UnityBuildKit config
```
-3. After filling out the config file information, run
+3. After filling out the config file, run
```
$ UnityBuildKit generate
```
diff --git a/Sources/UBKit/Files/Config/configFile.swift b/Sources/UBKit/Files/Config/configFile.swift
index 413bbba..679ce7e 100644
--- a/Sources/UBKit/Files/Config/configFile.swift
+++ b/Sources/UBKit/Files/Config/configFile.swift
@@ -31,13 +31,13 @@ extension File {
"ios": {
"projectName": "ExampleProject",
"bundleId": "com.example.ExampleProject",
- "projectPath": "" // Defaults to iOS/
+ "projectPath": "" // e.g. iOS/
},
"unity": {
"projectName": "ExampleProject",
- "applicationPath": "", // e.g /Applications/Unity/Unity.app/Contents/MacOS/Unity
- "version": "", // e.g. 2017.1.f1
- "projectPath": "", // Defaults to Unity/
+ "applicationPath": "", // e.g. /Applications/Unity/Unity.app/Contents/MacOS/Unity
+ "version": "", // e.g. 2017.2.1.f1
+ "projectPath": "", // e.g. Unity/
"sceneNames": [
"ExampleScene"
]
diff --git a/Sources/UBKit/Files/Unity/UnityFrameworksScript.swift b/Sources/UBKit/Files/Unity/UnityFrameworksScript.swift
new file mode 100644
index 0000000..227dfd3
--- /dev/null
+++ b/Sources/UBKit/Files/Unity/UnityFrameworksScript.swift
@@ -0,0 +1,72 @@
+//
+// UnityProjectScript.swift
+// UnityBuildKitPackageDescription
+//
+// Copyright (c) 2017 Handsome
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+import Foundation
+
+extension File {
+
+ class func unityFrameworksScriptFile(projectName: String, iOSProjectPath: String) -> Data? {
+ let file = """
+ using System.Collections;
+ using System.IO;
+ using UnityEngine;
+ using UnityEditor;
+ using UnityEditor.SceneManagement;
+ using UnityEngine.SceneManagement;
+ using UnityEditor.iOS.Xcode;
+
+ public class XcodeFrameworks: MonoBehaviour {
+
+ private const string iOSProjectRoot = \"\(iOSProjectPath)\";
+ private const string iOSProjectName = \"\(projectName)\";
+ private const string PbxFilePath = iOSProjectName + ".xcodeproj/project.pbxproj";
+
+ public static void Perform () {
+ var pbx = new PBXProject();
+ var pbxPath = Path.Combine(iOSProjectRoot, PbxFilePath);
+ pbx.ReadFromFile(pbxPath);
+
+ var targetGuid = pbx.TargetGuidByName(iOSProjectName);
+ pbx.AddFrameworkToProject(targetGuid, "GameKit.framework", true);
+ pbx.AddFrameworkToProject(targetGuid, "CoreGraphics.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "AVFoundation.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "CoreVideo.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "CoreMedia.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "SystemConfiguration.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "CoreLocation.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "MediaPlayer.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "CFNetwork.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "AudioToolbox.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "OpenAL.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "QuartzCore.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "Foundation.framework", false);
+ pbx.AddFrameworkToProject(targetGuid, "MediaToolbox.framework", false);
+
+ pbx.WriteToFile(pbxPath);
+ }
+ }
+ """.data(using: .utf8)
+ return file
+ }
+}
diff --git a/Sources/UBKit/Files/Xcode/SpecFile.swift b/Sources/UBKit/Files/Xcode/SpecFile.swift
index b86df0d..d337ea2 100644
--- a/Sources/UBKit/Files/Xcode/SpecFile.swift
+++ b/Sources/UBKit/Files/Xcode/SpecFile.swift
@@ -51,7 +51,7 @@ extension File {
UNITY_SCRIPTING_BACKEND: il2cpp
UNITY_IOS_EXPORT_PATH: ${SRCROOT}/../Unity/\(projectName)/ios_build
GCC_PREFIX_HEADER: $(UNITY_IOS_EXPORT_PATH)/Classes/Prefix.pch
- 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
+ OTHER_LDFLAGS: -weak-lSystem -liconv.2 -liPhone-lib -weak_framework CoreMotion -weak_framework iAd -framework OpenGLES
HEADER_SEARCH_PATHS: $(UNITY_IOS_EXPORT_PATH)/Classes $(UNITY_IOS_EXPORT_PATH)/Classes/Native $(UNITY_IOS_EXPORT_PATH)/Libraries/libil2cpp/include
LIBRARY_SEARCH_PATHS: $(UNITY_IOS_EXPORT_PATH)/Libraries $(UNITY_IOS_EXPORT_PATH)/Libraries/libil2cpp/include
ENABLE_BITCODE: NO
diff --git a/Sources/UBKit/Models/Config.swift b/Sources/UBKit/Models/Config.swift
index a2d5161..3051534 100644
--- a/Sources/UBKit/Models/Config.swift
+++ b/Sources/UBKit/Models/Config.swift
@@ -64,10 +64,18 @@ struct iOSConfig: Decodable {
}
let projectPath: String
- if let path = try? container.decode(String.self, forKey: .projectPath), !path.isEmpty {
- projectPath = path
- } else {
- projectPath = FileManager.default.currentDirectoryPath.appending("/iOS/")
+ do {
+ let path = try container.decode(String.self, forKey: .projectPath)
+ if path.isEmpty {
+ throw UBKitError.invalidConfigArgument(Keys.projectPath.rawValue)
+ }
+ projectPath = FileManager.default.currentDirectoryPath.appending("/").appending(path)
+ } catch {
+ throw UBKitError.invalidConfigArgument(Keys.projectPath.rawValue)
+ }
+
+ if !projectPath.hasSuffix("/") {
+ throw UBKitError.invalidConfigArgument("Project Path must end with a \"/\"")
}
self.projectName = projectName
@@ -113,10 +121,18 @@ struct UnityConfig {
}
let projectPath: String
- if let path = try? container.decode(String.self, forKey: .projectPath), !path.isEmpty {
- projectPath = path
- } else {
- projectPath = FileManager.default.currentDirectoryPath.appending("/Unity/")
+ do {
+ let path = try container.decode(String.self, forKey: .projectPath)
+ if path.isEmpty {
+ throw UBKitError.invalidConfigArgument(Keys.projectPath.rawValue)
+ }
+ projectPath = FileManager.default.currentDirectoryPath.appending("/").appending(path)
+ } catch {
+ throw UBKitError.invalidConfigArgument(Keys.projectPath.rawValue)
+ }
+
+ if !projectPath.hasSuffix("/") {
+ throw UBKitError.invalidConfigArgument("Project Path must end with a \"/\"")
}
let sceneNames = try container.decode([String].self, forKey: .sceneNames)
diff --git a/Sources/UBKit/Models/UnityCommandLine.swift b/Sources/UBKit/Models/UnityCommandLine.swift
index b20bfd7..76a867f 100644
--- a/Sources/UBKit/Models/UnityCommandLine.swift
+++ b/Sources/UBKit/Models/UnityCommandLine.swift
@@ -29,6 +29,7 @@ import Foundation
struct UnityCommandLine {
static let buildAction = "iOSBuilder.Perform"
static let refreshAction = "XcodeRefresher.Refresh"
+ static let frameworksAction = "XcodeFrameworks.Perform"
struct Arguments {
static let projectPath = "-projectPath"
diff --git a/Sources/UBKit/Workers/FileCopier.swift b/Sources/UBKit/Workers/FileCopier.swift
index 8c8187b..51cbc6c 100644
--- a/Sources/UBKit/Workers/FileCopier.swift
+++ b/Sources/UBKit/Workers/FileCopier.swift
@@ -80,6 +80,11 @@ class FileCopier {
return unityFilesResult
}
+ let addFrameworksResult = addXcodeFrameworks()
+ guard addFrameworksResult == .success else {
+ return addFrameworksResult
+ }
+
return .success
}
}
@@ -113,25 +118,6 @@ private extension FileCopier {
return .success
}
- func x() -> Result {
- guard let project = project else {
- return .failure(UBKitError.invalidXcodeProject("Failed to find project file"))
- }
-
- guard let mainTarget = project.pbxproj.objects.nativeTargets.filter({ $0.value.name == config.iOS.projectName }).first else {
- return .failure(UBKitError.invalidXcodeProject("Missing main target"))
- }
-
- for phase in mainTarget.value.buildPhases {
- if phase.starts(with: "RBP_") {
-
- break
- }
- }
-
- return .success
- }
-
func changeUnityFiles() -> Result {
let mainFilePath = workingPath.appending(config.unity.projectName).appending("/ios_build/Classes/main.mm")
guard fileManager.fileExists(atPath: mainFilePath) else {
@@ -165,12 +151,13 @@ private extension FileCopier {
func addUnityFiles() -> Result {
let semaphore = DispatchSemaphore(value: 0)
var statusCode: Int32 = 999
+ let projectPath = workingPath.appending(config.unity.projectName).appending("/ios_build")
shell.perform(
config.unity.applicationPath,
UnityCommandLine.Arguments.batchmode,
UnityCommandLine.Arguments.buildPath,
- workingPath.appending(config.unity.projectName).appending("/ios_build"),
+ projectPath,
UnityCommandLine.Arguments.executeMethod,
UnityCommandLine.refreshAction,
UnityCommandLine.Arguments.quit,
@@ -192,6 +179,37 @@ private extension FileCopier {
}
}
+ func addXcodeFrameworks() -> Result {
+ let semaphore = DispatchSemaphore(value: 0)
+ var statusCode: Int32 = 999
+ let projectPath = workingPath.appending(config.unity.projectName)
+
+ shell.perform(
+ config.unity.applicationPath,
+ UnityCommandLine.Arguments.batchmode,
+ UnityCommandLine.Arguments.projectPath,
+ projectPath,
+ UnityCommandLine.Arguments.executeMethod,
+ UnityCommandLine.frameworksAction,
+ UnityCommandLine.Arguments.quit,
+ terminationHandler: { (process) in
+ statusCode = process.terminationStatus
+ semaphore.signal()
+ })
+
+ let timeout = semaphore.wait(timeout: DispatchTime.now()+60.0)
+ switch timeout {
+ case .success:
+ if statusCode == 0 {
+ return .success
+ } else {
+ return .failure(UBKitError.shellCommand("Initializing Unity Project"))
+ }
+ case .timedOut:
+ return .failure(UBKitError.waitTimedOut)
+ }
+ }
+
func saveProject() -> Result {
guard let project = project else {
return .failure(UBKitError.invalidXcodeProject("Failed to find project file"))
diff --git a/Sources/UBKit/Workers/UnityProject.swift b/Sources/UBKit/Workers/UnityProject.swift
index e6d6d29..e41abbb 100644
--- a/Sources/UBKit/Workers/UnityProject.swift
+++ b/Sources/UBKit/Workers/UnityProject.swift
@@ -47,6 +47,7 @@ class UnityProject {
return .failure(UBKitError.invalidFolder(unityAppPath))
}
+ print("Unity Project Path: \(workingPath)\n")
let unityFolderResult = createUnityFolder()
guard unityFolderResult == .success else {
return unityFolderResult
@@ -59,7 +60,7 @@ class UnityProject {
return projectGenerationResult
}
- print("\nGenerating Unity Editor scripts")
+ print("Generating Unity Editor scripts")
let editorScriptsResult = createUnityEditorScripts()
guard editorScriptsResult == .success else {
return editorScriptsResult
@@ -144,12 +145,19 @@ private extension UnityProject {
}
guard fileManager.createFile(
- atPath: editorFilePath.appending("ProjectScript.cs"),
+ atPath: editorFilePath.appending("XcodeProjectRefresher.cs"),
contents: File.unityProjectScriptFile(projectName: projectName, iOSProjectPath: config.iOS.projectPath),
attributes: nil) else {
return .failure(UBKitError.unableToCreateFile("Unity Project Script"))
}
+ guard fileManager.createFile(
+ atPath: editorFilePath.appending("XcodeFrameworks.cs"),
+ contents: File.unityFrameworksScriptFile(projectName: projectName, iOSProjectPath: config.iOS.projectPath),
+ attributes: nil) else {
+ return .failure(UBKitError.unableToCreateFile("Xcode Frameworks Script"))
+ }
+
return .success
}
@@ -185,7 +193,7 @@ private extension UnityProject {
if statusCode == 0 {
return .success
} else {
- return .failure(UBKitError.shellCommand("Initializing Unity Project"))
+ return .failure(UBKitError.shellCommand("Initializing Unity Project: \(statusCode)"))
}
case .timedOut:
return .failure(UBKitError.waitTimedOut)
diff --git a/Sources/UBKit/Workers/XcodeProject.swift b/Sources/UBKit/Workers/XcodeProject.swift
index d201ccf..96efbc5 100644
--- a/Sources/UBKit/Workers/XcodeProject.swift
+++ b/Sources/UBKit/Workers/XcodeProject.swift
@@ -54,6 +54,7 @@ class XcodeProject {
}
func create() -> Result {
+ print("iOS Project Path: \(workingPath)")
let iOSFolderResult = createiOSFolder()
guard iOSFolderResult == .success else {
return iOSFolderResult
diff --git a/UnityBuildKit.xcodeproj/project.pbxproj b/UnityBuildKit.xcodeproj/project.pbxproj
index 8b94e02..015a8e9 100644
--- a/UnityBuildKit.xcodeproj/project.pbxproj
+++ b/UnityBuildKit.xcodeproj/project.pbxproj
@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
+ D4C15EC42023E6C3002B8938 /* UnityFrameworksScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4C15EC32023E6C3002B8938 /* UnityFrameworksScript.swift */; };
+ D4C15EC52023E6C3002B8938 /* UnityFrameworksScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4C15EC32023E6C3002B8938 /* UnityFrameworksScript.swift */; };
OBJ_204 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; };
OBJ_210 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_78 /* Package.swift */; };
OBJ_216 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_134 /* Package.swift */; };
@@ -428,6 +430,7 @@
/* Begin PBXFileReference section */
"AEXML::AEXML::Product" /* AEXML.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AEXML.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ D4C15EC32023E6C3002B8938 /* UnityFrameworksScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnityFrameworksScript.swift; sourceTree = "