PostBuildStandalone.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text.RegularExpressions;
  5. using UnityEditor;
  6. using UnityEditor.Callbacks;
  7. using UnityEngine;
  8. using System.Runtime.InteropServices;
  9. namespace ZenFulcrum.EmbeddedBrowser {
  10. /**
  11. * Getting CEF running on a build result requires some fiddling to get all the files in the right place.
  12. */
  13. class PostBuildStandalone {
  14. // private static readonly List<string> rootDirDlls = new List<string>{
  15. // "d3dcompiler_43.dll",
  16. // "d3dcompiler_47.dll",
  17. // "libEGL.dll",
  18. // "libGLESv2.dll",
  19. // "widevinecdmadapter.dll",
  20. // "zf_cef.dll",
  21. // };
  22. [PostProcessBuild(10)]
  23. public static void PostprocessWindowsBuild(BuildTarget target, string buildFile) {
  24. if (target != BuildTarget.StandaloneWindows && target != BuildTarget.StandaloneWindows64) return;
  25. Debug.Log("Post processing " + buildFile);
  26. var buildName = Regex.Match(buildFile, @"/([^/]+)\.exe$").Groups[1].Value;
  27. var buildPath = Directory.GetParent(buildFile);
  28. var dataPath = buildPath + "/" + buildName + "_Data";
  29. var pluginsPath = dataPath + "/Plugins/";
  30. //can't use FileLocations because we may not be building the same type as the editor
  31. var platformPluginsSrc = ZFFolder + "/Plugins/w" + (target == BuildTarget.StandaloneWindows64 ? "64" : "32");
  32. //Copy stuff we need in the root dir there
  33. // foreach (var file in rootDirDlls) {
  34. // ForceMove(
  35. // dataPath + "/Plugins/" + file,
  36. // buildPath + "/" + file
  37. // );
  38. // }
  39. File.Copy(platformPluginsSrc + "/natives_blob.bin", pluginsPath + "/natives_blob.bin", true);
  40. File.Copy(platformPluginsSrc + "/snapshot_blob.bin", pluginsPath + "/snapshot_blob.bin", true);
  41. File.Copy(ZFFolder + "/ThirdPartyNotices.txt", pluginsPath + "/ThirdPartyNotices.txt", true);
  42. //Copy the needed resources
  43. var resSrcDir = ZFFolder + "/Plugins/CEFResources";
  44. foreach (var filePath in Directory.GetFiles(resSrcDir)) {
  45. var fileName = new FileInfo(filePath).Name;
  46. if (fileName.EndsWith(".meta")) continue;
  47. File.Copy(filePath, pluginsPath + fileName, true);
  48. }
  49. //(Unlike locales, icudtl.dat can't be put in a different folder)
  50. File.Copy(platformPluginsSrc + "/icudtl.dat", pluginsPath + "/icudtl.dat", true);
  51. //Slave process (doesn't get automatically copied by Unity like the .dlls)
  52. File.Copy(
  53. platformPluginsSrc + "/" + FileLocations.SlaveExecutable + ".exe",
  54. pluginsPath + FileLocations.SlaveExecutable + ".exe",
  55. true
  56. );
  57. //Locales
  58. var localesSrcDir = ZFFolder + "/Plugins/CEFResources/locales";
  59. var localesDestDir = dataPath + "/Plugins/locales";
  60. Directory.CreateDirectory(localesDestDir);
  61. foreach (var filePath in Directory.GetFiles(localesSrcDir)) {
  62. var fileName = new FileInfo(filePath).Name;
  63. if (fileName.EndsWith(".meta")) continue;
  64. File.Copy(filePath, localesDestDir + "/" + fileName, true);
  65. }
  66. WriteBrowserAssets(dataPath + "/" + StandaloneWebResources.DefaultPath);
  67. }
  68. [PostProcessBuild(10)]
  69. public static void PostprocessLinuxBuild(BuildTarget target, string buildFile) {
  70. if (target == BuildTarget.StandaloneLinux || target == BuildTarget.StandaloneLinuxUniversal) {
  71. throw new Exception("Only x86_64 is supported");
  72. }
  73. if (target != BuildTarget.StandaloneLinux64) return;
  74. Debug.Log("Post processing " + buildFile);
  75. var buildName = Regex.Match(buildFile, @"\/([^\/]+?)(\.x86(_64)?)?$").Groups[1].Value;
  76. var buildPath = Directory.GetParent(buildFile);
  77. var dataPath = buildPath + "/" + buildName + "_Data";
  78. //can't use FileLocations because we may not be building the same type as the editor
  79. var platformPluginsSrc = ZFFolder + "/Plugins/l" + (target == BuildTarget.StandaloneLinux64 ? "64" : "32");
  80. //Copy the needed resources
  81. var resSrcDir = ZFFolder + "/Plugins/CEFResources";
  82. foreach (var filePath in Directory.GetFiles(resSrcDir)) {
  83. var fileName = new FileInfo(filePath).Name;
  84. if (fileName.EndsWith(".meta")) continue;
  85. File.Copy(filePath, dataPath + "/Plugins/" + fileName, true);
  86. }
  87. var byBinFiles = new List<string>() {
  88. "natives_blob.bin",
  89. "snapshot_blob.bin",
  90. "icudtl.dat",
  91. };
  92. foreach (var file in byBinFiles) {
  93. var linkDest = buildName + "_Data/Plugins/" + file;
  94. var linkFile = buildPath + "/" + file;
  95. File.Copy(platformPluginsSrc + "/" + file, dataPath + "/Plugins/" + file, true);
  96. File.Delete(linkFile);
  97. var linkRes = symlink(linkDest, linkFile);
  98. if (linkRes != 0) throw new Exception("Failed to symlink " + linkFile);
  99. }
  100. File.Copy(platformPluginsSrc + "/libgcrypt.so.11", dataPath + "/Plugins/libgcrypt.so.11", true);
  101. File.Copy(ZFFolder + "/ThirdPartyNotices.txt", dataPath + "/Plugins/ThirdPartyNotices.txt", true);
  102. //Slave process (doesn't get automatically copied by Unity like the .dlls)
  103. File.Copy(
  104. platformPluginsSrc + "/" + FileLocations.SlaveExecutable,
  105. dataPath + "/Plugins/" + FileLocations.SlaveExecutable,
  106. true
  107. );
  108. //Locales
  109. var localesSrcDir = ZFFolder + "/Plugins/CEFResources/locales";
  110. var localesDestDir = dataPath + "/Plugins/locales";
  111. Directory.CreateDirectory(localesDestDir);
  112. foreach (var filePath in Directory.GetFiles(localesSrcDir)) {
  113. var fileName = new FileInfo(filePath).Name;
  114. if (fileName.EndsWith(".meta")) continue;
  115. File.Copy(filePath, localesDestDir + "/" + fileName, true);
  116. }
  117. WriteBrowserAssets(dataPath + "/" + StandaloneWebResources.DefaultPath);
  118. }
  119. [PostProcessBuild(10)]
  120. public static void PostprocessMacBuild(BuildTarget target, string buildFile) {
  121. #if UNITY_2017_3_OR_NEWER
  122. if (target != BuildTarget.StandaloneOSX) return;
  123. #else
  124. if (target == BuildTarget.StandaloneOSXUniversal || target == BuildTarget.StandaloneOSXIntel) {
  125. throw new Exception("Only x86_64 is supported");
  126. }
  127. if (target != BuildTarget.StandaloneOSXIntel64) return;
  128. #endif
  129. Debug.Log("Post processing " + buildFile);
  130. //var buildName = Regex.Match(buildFile, @"\/([^\/]+?)\.app$").Groups[1].Value;
  131. var buildPath = buildFile;
  132. var platformPluginsSrc = ZFFolder + "/Plugins/m64";
  133. //Copy app bits
  134. CopyDirectory(
  135. platformPluginsSrc + "/BrowserLib.app/Contents/Frameworks/Chromium Embedded Framework.framework",
  136. buildPath + "/Contents/Frameworks/Chromium Embedded Framework.framework"
  137. );
  138. CopyDirectory(
  139. platformPluginsSrc + "/BrowserLib.app/Contents/Frameworks/ZFGameBrowser.app",
  140. buildPath + "/Contents/Frameworks/ZFGameBrowser.app"
  141. );
  142. File.Copy(platformPluginsSrc + "/libZFProxyWeb.dylib", buildPath + "/Contents/Plugins/libZFProxyWeb.dylib", true);
  143. File.Copy(ZFFolder + "/ThirdPartyNotices.txt", buildPath + "/ThirdPartyNotices.txt", true);
  144. //BrowserAssets
  145. WriteBrowserAssets(buildPath + "/Contents/" + StandaloneWebResources.DefaultPath);
  146. }
  147. private static void WriteBrowserAssets(string path) {
  148. //Debug.Log("Writing browser assets to " + path);
  149. var htmlDir = Application.dataPath + "/../BrowserAssets";
  150. var allData = new Dictionary<string, byte[]>();
  151. if (Directory.Exists(htmlDir)) {
  152. foreach (var file in Directory.GetFiles(htmlDir, "*", SearchOption.AllDirectories)) {
  153. var localPath = file.Substring(htmlDir.Length).Replace("\\", "/");
  154. allData[localPath] = File.ReadAllBytes(file);
  155. }
  156. }
  157. var wr = new StandaloneWebResources(path);
  158. wr.WriteData(allData);
  159. }
  160. private static void ForceMove(string src, string dest) {
  161. if (File.Exists(dest)) File.Delete(dest);
  162. File.Move(src, dest);
  163. }
  164. private static string ZFFolder {
  165. get {
  166. var path = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName();
  167. path = Directory.GetParent(path).Parent.Parent.FullName;
  168. return path;
  169. }
  170. }
  171. private static void CopyDirectory(string src, string dest) {
  172. foreach (var dir in Directory.GetDirectories(src, "*", SearchOption.AllDirectories)) {
  173. Directory.CreateDirectory(dir.Replace(src, dest));
  174. }
  175. foreach (var file in Directory.GetFiles(src, "*", SearchOption.AllDirectories)) {
  176. if (file.EndsWith(".meta")) continue;
  177. File.Copy(file, file.Replace(src, dest), true);
  178. }
  179. }
  180. [DllImport("__Internal")] static extern int symlink(string destStr, string symFile);
  181. }
  182. }