PostProcessBuild_macOS.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #if UNITY_EDITOR && UNITY_2019_1_OR_NEWER
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Reflection;
  5. using UnityEngine;
  6. using UnityEditor;
  7. using UnityEditor.Callbacks;
  8. //-----------------------------------------------------------------------------
  9. // Copyright 2012-2021 RenderHeads Ltd. All rights reserved.
  10. //-----------------------------------------------------------------------------
  11. namespace RenderHeads.Media.AVProVideo.Editor
  12. {
  13. public class PBXProjectHandlerException : System.Exception
  14. {
  15. public PBXProjectHandlerException(string message)
  16. : base(message)
  17. {
  18. }
  19. }
  20. public class PBXProjectHandler
  21. {
  22. private static System.Type _PBXProjectType;
  23. private static System.Type PBXProjectType
  24. {
  25. get
  26. {
  27. if (_PBXProjectType == null)
  28. {
  29. _PBXProjectType = System.Type.GetType("UnityEditor.iOS.Xcode.PBXProject, UnityEditor.iOS.Extensions.Xcode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
  30. if (_PBXProjectType == null)
  31. {
  32. throw new PBXProjectHandlerException("Failed to get type \"PBXProject\"");
  33. }
  34. }
  35. return _PBXProjectType;
  36. }
  37. }
  38. private static Dictionary<string, MethodInfo> _PBXProjectTypeMethods;
  39. private static Dictionary<string, MethodInfo> PBXProjectTypeMethods
  40. {
  41. get
  42. {
  43. if (_PBXProjectTypeMethods == null)
  44. {
  45. _PBXProjectTypeMethods = new Dictionary<string, MethodInfo>();
  46. }
  47. return _PBXProjectTypeMethods;
  48. }
  49. }
  50. private static MethodInfo GetMethod(string name, System.Type[] types)
  51. {
  52. string lookup = name + types.ToString();
  53. MethodInfo method;
  54. if (!PBXProjectTypeMethods.TryGetValue(lookup, out method))
  55. {
  56. method = _PBXProjectType.GetMethod(name, types);
  57. if (method != null)
  58. {
  59. _PBXProjectTypeMethods[lookup] = method;
  60. }
  61. else
  62. {
  63. throw new PBXProjectHandlerException(string.Format("Unknown method \"{0}\"", name));
  64. }
  65. }
  66. return method;
  67. }
  68. private object _project;
  69. public PBXProjectHandler()
  70. {
  71. _project = System.Activator.CreateInstance(PBXProjectType);
  72. }
  73. public void ReadFromFile(string path)
  74. {
  75. MethodInfo method = GetMethod("ReadFromFile", new System.Type[] { typeof(string) });
  76. Debug.LogFormat("[AVProVideo] Reading Xcode project at: {0}", path);
  77. method.Invoke(_project, new object[] { path });
  78. }
  79. public void WriteToFile(string path)
  80. {
  81. MethodInfo method = GetMethod("WriteToFile", new System.Type[] { typeof(string) });
  82. Debug.LogFormat("[AVProVideo] Writing Xcode project to: {0}", path);
  83. method.Invoke(_project, new object[] { path });
  84. }
  85. public string TargetGuidByName(string name)
  86. {
  87. MethodInfo method = GetMethod("TargetGuidByName", new System.Type[] { typeof(string) });
  88. string guid = (string)method.Invoke(_project, new object[] { name });
  89. Debug.LogFormat("[AVProVideo] Target GUID for '{0}' is '{1}'", name, guid);
  90. return guid;
  91. }
  92. public void SetBuildProperty(string guid, string property, string value)
  93. {
  94. MethodInfo method = GetMethod("SetBuildProperty", new System.Type[] { typeof(string), typeof(string), typeof(string) });
  95. Debug.LogFormat("[AVProVideo] Setting build property '{0}' to '{1}' for target with guid '{2}'", property, value, guid);
  96. method.Invoke(_project, new object[] { guid, property, value });
  97. }
  98. }
  99. public class PostProcessBuild_macOS
  100. {
  101. private static bool ActualModifyProjectAtPath(string path)
  102. {
  103. if (!Directory.Exists(path))
  104. {
  105. Debug.LogWarningFormat("[AVProVideo] Failed to find Xcode project with path: {0}", path);
  106. return false;
  107. }
  108. Debug.LogFormat("[AVProVideo] Modifying Xcode project at: {0}", path);
  109. string projectPath = Path.Combine(path, "project.pbxproj");
  110. try
  111. {
  112. PBXProjectHandler handler = new PBXProjectHandler();
  113. handler.ReadFromFile(projectPath);
  114. string guid = handler.TargetGuidByName(Application.productName);
  115. handler.SetBuildProperty(guid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");
  116. handler.WriteToFile(projectPath);
  117. return true;
  118. }
  119. catch (PBXProjectHandlerException ex)
  120. {
  121. Debug.LogErrorFormat("[AVProVideo] {0}", ex);
  122. }
  123. return false;
  124. }
  125. [PostProcessBuild]
  126. public static void ModifyProject(BuildTarget target, string path)
  127. {
  128. if (target != BuildTarget.StandaloneOSX)
  129. return;
  130. #if AVPROVIDEO_SUPPORT_MACOSX_10_14_3_AND_OLDER
  131. Debug.Log("[AVProVideo] Post-processing Xcode project");
  132. string projectPath = Path.Combine(path, Path.GetFileName(path) + ".xcodeproj");
  133. if (ActualModifyProjectAtPath(projectPath))
  134. {
  135. Debug.Log("[AVProVideo] Finished");
  136. }
  137. else
  138. {
  139. Debug.LogError("[AVProVideo] Failed to modify Xcode project");
  140. 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");
  141. }
  142. #endif // AVPROVIDEO_SUPPORT_MACOSX_10_14_3_AND_OLDER
  143. }
  144. }
  145. } // namespace RenderHeads.Media.AVProVideo.Editor
  146. #endif