Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
TOOL_NAME = UnityBuildKit
VERSION = 1.1.1
VERSION = 1.1.2

PREFIX = /usr/local
INSTALL_PATH = $(PREFIX)/bin/$(TOOL_NAME)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img src="Assets/ubk_logo.png">
</p>
<p align="center">
<img src="https://img.shields.io/badge/version-1.1.1-blue.svg?style=flat-square" />
<img src="https://img.shields.io/badge/version-1.1.2-blue.svg?style=flat-square" />
<a href="https://github.com/handsomecode/UnityBuildKit/blob/master/LICENSE">
<img src="https://img.shields.io/github/license/mashape/apistatus.svg?style=flat-square"/>
</a>
Expand Down Expand Up @@ -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
```
Expand Down
8 changes: 4 additions & 4 deletions Sources/UBKit/Files/Config/configFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
Expand Down
72 changes: 72 additions & 0 deletions Sources/UBKit/Files/Unity/UnityFrameworksScript.swift
Original file line number Diff line number Diff line change
@@ -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
}
}
2 changes: 1 addition & 1 deletion Sources/UBKit/Files/Xcode/SpecFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 24 additions & 8 deletions Sources/UBKit/Models/Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions Sources/UBKit/Models/UnityCommandLine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
58 changes: 38 additions & 20 deletions Sources/UBKit/Workers/FileCopier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ class FileCopier {
return unityFilesResult
}

let addFrameworksResult = addXcodeFrameworks()
guard addFrameworksResult == .success else {
return addFrameworksResult
}

return .success
}
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand All @@ -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"))
Expand Down
14 changes: 11 additions & 3 deletions Sources/UBKit/Workers/UnityProject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions Sources/UBKit/Workers/XcodeProject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class XcodeProject {
}

func create() -> Result {
print("iOS Project Path: \(workingPath)")
let iOSFolderResult = createiOSFolder()
guard iOSFolderResult == .success else {
return iOSFolderResult
Expand Down
6 changes: 6 additions & 0 deletions UnityBuildKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -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 = "<group>"; };
"JSONUtilities::JSONUtilities::Product" /* JSONUtilities.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = JSONUtilities.framework; sourceTree = BUILT_PRODUCTS_DIR; };
OBJ_100 /* PBXHeadersBuildPhase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PBXHeadersBuildPhase.swift; sourceTree = "<group>"; };
OBJ_101 /* PBXLegacyTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PBXLegacyTarget.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -714,6 +717,7 @@
children = (
OBJ_14 /* UnityEditorBuildScript.swift */,
OBJ_15 /* UnityProjectScript.swift */,
D4C15EC32023E6C3002B8938 /* UnityFrameworksScript.swift */,
);
path = Unity;
sourceTree = "<group>";
Expand Down Expand Up @@ -1448,6 +1452,7 @@
buildActionMask = 0;
files = (
OBJ_204 /* Package.swift in Sources */,
D4C15EC42023E6C3002B8938 /* UnityFrameworksScript.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1526,6 +1531,7 @@
OBJ_291 /* SpecFile.swift in Sources */,
OBJ_292 /* ViewControllerFile.swift in Sources */,
OBJ_293 /* Config.swift in Sources */,
D4C15EC52023E6C3002B8938 /* UnityFrameworksScript.swift in Sources */,
OBJ_294 /* Result.swift in Sources */,
OBJ_295 /* Shell.swift in Sources */,
OBJ_296 /* UBKitError.swift in Sources */,
Expand Down