diff --git a/PBX Editor/PBXBuildFile.cs b/PBX Editor/PBXBuildFile.cs index d179177..01bc685 100755 --- a/PBX Editor/PBXBuildFile.cs +++ b/PBX Editor/PBXBuildFile.cs @@ -12,16 +12,11 @@ public class PBXBuildFile : PBXObject private const string WEAK_VALUE = "Weak"; private const string COMPILER_FLAGS_KEY = "COMPILER_FLAGS"; - public PBXBuildFile( PBXFileReference fileRef, bool weak = false ) : base() + public PBXBuildFile( PBXFileReference fileRef, bool weak = false, string[] compilerFlags = null ) : base() { this.Add( FILE_REF_KEY, fileRef.guid ); SetWeakLink( weak ); - - if (!string.IsNullOrEmpty(fileRef.compilerFlags)) - { - foreach (var flag in fileRef.compilerFlags.Split(',')) - AddCompilerFlag(flag); - } + AddCompilerFlags(compilerFlags); } public PBXBuildFile( string guid, PBXDictionary dictionary ) : base ( guid, dictionary ) @@ -68,16 +63,11 @@ public bool SetWeakLink( bool weak = false ) else { attributes = settings[ ATTRIBUTES_KEY ] as PBXList; } - + + attributes.Remove( WEAK_VALUE ); if( weak ) { attributes.Add( WEAK_VALUE ); } - else { - attributes.Remove( WEAK_VALUE ); - } - - settings.Add( ATTRIBUTES_KEY, attributes ); - this.Add( SETTINGS_KEY, settings ); return true; } @@ -104,23 +94,35 @@ public bool AddCodeSignOnCopy() } - public bool AddCompilerFlag( string flag ) + public bool AddCompilerFlags( params string[] flags ) { - if( !_data.ContainsKey( SETTINGS_KEY ) ) - _data[ SETTINGS_KEY ] = new PBXDictionary(); - - if( !((PBXDictionary)_data[ SETTINGS_KEY ]).ContainsKey( COMPILER_FLAGS_KEY ) ) { - ((PBXDictionary)_data[ SETTINGS_KEY ]).Add( COMPILER_FLAGS_KEY, flag ); - return true; - } + if( flags == null || flags.Length == 0) + return false; + + object settingsObject; + PBXDictionary settings; + + if( !_data.TryGetValue( SETTINGS_KEY, out settingsObject ) ) { + settings = new PBXDictionary(); + _data[ SETTINGS_KEY ] = settings; + } else + settings = settingsObject as PBXDictionary; - string[] flags = ((string)((PBXDictionary)_data[ SETTINGS_KEY ])[ COMPILER_FLAGS_KEY ]).Split( ' ' ); - foreach( string item in flags ) { - if( item.CompareTo( flag ) == 0 ) - return false; + List currentFlags = null; + if( settings.ContainsKey( COMPILER_FLAGS_KEY ) ) { + // merge specified with existing + currentFlags = new List(((string)settings[ COMPILER_FLAGS_KEY ]).Split( ' ' )); + + foreach( string flag in flags ) { + if( !currentFlags.Contains(flag) ) + currentFlags.Add(flag); + } + } else { + // no current flags so just use ones specified + currentFlags = new List(flags); } - - ((PBXDictionary)_data[ SETTINGS_KEY ])[ COMPILER_FLAGS_KEY ] = ( string.Join( " ", flags ) + " " + flag ); + + settings[ COMPILER_FLAGS_KEY ] = string.Join( " ", currentFlags.ToArray() ); return true; } diff --git a/PBX Editor/PBXFileReference.cs b/PBX Editor/PBXFileReference.cs index bed31f2..1154113 100755 --- a/PBX Editor/PBXFileReference.cs +++ b/PBX Editor/PBXFileReference.cs @@ -13,7 +13,6 @@ public class PBXFileReference : PBXObject protected const string LASTKNOWN_FILE_TYPE_KEY = "lastKnownFileType"; protected const string ENCODING_KEY = "fileEncoding"; - public string compilerFlags; public string buildPhase; public readonly Dictionary trees = new Dictionary { { TreeEnum.ABSOLUTE, "" }, diff --git a/PBX Editor/PBXParser.cs b/PBX Editor/PBXParser.cs index 9e1b185..b8e1e03 100755 --- a/PBX Editor/PBXParser.cs +++ b/PBX Editor/PBXParser.cs @@ -607,9 +607,8 @@ private bool SerializeString( string aString, StringBuilder builder, bool useQuo return true; } - // FIX ME: Original regexp was: @"^[A-Za-z0-9_.]+$", we use modified regexp with '/-' allowed - // to workaround Unity bug when all PNGs had "Libraries/" (group name) added to their paths after append - if( !Regex.IsMatch( aString, @"^[A-Za-z0-9_./-]+$" ) ) { + // Escape any string values that don't match the following + if( !Regex.IsMatch( aString, @"^[A-Za-z0-9_./]+$" ) ) { useQuotes = true; } diff --git a/XCProject.cs b/XCProject.cs index 9ca81be..b671062 100755 --- a/XCProject.cs +++ b/XCProject.cs @@ -2,6 +2,7 @@ using UnityEditor; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.IO; using System.Text.RegularExpressions; @@ -334,7 +335,7 @@ public object GetObject( string guid ) return _objects[guid]; } - public PBXDictionary AddFile( string filePath, PBXGroup parent = null, string tree = "SOURCE_ROOT", bool createBuildFiles = true, bool weak = false ) + public PBXDictionary AddFile( string filePath, PBXGroup parent = null, string tree = "SOURCE_ROOT", bool createBuildFiles = true, bool weak = false, params string[] compilerFlags ) { //Debug.Log("AddFile " + filePath + ", " + parent + ", " + tree + ", " + (createBuildFiles? "TRUE":"FALSE") + ", " + (weak? "TRUE":"FALSE") ); @@ -376,22 +377,34 @@ public PBXDictionary AddFile( string filePath, PBXGroup parent = null, string tr //Check if there is already a file PBXFileReference fileReference = GetFile( System.IO.Path.GetFileName( filePath ) ); if( fileReference != null ) { - Debug.Log("File already exists: " + filePath); //not a warning, because this is normal for most builds! - return null; + PBXFileReference newFileReference = new PBXFileReference( filePath, (TreeEnum)System.Enum.Parse( typeof(TreeEnum), tree ) ); + + // Check the incoming file wants to be part of a build phase, existing one could be empty + if (fileReference.buildPhase != newFileReference.buildPhase) { + Debug.Log("File build phase has changed adding: " + filePath); + fileReference.buildPhase = newFileReference.buildPhase; + } else if(compilerFlags != null && compilerFlags.Length > 0) { + // Need to modify build files that references this file to add compiler flags + } else { + Debug.Log("File already exists: " + filePath); //not a warning, because this is normal for most builds! + return null; + } } - - fileReference = new PBXFileReference( filePath, (TreeEnum)System.Enum.Parse( typeof(TreeEnum), tree ) ); - parent.AddChild( fileReference ); - fileReferences.Add( fileReference ); - results.Add( fileReference.guid, fileReference ); - + else + { + fileReference = new PBXFileReference( filePath, (TreeEnum)System.Enum.Parse( typeof(TreeEnum), tree ) ); + parent.AddChild( fileReference ); + fileReferences.Add( fileReference ); + results.Add( fileReference.guid, fileReference ); + } + //Create a build file for reference if( !string.IsNullOrEmpty( fileReference.buildPhase ) && createBuildFiles ) { switch( fileReference.buildPhase ) { case "PBXFrameworksBuildPhase": foreach( KeyValuePair currentObject in frameworkBuildPhases ) { - BuildAddFile(fileReference,currentObject,weak); + BuildAddFile(fileReference,currentObject,weak,compilerFlags); } if ( !string.IsNullOrEmpty( absPath ) && ( tree.CompareTo( "SOURCE_ROOT" ) == 0 )) { string libraryPath = Path.Combine( "$(SRCROOT)", Path.GetDirectoryName( filePath ) ); @@ -406,25 +419,25 @@ public PBXDictionary AddFile( string filePath, PBXGroup parent = null, string tr case "PBXResourcesBuildPhase": foreach( KeyValuePair currentObject in resourcesBuildPhases ) { Debug.Log( "Adding Resources Build File" ); - BuildAddFile(fileReference,currentObject,weak); + BuildAddFile(fileReference,currentObject,weak,compilerFlags); } break; case "PBXShellScriptBuildPhase": foreach( KeyValuePair currentObject in shellScriptBuildPhases ) { Debug.Log( "Adding Script Build File" ); - BuildAddFile(fileReference,currentObject,weak); + BuildAddFile(fileReference,currentObject,weak,compilerFlags); } break; case "PBXSourcesBuildPhase": foreach( KeyValuePair currentObject in sourcesBuildPhases ) { Debug.Log( "Adding Source Build File" ); - BuildAddFile(fileReference,currentObject,weak); + BuildAddFile(fileReference,currentObject,weak,compilerFlags); } break; case "PBXCopyFilesBuildPhase": foreach( KeyValuePair currentObject in copyBuildPhases ) { Debug.Log( "Adding Copy Files Build Phase" ); - BuildAddFile(fileReference,currentObject,weak); + BuildAddFile(fileReference,currentObject,weak,compilerFlags); } break; case null: @@ -519,35 +532,20 @@ public void AddEmbedFramework( string fileName) embedPhase.AddBuildFile(buildFile); } - private void BuildAddFile (PBXFileReference fileReference, KeyValuePair currentObject,bool weak) - { - PBXBuildFile buildFile = new PBXBuildFile( fileReference, weak ); - buildFiles.Add( buildFile ); - currentObject.Value.AddBuildFile( buildFile ); - } - private void BuildAddFile (PBXFileReference fileReference, KeyValuePair currentObject,bool weak) - { - PBXBuildFile buildFile = new PBXBuildFile( fileReference, weak ); - buildFiles.Add( buildFile ); - currentObject.Value.AddBuildFile( buildFile ); - } - private void BuildAddFile (PBXFileReference fileReference, KeyValuePair currentObject,bool weak) - { - PBXBuildFile buildFile = new PBXBuildFile( fileReference, weak ); - buildFiles.Add( buildFile ); - currentObject.Value.AddBuildFile( buildFile ); - } - private void BuildAddFile (PBXFileReference fileReference, KeyValuePair currentObject,bool weak) - { - PBXBuildFile buildFile = new PBXBuildFile( fileReference, weak ); - buildFiles.Add( buildFile ); - currentObject.Value.AddBuildFile( buildFile ); - } - private void BuildAddFile (PBXFileReference fileReference, KeyValuePair currentObject,bool weak) + private void BuildAddFile(PBXFileReference fileReference, KeyValuePair currentObject,bool weak, string[] compilerFlags) where T : PBXBuildPhase { - PBXBuildFile buildFile = new PBXBuildFile( fileReference, weak ); - buildFiles.Add( buildFile ); - currentObject.Value.AddBuildFile( buildFile ); + PBXBuildFile buildFile = buildFiles.Values.Where(x => x.fileRef == fileReference.guid).FirstOrDefault(); + + if (buildFile == null) { + buildFile = new PBXBuildFile( fileReference, weak, compilerFlags ); + buildFiles.Add( buildFile ); + } else { + buildFile.SetWeakLink(weak); + buildFile.AddCompilerFlags(compilerFlags); + } + + if (!currentObject.Value.HasBuildFile(buildFile.guid)) + currentObject.Value.AddBuildFile( buildFile ); } public bool AddFolder( string folderPath, PBXGroup parent = null, string[] exclude = null, bool recursive = true, bool createBuildFile = true ) @@ -678,9 +676,11 @@ public PBXGroup GetGroup( string name, string path = null, PBXGroup parent = nul foreach( KeyValuePair current in groups ) { if( string.IsNullOrEmpty( current.Value.name ) ) { - if( current.Value.path.CompareTo( name ) == 0 && parent.HasChild( current.Key ) ) { - return current.Value; - } + if( !string.IsNullOrEmpty( current.Value.path ) ) { + if( current.Value.path.CompareTo( name ) == 0 && parent.HasChild( current.Key ) ) { + return current.Value; + } + } } else if( current.Value.name.CompareTo( name ) == 0 && parent.HasChild( current.Key ) ) { return current.Value; } @@ -709,71 +709,92 @@ public void ApplyMod( string pbxmod ) public void ApplyMod( XCMod mod ) { PBXGroup modGroup = this.GetGroup( mod.group ); - - Debug.Log( "Adding libraries..." ); - - foreach( XCModFile libRef in mod.libs ) { - string completeLibPath = System.IO.Path.Combine( "usr/lib", libRef.filePath ); - Debug.Log ("Adding library " + completeLibPath); - this.AddFile( completeLibPath, modGroup, "SDKROOT", true, libRef.isWeak ); + + if (mod.libs != null) { + Debug.Log( "Adding libraries..." ); + + foreach( XCModFile libRef in mod.libs ) { + string completeLibPath = System.IO.Path.Combine( "usr/lib", libRef.filePath ); + Debug.Log ("Adding library " + completeLibPath); + this.AddFile( completeLibPath, modGroup, "SDKROOT", true, libRef.isWeak ); + } } - - Debug.Log( "Adding frameworks..." ); - PBXGroup frameworkGroup = this.GetGroup( "Frameworks" ); - foreach( string framework in mod.frameworks ) { - string[] filename = framework.Split( ':' ); - bool isWeak = ( filename.Length > 1 ) ? true : false; - string completePath = System.IO.Path.Combine( "System/Library/Frameworks", filename[0] ); - this.AddFile( completePath, frameworkGroup, "SDKROOT", true, isWeak ); + + if (mod.frameworks != null) { + Debug.Log( "Adding frameworks..." ); + PBXGroup frameworkGroup = this.GetGroup( "Frameworks" ); + foreach( string framework in mod.frameworks ) { + string[] filename = framework.Split( ':' ); + bool isWeak = ( filename.Length > 1 ) ? true : false; + string completePath = System.IO.Path.Combine( "System/Library/Frameworks", filename[0] ); + this.AddFile( completePath, frameworkGroup, "SDKROOT", true, isWeak ); + } } - Debug.Log( "Adding files..." ); - foreach( string filePath in mod.files ) { - string absoluteFilePath = System.IO.Path.Combine( mod.path, filePath ); - this.AddFile( absoluteFilePath, modGroup ); + if (mod.files != null) { + Debug.Log( "Adding files..." ); + foreach( string filePath in mod.files ) { + string[] filename = filePath.Split( ':' ); + string[] compileFlags = null; + if (filename.Length > 1) + compileFlags = filename[1].Split(','); + string absoluteFilePath = System.IO.Path.Combine( mod.path, filename[0] ); + this.AddFile( absoluteFilePath, modGroup, "SOURCE_ROOT", true, false, compileFlags ); + } } - Debug.Log( "Adding embed binaries..." ); - if (mod.embed_binaries != null) - { - //1. Add LD_RUNPATH_SEARCH_PATHS for embed framework - this.overwriteBuildSetting("LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks", "Release"); - this.overwriteBuildSetting("LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks", "Debug"); + if (mod.embed_binaries != null) { + Debug.Log( "Adding embed binaries..." ); + if (mod.embed_binaries != null) + { + //1. Add LD_RUNPATH_SEARCH_PATHS for embed framework + this.overwriteBuildSetting("LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks", "Release"); + this.overwriteBuildSetting("LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks", "Debug"); - foreach( string binary in mod.embed_binaries ) { - string absoluteFilePath = System.IO.Path.Combine( mod.path, binary ); - this.AddEmbedFramework(absoluteFilePath); + foreach( string binary in mod.embed_binaries ) { + string absoluteFilePath = System.IO.Path.Combine( mod.path, binary ); + this.AddEmbedFramework(absoluteFilePath); + } } } - - Debug.Log( "Adding folders..." ); - foreach( string folderPath in mod.folders ) { - string absoluteFolderPath = System.IO.Path.Combine( Application.dataPath, folderPath ); - Debug.Log ("Adding folder " + absoluteFolderPath); - this.AddFolder( absoluteFolderPath, modGroup, (string[])mod.excludes.ToArray( typeof(string) ) ); + + if (mod.folders != null) { + Debug.Log( "Adding folders..." ); + foreach( string folderPath in mod.folders ) { + string absoluteFolderPath = System.IO.Path.Combine( Application.dataPath, folderPath ); + Debug.Log ("Adding folder " + absoluteFolderPath); + this.AddFolder( absoluteFolderPath, modGroup, (string[])mod.excludes.ToArray( typeof(string) ) ); + } } - - Debug.Log( "Adding headerpaths..." ); - foreach( string headerpath in mod.headerpaths ) { - if (headerpath.Contains("$(inherited)")) { - Debug.Log ("not prepending a path to " + headerpath); - this.AddHeaderSearchPaths( headerpath ); - } else { - string absoluteHeaderPath = System.IO.Path.Combine( mod.path, headerpath ); - this.AddHeaderSearchPaths( absoluteHeaderPath ); + + if (mod.headerpaths != null) { + Debug.Log( "Adding headerpaths..." ); + foreach( string headerpath in mod.headerpaths ) { + if (headerpath.Contains("$(inherited)")) { + Debug.Log ("not prepending a path to " + headerpath); + this.AddHeaderSearchPaths( headerpath ); + } else { + string absoluteHeaderPath = System.IO.Path.Combine( mod.path, headerpath ); + this.AddHeaderSearchPaths( absoluteHeaderPath ); + } } } - Debug.Log( "Adding compiler flags..." ); - foreach( string flag in mod.compiler_flags ) { - this.AddOtherCFlags( flag ); + if (mod.compiler_flags != null) { + Debug.Log( "Adding compiler flags..." ); + foreach( string flag in mod.compiler_flags ) { + this.AddOtherCFlags( flag ); + } } - Debug.Log( "Adding linker flags..." ); - foreach( string flag in mod.linker_flags ) { - this.AddOtherLinkerFlags( flag ); + if (mod.linker_flags != null) { + Debug.Log( "Adding linker flags..." ); + foreach( string flag in mod.linker_flags ) { + this.AddOtherLinkerFlags( flag ); + } } + this.Consolidate(); } diff --git a/XCodePostProcess.cs b/XCodePostProcess.cs index f962014..1403a7f 100755 --- a/XCodePostProcess.cs +++ b/XCodePostProcess.cs @@ -13,8 +13,11 @@ public static class XCodePostProcess [PostProcessBuild(999)] public static void OnPostProcessBuild( BuildTarget target, string pathToBuiltProject ) { - if (target != BuildTarget.iPhone) { - Debug.LogWarning("Target is not iPhone. XCodePostProcess will not run"); +#if UNITY_5 + if (target != BuildTarget.iOS) { +#else + if (target != BuildTarget.iPhone) { +#endif return; }