#if UNITY_EDITOR && UNITY_2019_1_OR_NEWER using System.Collections.Generic; using System.IO; using System.Reflection; using UnityEngine; using UnityEditor; using UnityEditor.Callbacks; //----------------------------------------------------------------------------- // Copyright 2012-2024 RenderHeads Ltd. All rights reserved. //----------------------------------------------------------------------------- namespace RenderHeads.Media.AVProVideo.Editor { public class PBXProjectHandlerException : System.Exception { public PBXProjectHandlerException(string message) : base(message) { } } public class PBXProjectHandler { private static System.Type _PBXProjectType; private static System.Type PBXProjectType { get { if (_PBXProjectType == null) { _PBXProjectType = System.Type.GetType("UnityEditor.iOS.Xcode.PBXProject, UnityEditor.iOS.Extensions.Xcode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); if (_PBXProjectType == null) { throw new PBXProjectHandlerException("Failed to get type \"PBXProject\""); } } return _PBXProjectType; } } private static Dictionary _PBXProjectTypeMethods; private static Dictionary PBXProjectTypeMethods { get { if (_PBXProjectTypeMethods == null) { _PBXProjectTypeMethods = new Dictionary(); } return _PBXProjectTypeMethods; } } private static MethodInfo GetMethod(string name, System.Type[] types) { string lookup = name + types.ToString(); MethodInfo method; if (!PBXProjectTypeMethods.TryGetValue(lookup, out method)) { method = _PBXProjectType.GetMethod(name, types); if (method != null) { _PBXProjectTypeMethods[lookup] = method; } else { throw new PBXProjectHandlerException(string.Format("Unknown method \"{0}\"", name)); } } return method; } private object _project; public PBXProjectHandler() { _project = System.Activator.CreateInstance(PBXProjectType); } public void ReadFromFile(string path) { MethodInfo method = GetMethod("ReadFromFile", new System.Type[] { typeof(string) }); Debug.LogFormat("[AVProVideo] Reading Xcode project at: {0}", path); method.Invoke(_project, new object[] { path }); } public void WriteToFile(string path) { MethodInfo method = GetMethod("WriteToFile", new System.Type[] { typeof(string) }); Debug.LogFormat("[AVProVideo] Writing Xcode project to: {0}", path); method.Invoke(_project, new object[] { path }); } public string TargetGuidByName(string name) { MethodInfo method = GetMethod("TargetGuidByName", new System.Type[] { typeof(string) }); string guid = (string)method.Invoke(_project, new object[] { name }); Debug.LogFormat("[AVProVideo] Target GUID for '{0}' is '{1}'", name, guid); return guid; } public void SetBuildProperty(string guid, string property, string value) { MethodInfo method = GetMethod("SetBuildProperty", new System.Type[] { typeof(string), typeof(string), typeof(string) }); Debug.LogFormat("[AVProVideo] Setting build property '{0}' to '{1}' for target with guid '{2}'", property, value, guid); method.Invoke(_project, new object[] { guid, property, value }); } } public class PostProcessBuild_macOS { private static bool ActualModifyProjectAtPath(string path) { if (!Directory.Exists(path)) { Debug.LogWarningFormat("[AVProVideo] Failed to find Xcode project with path: {0}", path); return false; } Debug.LogFormat("[AVProVideo] Modifying Xcode project at: {0}", path); string projectPath = Path.Combine(path, "project.pbxproj"); try { PBXProjectHandler handler = new PBXProjectHandler(); handler.ReadFromFile(projectPath); string guid = handler.TargetGuidByName(Application.productName); handler.SetBuildProperty(guid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES"); handler.WriteToFile(projectPath); return true; } catch (PBXProjectHandlerException ex) { Debug.LogErrorFormat("[AVProVideo] {0}", ex); } return false; } [PostProcessBuild] public static void ModifyProject(BuildTarget target, string path) { if (target != BuildTarget.StandaloneOSX) return; #if AVPROVIDEO_SUPPORT_MACOSX_10_14_3_AND_OLDER Debug.Log("[AVProVideo] Post-processing Xcode project"); string projectPath = Path.Combine(path, Path.GetFileName(path) + ".xcodeproj"); if (ActualModifyProjectAtPath(projectPath)) { Debug.Log("[AVProVideo] Finished"); } else { Debug.LogError("[AVProVideo] Failed to modify Xcode project"); Debug.Log("[AVProVideo] You will need to manually set \"Always Embed Swift Standard Libraries\" to \"YES\" in the target's build settings if you're targetting macOS versions prior to 10.14.4"); } #endif // AVPROVIDEO_SUPPORT_MACOSX_10_14_3_AND_OLDER } } } // namespace RenderHeads.Media.AVProVideo.Editor #endif