public XCProject( string filePath ) : this() { if( !Directory.Exists( filePath ) ) { Debug.LogWarning( "XCode project path does not exist: " + filePath ); return; } if( filePath.EndsWith( ".xcodeproj" ) ) { Debug.Log( "Opening project " + filePath ); this.projectRootPath = Path.GetDirectoryName( filePath ); this.filePath = filePath; } else { Debug.Log( "Looking for xcodeproj files in " + filePath ); string[] projects = Directory.GetDirectories( filePath, "*.xcodeproj" ); if( projects.Length == 0 ) { Debug.LogWarning( "Error: missing xcodeproj file" ); return; } this.projectRootPath = filePath; //if the path is relative to the project, we need to make it absolute if (!Path.IsPathRooted(projectRootPath)) projectRootPath = Application.dataPath.Replace("Assets", "") + projectRootPath; //Debug.Log ("projectRootPath adjusted to " + projectRootPath); this.filePath = projects[ 0 ]; } projectFileInfo = new FileInfo( Path.Combine( this.filePath, "project.pbxproj" ) ); string contents = projectFileInfo.OpenText().ReadToEnd(); PBXParser parser = new PBXParser(); _datastore = parser.Decode( contents ); if( _datastore == null ) { throw new System.Exception( "Project file not found at file path " + filePath ); } if( !_datastore.ContainsKey( "objects" ) ) { Debug.Log( "Errore " + _datastore.Count ); return; } _objects = (PBXDictionary)_datastore["objects"]; modified = false; _rootObjectKey = (string)_datastore["rootObject"]; if( !string.IsNullOrEmpty( _rootObjectKey ) ) { _project = new PBXProject( _rootObjectKey, (PBXDictionary)_objects[ _rootObjectKey ] ); _rootGroup = new PBXGroup( _rootObjectKey, (PBXDictionary)_objects[ _project.mainGroupID ] ); } else { Debug.LogWarning( "error: project has no root object" ); _project = null; _rootGroup = null; } }
// We support neither recursing into nor bundles contained inside loc folders public bool AddLocFolder( string folderPath, PBXGroup parent = null, string[] exclude = null, bool createBuildFile = true) { DirectoryInfo sourceDirectoryInfo = new DirectoryInfo( folderPath ); if( exclude == null ) exclude = new string[] {}; if( parent == null ) parent = rootGroup; // Create group as needed System.Uri projectFolderURI = new System.Uri( projectFileInfo.DirectoryName ); System.Uri locFolderURI = new System.Uri( folderPath ); var relativePath = projectFolderURI.MakeRelativeUri( locFolderURI ).ToString(); PBXGroup newGroup = GetGroup( sourceDirectoryInfo.Name, relativePath, parent ); // Add loc region to project string nom = sourceDirectoryInfo.Name; string region = nom.Substring(0, nom.Length - ".lproj".Length); project.AddRegion(region); // Adding files. string regexExclude = string.Format( @"{0}", string.Join( "|", exclude ) ); foreach( string file in Directory.GetFiles( folderPath ) ) { if( Regex.IsMatch( file, regexExclude ) ) { continue; } // Add a variant group for the language as well var variant = new PBXVariantGroup(Path.GetFileName( file ), null, "GROUP"); variantGroups.Add(variant); // The group gets a reference to the variant, not to the file itself newGroup.AddChild(variant); AddFile( file, variant, "GROUP", createBuildFile ); } modified = true; return modified; }
public PBXGroup GetGroup( string name, string path = null, PBXGroup parent = null ) { if( string.IsNullOrEmpty( name ) ) return null; if( parent == null ) parent = rootGroup; foreach( KeyValuePair<string, PBXGroup> current in groups ) { if( string.IsNullOrEmpty( current.Value.name ) ) { 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; } } PBXGroup result = new PBXGroup( name, path ); groups.Add( result ); parent.AddChild( result ); modified = true; return result; }
public PBXDictionary AddFile( string filePath, PBXGroup parent = null, string tree = "SOURCE_ROOT", bool createBuildFiles = true, bool weak = false, string compilerFlags = null) { //Debug.Log("AddFile " + filePath + ", " + parent + ", " + tree + ", " + (createBuildFiles? "TRUE":"FALSE") + ", " + (weak? "TRUE":"FALSE") ); PBXDictionary results = new PBXDictionary(); if (filePath == null) { Debug.LogError ("AddFile called with null filePath"); return results; } string absPath = string.Empty; if( Path.IsPathRooted( filePath ) ) { Debug.Log( "Path is Rooted" ); absPath = filePath; } else if( tree.CompareTo( "SDKROOT" ) != 0) { absPath = Path.Combine( Application.dataPath, filePath ); } if( !( File.Exists( absPath ) || Directory.Exists( absPath ) ) && tree.CompareTo( "SDKROOT" ) != 0 ) { Debug.Log( "Missing file: " + filePath ); return results; } else if( tree.CompareTo( "SOURCE_ROOT" ) == 0 ) { Debug.Log( "Source Root File" ); System.Uri fileURI = new System.Uri( absPath ); System.Uri rootURI = new System.Uri( ( projectRootPath + "/." ) ); filePath = rootURI.MakeRelativeUri( fileURI ).ToString(); } else if( tree.CompareTo("GROUP") == 0) { Debug.Log( "Group File" ); filePath = Path.GetFileName( filePath ); } if( parent == null ) { parent = _rootGroup; } //Check if there is already a file PBXFileReference fileReference = GetFile( Path.GetFileName( filePath ) ); if( fileReference != null ) { //Updating internal data with this call. fileReference.GuessFileType(); } else { fileReference = new PBXFileReference( filePath, (TreeEnum)System.Enum.Parse( typeof(TreeEnum), tree ) ); } // Adding compiler flag if (!string.IsNullOrEmpty(compilerFlags)) { fileReference.compilerFlags = compilerFlags; } 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<string, PBXFrameworksBuildPhase> currentObject in frameworkBuildPhases ) { BuildAddFile(fileReference,currentObject,weak); } if ( !string.IsNullOrEmpty( absPath ) && ( tree.CompareTo( "SOURCE_ROOT" ) == 0 )) { string libraryPath = Path.Combine( "$(SRCROOT)", Path.GetDirectoryName( filePath ) ); if (File.Exists(absPath)) { this.AddLibrarySearchPaths( new PBXList( libraryPath ) ); } else { this.AddFrameworkSearchPaths( new PBXList( libraryPath ) ); } } break; case "PBXResourcesBuildPhase": foreach( KeyValuePair<string, PBXResourcesBuildPhase> currentObject in resourcesBuildPhases ) { Debug.Log( "Adding Resources Build File" ); BuildAddFile(fileReference,currentObject,weak); } break; case "PBXShellScriptBuildPhase": foreach( KeyValuePair<string, PBXShellScriptBuildPhase> currentObject in shellScriptBuildPhases ) { Debug.Log( "Adding Script Build File" ); BuildAddFile(fileReference,currentObject,weak); } break; case "PBXSourcesBuildPhase": foreach( KeyValuePair<string, PBXSourcesBuildPhase> currentObject in sourcesBuildPhases ) { Debug.Log( "Adding Source Build File" ); BuildAddFile(fileReference,currentObject,weak); } break; case "PBXCopyFilesBuildPhase": foreach( KeyValuePair<string, PBXCopyFilesBuildPhase> currentObject in copyBuildPhases ) { Debug.Log( "Adding Copy Files Build Phase" ); BuildAddFile(fileReference,currentObject,weak); } break; case null: Debug.LogWarning( "File Not Supported: " + filePath ); break; default: Debug.LogWarning( "File Not Supported." ); return null; } } return results; }
public bool AddFolder( string folderPath, PBXGroup parent = null, string[] exclude = null, bool recursive = true, bool createBuildFile = true, string compilerFlags = null) { Debug.Log("Folder PATH: "+folderPath); if( !Directory.Exists( folderPath ) ){ Debug.Log("Directory doesn't exist?"); return false; } if (folderPath.EndsWith(".lproj")){ Debug.Log("Ended with .lproj"); return AddLocFolder(folderPath, parent, exclude, createBuildFile); } DirectoryInfo sourceDirectoryInfo = new DirectoryInfo( folderPath ); if( exclude == null ){ Debug.Log("Exclude was null"); exclude = new string[] {}; } if( parent == null ){ Debug.Log("Parent was null"); parent = rootGroup; } // Create group PBXGroup newGroup = GetGroup( sourceDirectoryInfo.Name, null /*relative path*/, parent ); Debug.Log("New Group created"); foreach( string directory in Directory.GetDirectories( folderPath ) ) { Debug.Log( "DIR: " + directory ); if( directory.EndsWith( ".bundle" ) ) { // Treat it like a file and copy even if not recursive // TODO also for .xcdatamodeld? Debug.LogWarning( "This is a special folder: " + directory ); AddFile( directory, newGroup, "SOURCE_ROOT", createBuildFile ); continue; } if( recursive ) { Debug.Log( "recursive" ); AddFolder( directory, newGroup, exclude, recursive, createBuildFile, compilerFlags:compilerFlags ); } } // Adding files. string regexExclude = string.Format( @"{0}", string.Join( "|", exclude ) ); foreach( string file in Directory.GetFiles( folderPath ) ) { if( Regex.IsMatch( file, regexExclude ) ) { continue; } Debug.Log("Adding Files for Folder"); AddFile( file, newGroup, "SOURCE_ROOT", createBuildFile, compilerFlags:compilerFlags); } modified = true; return modified; }
public string ResolveName(string guid) { if (!this.objects.ContainsKey(guid)) { Debug.LogWarning(this + " ResolveName could not resolve " + guid); return(string.Empty); //"UNRESOLVED GUID:" + guid; } object entity = this.objects[guid]; if (entity is PBXBuildFile) { return(ResolveName(((PBXBuildFile)entity).fileRef)); } else if (entity is PBXFileReference) { PBXFileReference casted = (PBXFileReference)entity; return(casted.name != null ? casted.name : casted.path); } else if (entity is PBXGroup) { PBXGroup casted = (PBXGroup)entity; return(casted.name != null ? casted.name : casted.path); } else if (entity is PBXProject || guid == this.rootObject) { return("Project object"); } else if (entity is PBXFrameworksBuildPhase) { return("Frameworks"); } else if (entity is PBXResourcesBuildPhase) { return("Resources"); } else if (entity is PBXShellScriptBuildPhase) { return("ShellScript"); } else if (entity is PBXSourcesBuildPhase) { return("Sources"); } else if (entity is PBXCopyFilesBuildPhase) { return("CopyFiles"); } else if (entity is XCConfigurationList) { XCConfigurationList casted = (XCConfigurationList)entity; //Debug.LogWarning ("XCConfigurationList " + guid + " " + casted.ToString()); if (casted.data.ContainsKey("defaultConfigurationName")) { //Debug.Log ("XCConfigurationList " + (string)casted.data[ "defaultConfigurationName" ] + " " + guid); return((string)casted.data["defaultConfigurationName"]); } return(null); } else if (entity is PBXNativeTarget) { PBXNativeTarget obj = (PBXNativeTarget)entity; //Debug.LogWarning ("PBXNativeTarget " + guid + " " + obj.ToString()); if (obj.data.ContainsKey("name")) { //Debug.Log ("PBXNativeTarget " + (string)obj.data[ "name" ] + " " + guid); return((string)obj.data["name"]); } return(null); } else if (entity is XCBuildConfiguration) { XCBuildConfiguration obj = (XCBuildConfiguration)entity; //Debug.LogWarning ("XCBuildConfiguration UNRESOLVED GUID:" + guid + " " + (obj==null?"":obj.ToString())); if (obj.data.ContainsKey("name")) { //Debug.Log ("XCBuildConfiguration " + (string)obj.data[ "name" ] + " " + guid + " " + (obj==null?"":obj.ToString())); return((string)obj.data["name"]); } } else if (entity is PBXObject) { PBXObject obj = (PBXObject)entity; if (obj.data.ContainsKey("name")) { Debug.Log("PBXObject " + (string)obj.data["name"] + " " + guid + " " + (obj == null?"":obj.ToString())); } return((string)obj.data["name"]); } //return "UNRESOLVED GUID:" + guid; Debug.LogWarning("UNRESOLVED GUID:" + guid); return(null); }
public void ApplyMod(XCMod mod) { PBXGroup modGroup = this.GetGroup(mod.group); #if !XCODE_PROJECT_USES_SOFT_LINKS string groupFolderPath = Path.Combine(Path.Combine(projectRootPath, "Plugins"), mod.group); #endif // Debug.Log( "Adding libraries..." ); foreach (XCModFile libRef in mod.libs) { string completeLibPath = 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 = Path.Combine("System/Library/Frameworks", filename[0]); this.AddFile(completePath, frameworkGroup, "SDKROOT", true, isWeak); } // Debug.Log ( "Adding files..." ); foreach (string file in mod.files) { string[] args = file.Split(':'); string fileRelativePath = args[0]; string compilerFlags = (args.Length > 1) ? args[1] : null; string fileAbsolutePath = Path.Combine(mod.path, fileRelativePath); #if XCODE_PROJECT_USES_SOFT_LINKS // Will create reference to this file this.AddFile(fileAbsolutePath, modGroup, compilerFlags: compilerFlags); #else // Create a hard copy of the file, placed at build folder string finalFileAbsolutePath = Path.Combine(groupFolderPath, fileRelativePath); if (File.Exists(fileAbsolutePath)) { CopyFileFrom(fileAbsolutePath, finalFileAbsolutePath); } else if (Directory.Exists(fileAbsolutePath)) { IOExtensions.CopyFilesRecursively(fileAbsolutePath, finalFileAbsolutePath, true); } else { continue; } // Now add this new copy to xcode project this.AddFile(finalFileAbsolutePath, modGroup, compilerFlags: compilerFlags); #endif } // Debug.Log ( "Adding folders..." ); foreach (string folder in mod.folders) { string[] args = folder.Split(':'); string folderRelativePath = args[0]; string compilerFlags = (args.Length > 1) ? args[1] : null; string folderAbsolutePath = Path.Combine(mod.path, folderRelativePath); #if XCODE_PROJECT_USES_SOFT_LINKS // Will create reference to this folder this.AddFolder(folderAbsolutePath, modGroup, (string[])mod.excludes.ToArray(typeof(string)), compilerFlags: compilerFlags); #else // Check if source folder exist if (!Directory.Exists(folderAbsolutePath)) { continue; } // Make a hard copy of this folder string finalFolderAbsolutePath = Path.Combine(groupFolderPath, folderRelativePath); IOExtensions.CopyFilesRecursively(folderAbsolutePath, finalFolderAbsolutePath, true); // Now add this new copy to xcode project this.AddFolder(finalFolderAbsolutePath, modGroup, (string[])mod.excludes.ToArray(typeof(string)), compilerFlags: compilerFlags); #endif } // Debug.Log( "Adding headerpaths..." ); foreach (string headerpath in mod.headerpaths) { string[] args = headerpath.Split(':'); bool recursive = args.Length > 1 ? args[1].Equals("recursive") : false; if (args[0].Contains("$(inherited)")) { // Debug.Log ("not prepending a path to " + args[0]); this.AddHeaderSearchPaths(args[0], recursive); } else { #if XCODE_PROJECT_USES_SOFT_LINKS string absoluteHeaderPath = Path.Combine(mod.path, args[0]); #else string absoluteHeaderPath = Path.Combine(Path.Combine("$(SRCROOT)/Plugins", mod.group), args[0]); #endif this.AddHeaderSearchPaths(absoluteHeaderPath, recursive); } } // 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); } this.Consolidate(); }
public XCProject(string filePath) : this() { if (!Directory.Exists(filePath)) { Debug.LogWarning("XCode project path does not exist: " + filePath); return; } if (filePath.EndsWith(".xcodeproj")) { // Debug.Log( "Opening project " + filePath ); this.projectRootPath = Path.GetDirectoryName(filePath); this.filePath = filePath; } else { // Debug.Log( "Looking for xcodeproj files in " + filePath ); string[] projects = Directory.GetDirectories(filePath, "*.xcodeproj"); if (projects.Length == 0) { Debug.LogWarning("Error: missing xcodeproj file"); return; } this.projectRootPath = filePath; //if the path is relative to the project, we need to make it absolute if (!Path.IsPathRooted(projectRootPath)) { projectRootPath = Application.dataPath.Replace("Assets", "") + projectRootPath; } // Debug.Log ("projectRootPath adjusted to " + projectRootPath); this.filePath = projects[0]; } projectFileInfo = new FileInfo(Path.Combine(this.filePath, "project.pbxproj")); string contents = projectFileInfo.OpenText().ReadToEnd(); PBXParser parser = new PBXParser(); _datastore = parser.Decode(contents); if (_datastore == null) { throw new System.Exception("Project file not found at file path " + filePath); } if (!_datastore.ContainsKey("objects")) { Debug.Log("Errore " + _datastore.Count); return; } _objects = (PBXDictionary)_datastore["objects"]; modified = false; _rootObjectKey = (string)_datastore["rootObject"]; if (!string.IsNullOrEmpty(_rootObjectKey)) { _project = new PBXProject(_rootObjectKey, (PBXDictionary)_objects[_rootObjectKey]); _rootGroup = new PBXGroup(_rootObjectKey, (PBXDictionary)_objects[_project.mainGroupID]); } else { Debug.LogWarning("error: project has no root object"); _project = null; _rootGroup = null; } }
public bool AddFolder(string folderPath, PBXGroup parent = null, string[] exclude = null, bool recursive = true, bool createBuildFile = true, string compilerFlags = null) { // Debug.Log("Folder PATH: "+folderPath); if (!Directory.Exists(folderPath)) { // Debug.Log("Directory doesn't exist?"); return(false); } if (folderPath.EndsWith(".lproj")) { // Debug.Log("Ended with .lproj"); return(AddLocFolder(folderPath, parent, exclude, createBuildFile)); } DirectoryInfo sourceDirectoryInfo = new DirectoryInfo(folderPath); if (exclude == null) { // Debug.Log("Exclude was null"); exclude = new string[] {}; } if (parent == null) { // Debug.Log("Parent was null"); parent = rootGroup; } // Create group PBXGroup newGroup = GetGroup(sourceDirectoryInfo.Name, null /*relative path*/, parent); // Debug.Log("New Group created"); foreach (string directory in Directory.GetDirectories(folderPath)) { // Debug.Log( "DIR: " + directory ); if (directory.EndsWith(".bundle")) { // Treat it like a file and copy even if not recursive // TODO also for .xcdatamodeld? // Debug.LogWarning( "This is a special folder: " + directory ); AddFile(directory, newGroup, "SOURCE_ROOT", createBuildFile); continue; } if (recursive) { // Debug.Log( "recursive" ); AddFolder(directory, newGroup, exclude, recursive, createBuildFile, compilerFlags: compilerFlags); } } // Adding files. string regexExclude = string.Format(@"{0}", string.Join("|", exclude)); foreach (string file in Directory.GetFiles(folderPath)) { if (Regex.IsMatch(file, regexExclude)) { continue; } // Debug.Log("Adding Files for Folder"); AddFile(file, newGroup, "SOURCE_ROOT", createBuildFile, compilerFlags: compilerFlags); } modified = true; return(modified); }
public PBXDictionary AddFile(string filePath, PBXGroup parent = null, string tree = "SOURCE_ROOT", bool createBuildFiles = true, bool weak = false, string compilerFlags = null) { // Debug.Log("AddFile " + filePath + ", " + parent + ", " + tree + ", " + (createBuildFiles? "TRUE":"FALSE") + ", " + (weak? "TRUE":"FALSE") ); PBXDictionary results = new PBXDictionary(); if (filePath == null) { Debug.LogError("AddFile called with null filePath"); return(results); } string absPath = string.Empty; if (Path.IsPathRooted(filePath)) { // Debug.Log( "Path is Rooted" ); absPath = filePath; } else if (tree.CompareTo("SDKROOT") != 0) { absPath = Path.Combine(Application.dataPath, filePath); } if (!(File.Exists(absPath) || Directory.Exists(absPath)) && tree.CompareTo("SDKROOT") != 0) { // Debug.Log( "Missing file: " + filePath ); return(results); } else if (tree.CompareTo("SOURCE_ROOT") == 0) { // Debug.Log( "Source Root File" ); System.Uri fileURI = new System.Uri(absPath); System.Uri rootURI = new System.Uri((projectRootPath + "/.")); filePath = rootURI.MakeRelativeUri(fileURI).ToString(); } else if (tree.CompareTo("GROUP") == 0) { // Debug.Log( "Group File" ); filePath = Path.GetFileName(filePath); } if (parent == null) { parent = _rootGroup; } //Check if there is already a file PBXFileReference fileReference = GetFile(Path.GetFileName(filePath)); if (fileReference != null) { //Updating internal data with this call. fileReference.GuessFileType(); } else { fileReference = new PBXFileReference(filePath, (TreeEnum)System.Enum.Parse(typeof(TreeEnum), tree)); } // Adding compiler flag if (!string.IsNullOrEmpty(compilerFlags)) { fileReference.compilerFlags = compilerFlags; } 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 <string, PBXFrameworksBuildPhase> currentObject in frameworkBuildPhases) { BuildAddFile(fileReference, currentObject, weak); } if (!string.IsNullOrEmpty(absPath) && (tree.CompareTo("SOURCE_ROOT") == 0)) { string libraryPath = Path.Combine("$(SRCROOT)", Path.GetDirectoryName(filePath)); if (File.Exists(absPath)) { this.AddLibrarySearchPaths(new PBXList(libraryPath)); } else { this.AddFrameworkSearchPaths(new PBXList(libraryPath)); } } break; case "PBXResourcesBuildPhase": foreach (KeyValuePair <string, PBXResourcesBuildPhase> currentObject in resourcesBuildPhases) { // Debug.Log( "Adding Resources Build File" ); BuildAddFile(fileReference, currentObject, weak); } break; case "PBXShellScriptBuildPhase": foreach (KeyValuePair <string, PBXShellScriptBuildPhase> currentObject in shellScriptBuildPhases) { // Debug.Log( "Adding Script Build File" ); BuildAddFile(fileReference, currentObject, weak); } break; case "PBXSourcesBuildPhase": foreach (KeyValuePair <string, PBXSourcesBuildPhase> currentObject in sourcesBuildPhases) { // Debug.Log( "Adding Source Build File" ); BuildAddFile(fileReference, currentObject, weak); } break; case "PBXCopyFilesBuildPhase": foreach (KeyValuePair <string, PBXCopyFilesBuildPhase> currentObject in copyBuildPhases) { // Debug.Log( "Adding Copy Files Build Phase" ); BuildAddFile(fileReference, currentObject, weak); } break; case null: Debug.LogWarning("File Not Supported: " + filePath); break; default: Debug.LogWarning("File Not Supported."); return(null); } } return(results); }