PluginProcessor.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #if UNITY_2018_1_OR_NEWER || (UNITY_2017_4_OR_NEWER && !UNITY_2017_4_0 && !UNITY_2017_4_1 && !UNITY_2017_4_2 && !UNITY_2017_4_3 && !UNITY_2017_4_4 && !UNITY_2017_4_5 && !UNITY_2017_4_6 && !UNITY_2017_4_7 && !UNITY_2017_4_8 && !UNITY_2017_4_9 && !UNITY_2017_4_10 && !UNITY_2017_4_11 && !UNITY_2017_4_12 && !UNITY_2017_4_13 && !UNITY_2017_4_14 && !UNITY_2017_4_15 && !UNITY_2017_4_15)
  2. // Unity added Android ARM64 support in 2018.1, and backported to 2017.4.16
  3. #define AVPROVIDEO_UNITY_ANDROID_ARM64_SUPPORT
  4. #endif
  5. #if !UNITY_2019_3_OR_NEWER || UNITY_2021_2_OR_NEWER || (UNITY_2020_3_OR_NEWER && !UNITY_2020_3_0 && !UNITY_2020_3_1 && !UNITY_2020_3_2 && !UNITY_2020_3_3 && !UNITY_2020_3_4 && !UNITY_2020_3_5 && !UNITY_2020_3_6 && !UNITY_2020_3_7 && !UNITY_2020_3_8 && !UNITY_2020_3_9 && !UNITY_2020_3_10 && !UNITY_2020_3_11 && !UNITY_2020_3_12 && !UNITY_2020_3_13 && !UNITY_2020_3_14 && !UNITY_2020_3_15 && !UNITY_2020_3_16) || (UNITY_2019_4_OR_NEWER && !UNITY_2019_4_0 && !UNITY_2019_4_1 && !UNITY_2019_4_2 && !UNITY_2019_4_3 && !UNITY_2019_4_4 && !UNITY_2019_4_5 && !UNITY_2019_4_6 && !UNITY_2019_4_7 && !UNITY_2019_4_8 && !UNITY_2019_4_9 && !UNITY_2019_4_10 && !UNITY_2019_4_11 && !UNITY_2019_4_12 && !UNITY_2019_4_13 && !UNITY_2019_4_14 && !UNITY_2019_4_15 && !UNITY_2019_4_16 && !UNITY_2019_4_17 && !UNITY_2019_4_18 && !UNITY_2019_4_19 && !UNITY_2019_4_20 && !UNITY_2019_4_21 && !UNITY_2019_4_22 && !UNITY_2019_4_23 && !UNITY_2019_4_24 && !UNITY_2019_4_25 && !UNITY_2019_4_26 && !UNITY_2019_4_27 && !UNITY_2019_4_28 && !UNITY_2019_4_29 && !UNITY_2019_4_30)
  6. // Unity dropped Android x86 support in 2019, but then added it back in 2021.2.0 and backported to 2020.3.17 and 2019.4.31
  7. #define AVPROVIDEO_UNITY_ANDROID_X86_SUPPORT
  8. #endif
  9. #if UNITY_2021_2_OR_NEWER || (UNITY_2020_3_OR_NEWER && !UNITY_2020_3_0 && !UNITY_2020_3_1 && !UNITY_2020_3_2 && !UNITY_2020_3_3 && !UNITY_2020_3_4 && !UNITY_2020_3_5 && !UNITY_2020_3_6 && !UNITY_2020_3_7 && !UNITY_2020_3_8 && !UNITY_2020_3_9 && !UNITY_2020_3_10 && !UNITY_2020_3_11 && !UNITY_2020_3_12 && !UNITY_2020_3_13 && !UNITY_2020_3_14 && !UNITY_2020_3_15 && !UNITY_2020_3_16) || (UNITY_2019_4_OR_NEWER && !UNITY_2019_4_0 && !UNITY_2019_4_1 && !UNITY_2019_4_2 && !UNITY_2019_4_3 && !UNITY_2019_4_4 && !UNITY_2019_4_5 && !UNITY_2019_4_6 && !UNITY_2019_4_7 && !UNITY_2019_4_8 && !UNITY_2019_4_9 && !UNITY_2019_4_10 && !UNITY_2019_4_11 && !UNITY_2019_4_12 && !UNITY_2019_4_13 && !UNITY_2019_4_14 && !UNITY_2019_4_15 && !UNITY_2019_4_16 && !UNITY_2019_4_17 && !UNITY_2019_4_18 && !UNITY_2019_4_19 && !UNITY_2019_4_20 && !UNITY_2019_4_21 && !UNITY_2019_4_22 && !UNITY_2019_4_23 && !UNITY_2019_4_24 && !UNITY_2019_4_25 && !UNITY_2019_4_26 && !UNITY_2019_4_27 && !UNITY_2019_4_28 && !UNITY_2019_4_29 && !UNITY_2019_4_30)
  10. // Unity added Android x86_64 support in 2021.2.0 and backported to 2020.3.17 and 2019.4.31
  11. #define AVPROVIDEO_UNITY_ANDROID_X8664_SUPPORT
  12. #endif
  13. #if UNITY_2019_1_OR_NEWER
  14. #define AVPROVIDEO_UNITY_UWP_ARM64_SUPPORT
  15. #endif
  16. #if UNITY_2018_1_OR_NEWER
  17. #define AVPROVIDEO_UNITY_BUILDWITHREPORT_SUPPORT
  18. #endif
  19. using UnityEngine;
  20. using UnityEditor;
  21. using UnityEditor.Build;
  22. #if AVPROVIDEO_UNITY_BUILDWITHREPORT_SUPPORT
  23. using UnityEditor.Build.Reporting;
  24. #endif
  25. using System.Collections.Generic;
  26. using System.IO;
  27. //-----------------------------------------------------------------------------
  28. // Copyright 2015-2021 RenderHeads Ltd. All rights reserved.
  29. //-----------------------------------------------------------------------------
  30. namespace RenderHeads.Media.AVProVideo.Editor
  31. {
  32. /// <summary>
  33. /// Some versions of Unity do not support specific CPU architectures for plugin files
  34. /// so this Build Preprocessor checks the plugin files for those and either disables
  35. /// them if their arch is not supported, or assigns the correct arch and enables them
  36. /// </summary>
  37. public class PluginProcessor :
  38. #if AVPROVIDEO_UNITY_BUILDWITHREPORT_SUPPORT
  39. IPreprocessBuildWithReport
  40. #else
  41. IPreprocessBuild
  42. #endif
  43. {
  44. internal class CpuArchitecture
  45. {
  46. internal CpuArchitecture(string code, bool isSupportedByThisUnityVersion)
  47. {
  48. _code = code;
  49. _isSupportedByThisUnityVersion = isSupportedByThisUnityVersion;
  50. }
  51. private string _code;
  52. private bool _isSupportedByThisUnityVersion;
  53. internal string Code()
  54. {
  55. return _code;
  56. }
  57. internal bool IsSupportedByThisUnityVersion()
  58. {
  59. return _isSupportedByThisUnityVersion;
  60. }
  61. }
  62. internal class PluginFile
  63. {
  64. internal PluginFile(BuildTarget buildTarget, string relativeFilePath, bool supportsEditor, CpuArchitecture cpuArchitecture)
  65. {
  66. _buildTarget = buildTarget;
  67. _relativeFilePath = relativeFilePath;
  68. _cpuArchitecture = cpuArchitecture;
  69. _supportsEditor = supportsEditor;
  70. }
  71. internal bool IsBuildTarget(BuildTarget buildTarget)
  72. {
  73. return (_buildTarget == buildTarget);
  74. }
  75. internal BuildTarget BuildTarget()
  76. {
  77. return _buildTarget;
  78. }
  79. internal bool IsForFile(string path)
  80. {
  81. return path.Replace("\\", "/").Contains(_relativeFilePath);
  82. }
  83. internal bool IsSupportedByThisUnityVersion()
  84. {
  85. return _cpuArchitecture.IsSupportedByThisUnityVersion();
  86. }
  87. internal string CpuArchitectureCode()
  88. {
  89. return _cpuArchitecture.Code();
  90. }
  91. internal bool SupportsEditor()
  92. {
  93. return _supportsEditor;
  94. }
  95. private BuildTarget _buildTarget;
  96. private string _relativeFilePath;
  97. private CpuArchitecture _cpuArchitecture;
  98. private bool _supportsEditor;
  99. }
  100. private static List<PluginFile> _pluginFiles = new List<PluginFile>(32);
  101. internal static void AddPluginFiles(BuildTarget buildTarget, string[] filenames, string folderPrefix, bool supportsEditor, CpuArchitecture cpuArchitecture)
  102. {
  103. foreach (string filename in filenames)
  104. {
  105. _pluginFiles.Add(new PluginFile(buildTarget, folderPrefix + filename, supportsEditor, cpuArchitecture));
  106. }
  107. }
  108. internal static void AddPlugins_Android()
  109. {
  110. #if AVPROVIDEO_UNITY_ANDROID_ARM64_SUPPORT
  111. const bool IsAndroidArm64Supported = true;
  112. #else
  113. const bool IsAndroidArm64Supported = false;
  114. #endif
  115. #if AVPROVIDEO_UNITY_ANDROID_X86_SUPPORT
  116. const bool IsAndroidX86Supported = true;
  117. #else
  118. const bool IsAndroidX86Supported = false;
  119. #endif
  120. #if AVPROVIDEO_UNITY_ANDROID_X8664_SUPPORT
  121. const bool IsAndroidX8664Supported = true;
  122. #else
  123. const bool IsAndroidX8664Supported = false;
  124. #endif
  125. string[] filenames = {
  126. "libAudio360.so",
  127. "libAudio360-JNI.so",
  128. "libAVProVideo2Native.so",
  129. "libopus.so",
  130. "libopusJNI.so",
  131. "libresample-rh.so",
  132. "libsamplerate-android.so",
  133. "libssrc-android.so",
  134. };
  135. BuildTarget target = BuildTarget.Android;
  136. AddPluginFiles(target, filenames, "Android/libs/armeabi-v7a/", false, new CpuArchitecture("ARMv7", true));
  137. AddPluginFiles(target, filenames, "Android/libs/arm64-v8a/", false, new CpuArchitecture("ARM64", IsAndroidArm64Supported));
  138. AddPluginFiles(target, filenames, "Android/libs/x86/", false, new CpuArchitecture("X86", IsAndroidX86Supported));
  139. AddPluginFiles(target, filenames, "Android/libs/x86_64/", false, new CpuArchitecture("X86_64", IsAndroidX8664Supported));
  140. }
  141. internal static void AddPlugins_UWP()
  142. {
  143. #if AVPROVIDEO_UNITY_UWP_ARM64_SUPPORT
  144. const bool IsUwpArm64Supported = true;
  145. #else
  146. const bool IsUwpArm64Supported = false;
  147. #endif
  148. string[] filenames = {
  149. "Audio360.dll",
  150. "AVProVideo.dll",
  151. "AVProVideoWinRT.dll",
  152. };
  153. BuildTarget target = BuildTarget.WSAPlayer;
  154. AddPluginFiles(target, filenames, "WSA/UWP/ARM/", false, new CpuArchitecture("ARM", true));
  155. AddPluginFiles(target, filenames, "WSA/UWP/ARM64/", false, new CpuArchitecture("ARM64", IsUwpArm64Supported));
  156. AddPluginFiles(target, filenames, "WSA/UWP/x86/", false, new CpuArchitecture("X86", true));
  157. AddPluginFiles(target, filenames, "WSA/UWP/x86_64/", false, new CpuArchitecture("X64", true));
  158. }
  159. private static void BuildPluginFileList()
  160. {
  161. _pluginFiles.Clear();
  162. AddPlugins_Android();
  163. AddPlugins_UWP();
  164. }
  165. private class SFileToDelete
  166. {
  167. public SFileToDelete(string fn)
  168. {
  169. filename = fn;
  170. fullPath = "";
  171. found = false;
  172. }
  173. public string filename;
  174. public string fullPath;
  175. public bool found;
  176. };
  177. private static void RemoveLegacyPluginFiles()
  178. {
  179. List<SFileToDelete> aFilesToDelete = new List<SFileToDelete>();
  180. #if (UNITY_EDITOR && UNITY_ANDROID)
  181. aFilesToDelete.Add( new SFileToDelete( "Android/guava-27.1-android.jar" ) );
  182. aFilesToDelete.Add( new SFileToDelete( "Android/libs/arm64-v8a/libc++_shared.so" ) );
  183. aFilesToDelete.Add( new SFileToDelete( "Android/libs/armeabi-v7a/libc++_shared.so" ) );
  184. aFilesToDelete.Add( new SFileToDelete( "Android/libs/x86/libc++_shared.so" ) );
  185. aFilesToDelete.Add( new SFileToDelete( "Android/libs/x86_64/libc++_shared.so" ) );
  186. #endif
  187. if( aFilesToDelete.Count > 0 )
  188. {
  189. int iNumFoundFilesToDelete = 0;
  190. string aFilesToDeleteString = "";
  191. PluginImporter[] importers = PluginImporter.GetAllImporters();
  192. foreach (PluginImporter pi in importers)
  193. {
  194. foreach( SFileToDelete fileToDelete in aFilesToDelete )
  195. {
  196. string pluginFilename = pi.assetPath;
  197. pluginFilename.Replace("\\", "/");
  198. if( pluginFilename.Contains( fileToDelete.filename ) )
  199. {
  200. fileToDelete.fullPath = pi.assetPath;
  201. fileToDelete.found = true;
  202. if( iNumFoundFilesToDelete > 0 )
  203. {
  204. aFilesToDeleteString += "\n";
  205. }
  206. aFilesToDeleteString += pi.assetPath;
  207. ++iNumFoundFilesToDelete;
  208. }
  209. }
  210. }
  211. if( iNumFoundFilesToDelete > 0 )
  212. {
  213. string message = ( iNumFoundFilesToDelete == 1 ) ? "A legacy AVPro Video plugin file has been found that requires deleting in order to build." : "Legacy AVPro Video plugin files have been found that require deleting in order to build.";
  214. Debug.Log("[AVProVideo] " + message + " Files: " + aFilesToDeleteString );
  215. if ( EditorUtility.DisplayDialog( "AVPro Video Legacy File", message + "\n\nDelete the following files?\n\n" + aFilesToDeleteString, "Delete", "Ignore" ) )
  216. {
  217. foreach( SFileToDelete fileToDelete in aFilesToDelete )
  218. {
  219. bool bDeleted = AssetDatabase.DeleteAsset( fileToDelete.fullPath );
  220. if( bDeleted )
  221. {
  222. Debug.Log( "[AVProVideo] Deleting " + fileToDelete.fullPath );
  223. }
  224. }
  225. }
  226. }
  227. }
  228. }
  229. public int callbackOrder { get { return 0; } }
  230. #if AVPROVIDEO_UNITY_BUILDWITHREPORT_SUPPORT
  231. public void OnPreprocessBuild(BuildReport report)
  232. {
  233. RemoveLegacyPluginFiles();
  234. BuildPluginFileList();
  235. CheckNativePlugins(report.summary.platform);
  236. }
  237. #else
  238. public void OnPreprocessBuild(BuildTarget target, string path)
  239. {
  240. RemoveLegacyPluginFiles();
  241. BuildPluginFileList();
  242. CheckNativePlugins(target);
  243. }
  244. #endif
  245. internal static void CheckNativePlugins(BuildTarget target)
  246. {
  247. PluginImporter[] importers = PluginImporter.GetAllImporters();
  248. foreach (PluginImporter pi in importers)
  249. {
  250. // Currently we're only interested in native plugins
  251. if (!pi.isNativePlugin) continue;
  252. // Skip plugins that aren't in the AVProVideo path
  253. // NOTE: This is commented out for now to allow the case where users have moved the plugin files to another folder.
  254. // Eventually might need a more robust method, perhaps using GUIDS
  255. //if (!pi.assetPath.Contains("AVProVideo")) continue;
  256. foreach (PluginFile pluginFile in _pluginFiles)
  257. {
  258. if (pluginFile.IsBuildTarget(target) &&
  259. pluginFile.IsForFile(pi.assetPath))
  260. {
  261. pi.SetCompatibleWithAnyPlatform(false);
  262. if (pluginFile.IsSupportedByThisUnityVersion())
  263. {
  264. Debug.Log("[AVProVideo] Enabling " + pluginFile.CpuArchitectureCode() + " " + pi.assetPath);
  265. pi.SetCompatibleWithEditor(pluginFile.SupportsEditor());
  266. pi.SetCompatibleWithPlatform(pluginFile.BuildTarget(), true);
  267. pi.SetPlatformData(pluginFile.BuildTarget(), "CPU", pluginFile.CpuArchitectureCode());
  268. }
  269. else
  270. {
  271. pi.SetCompatibleWithEditor(false);
  272. pi.SetCompatibleWithPlatform(pluginFile.BuildTarget(), false);
  273. pi.SetPlatformData(pluginFile.BuildTarget(), "CPU", "");
  274. Debug.Log("[AVProVideo] Disabling " + pluginFile.CpuArchitectureCode() + " " + pi.assetPath);
  275. }
  276. pi.SaveAndReimport();
  277. break;
  278. }
  279. }
  280. }
  281. }
  282. }
  283. }