BuildManager.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using System.IO;
  5. using System.Runtime.CompilerServices;
  6. using System.Threading;
  7. using bs;
  8. namespace bs.Editor
  9. {
  10. /** @addtogroup Build
  11. * @{
  12. */
  13. /// <summary>
  14. /// Contains a list of valid platforms that can be built for.
  15. /// </summary>
  16. public enum PlatformType // Note: Must match C++ enum PlatformType
  17. {
  18. Windows,
  19. Count // Keep at end
  20. }
  21. /// <summary>
  22. /// Contains build data for a specific platform.
  23. /// </summary>
  24. public abstract class PlatformInfo : ScriptObject
  25. {
  26. /// <summary>
  27. /// Creates a new platform info. For internal runtime use only.
  28. /// </summary>
  29. protected PlatformInfo()
  30. { }
  31. /// <summary>
  32. /// Returns the platform that this object contains data for.
  33. /// </summary>
  34. public PlatformType Type
  35. {
  36. get { return Internal_GetType(mCachedPtr); }
  37. }
  38. /// <summary>
  39. /// Initial scene that is loaded when application is first started.
  40. /// </summary>
  41. public RRef<Prefab> MainScene
  42. {
  43. get { return Internal_GetMainScene(mCachedPtr); }
  44. set
  45. {
  46. IntPtr scenePtr = IntPtr.Zero;
  47. if (value != null)
  48. scenePtr = value.GetCachedPtr();
  49. Internal_SetMainScene(mCachedPtr, scenePtr);
  50. }
  51. }
  52. /// <summary>
  53. /// Determines should the application be started in fullscreen using the user's desktop resolution.
  54. /// </summary>
  55. public bool Fullscreen
  56. {
  57. get { return Internal_GetFullscreen(mCachedPtr); }
  58. set { Internal_SetFullscreen(mCachedPtr, value); }
  59. }
  60. /// <summary>
  61. /// Width of a window if the game is started in windowed mode. This is only relevant if <see cref="Fullscreen"/>
  62. /// is off.
  63. /// </summary>
  64. public int WindowedWidth
  65. {
  66. get
  67. {
  68. int width, height;
  69. Internal_GetResolution(mCachedPtr, out width, out height);
  70. return width;
  71. }
  72. set { Internal_SetResolution(mCachedPtr, value, WindowedHeight); }
  73. }
  74. /// <summary>
  75. /// Height of a window if the game is started in windowed mode. This is only relevant if <see cref="Fullscreen"/>
  76. /// is off.
  77. /// </summary>
  78. public int WindowedHeight
  79. {
  80. get
  81. {
  82. int width, height;
  83. Internal_GetResolution(mCachedPtr, out width, out height);
  84. return height;
  85. }
  86. set { Internal_SetResolution(mCachedPtr, WindowedWidth, value); }
  87. }
  88. /// <summary>
  89. /// Determines should the scripts be output in debug mode (worse performance but better error reporting).
  90. /// </summary>
  91. public bool Debug
  92. {
  93. get { return Internal_GetDebug(mCachedPtr); }
  94. set { Internal_SetDebug(mCachedPtr, value); }
  95. }
  96. /// <summary>
  97. /// A set of semicolon separated defines to use when compiling scripts for this platform.
  98. /// </summary>
  99. public string Defines
  100. {
  101. get { return Internal_GetDefines(mCachedPtr); }
  102. set { Internal_SetDefines(mCachedPtr, value); }
  103. }
  104. [MethodImpl(MethodImplOptions.InternalCall)]
  105. private static extern PlatformType Internal_GetType(IntPtr thisPtr);
  106. [MethodImpl(MethodImplOptions.InternalCall)]
  107. private static extern string Internal_GetDefines(IntPtr thisPtr);
  108. [MethodImpl(MethodImplOptions.InternalCall)]
  109. private static extern void Internal_SetDefines(IntPtr thisPtr, string value);
  110. [MethodImpl(MethodImplOptions.InternalCall)]
  111. private static extern RRef<Prefab> Internal_GetMainScene(IntPtr thisPtr);
  112. [MethodImpl(MethodImplOptions.InternalCall)]
  113. static extern void Internal_SetMainScene(IntPtr thisPtr, IntPtr prefabPtr);
  114. [MethodImpl(MethodImplOptions.InternalCall)]
  115. static extern bool Internal_GetFullscreen(IntPtr thisPtr);
  116. [MethodImpl(MethodImplOptions.InternalCall)]
  117. static extern void Internal_SetFullscreen(IntPtr thisPtr, bool fullscreen);
  118. [MethodImpl(MethodImplOptions.InternalCall)]
  119. static extern void Internal_GetResolution(IntPtr thisPtr, out int width, out int height);
  120. [MethodImpl(MethodImplOptions.InternalCall)]
  121. static extern void Internal_SetResolution(IntPtr thisPtr, int width, int height);
  122. [MethodImpl(MethodImplOptions.InternalCall)]
  123. static extern bool Internal_GetDebug(IntPtr thisPtr);
  124. [MethodImpl(MethodImplOptions.InternalCall)]
  125. static extern void Internal_SetDebug(IntPtr thisPtr, bool fullscreen);
  126. }
  127. /// <summary>
  128. /// Supported icon sizes for Windows platform.
  129. /// </summary>
  130. public enum WinIconSizes
  131. {
  132. Icon16 = 16,
  133. Icon32 = 32,
  134. Icon48 = 48,
  135. Icon64 = 64,
  136. Icon96 = 96,
  137. Icon128 = 128,
  138. Icon196 = 196,
  139. Icon256 = 256
  140. }
  141. /// <summary>
  142. /// Platform data specific to Windows.
  143. /// </summary>
  144. public class WinPlatformInfo : PlatformInfo
  145. {
  146. /// <summary>
  147. /// Texture that will be displayed on the application's executable.
  148. /// </summary>
  149. public RRef<Texture> Icon
  150. {
  151. get { return Internal_GetIcon(mCachedPtr); }
  152. set
  153. {
  154. IntPtr texturePtr = IntPtr.Zero;
  155. if (value != null)
  156. texturePtr = value.GetCachedPtr();
  157. Internal_SetIcon(mCachedPtr, texturePtr);
  158. }
  159. }
  160. /// <summary>
  161. /// Text that will be displayed in the application's title bar.
  162. /// </summary>
  163. public string TitleText
  164. {
  165. get { return Internal_GetTitleText(mCachedPtr); }
  166. set { Internal_SetTitleText(mCachedPtr, value); }
  167. }
  168. [MethodImpl(MethodImplOptions.InternalCall)]
  169. private static extern RRef<Texture> Internal_GetIcon(IntPtr thisPtr);
  170. [MethodImpl(MethodImplOptions.InternalCall)]
  171. private static extern void Internal_SetIcon(IntPtr thisPtr, IntPtr texturePtr);
  172. [MethodImpl(MethodImplOptions.InternalCall)]
  173. private static extern string Internal_GetTitleText(IntPtr thisPtr);
  174. [MethodImpl(MethodImplOptions.InternalCall)]
  175. private static extern void Internal_SetTitleText(IntPtr thisPtr, string value);
  176. }
  177. /// <summary>
  178. /// Handles building of the game executable and packaging of all necessary resources, making the game be ready to ran
  179. /// as a standalone product.
  180. /// </summary>
  181. public static class BuildManager
  182. {
  183. /// <summary>
  184. /// Returns a list of all available platforms that can be built for.
  185. /// </summary>
  186. public static PlatformType[] AvailablePlatforms
  187. {
  188. get { return Internal_GetAvailablePlatforms(); }
  189. }
  190. /// <summary>
  191. /// Returns the currently active platform.
  192. /// </summary>
  193. public static PlatformType ActivePlatform
  194. {
  195. get { return Internal_GetActivePlatform(); }
  196. set { Internal_SetActivePlatform(value); }
  197. }
  198. /// <summary>
  199. /// Returns the data about the currently active platform.
  200. /// </summary>
  201. public static PlatformInfo ActivePlatformInfo
  202. {
  203. get { return Internal_GetActivePlatformInfo(); }
  204. }
  205. /// <summary>
  206. /// Returns absolute path to the folder where builds for the currently active platform are output.
  207. /// </summary>
  208. public static string OutputFolder
  209. {
  210. get { return GetBuildFolder(BuildFolder.DestinationRoot, ActivePlatform); }
  211. }
  212. /// <summary>
  213. /// Returns a path to a specific folder used in the build process. See entries of BuildFolder enum for explanations
  214. /// of individual folder types.
  215. /// </summary>
  216. /// <param name="folder">Type of folder to retrieve the path for.</param>
  217. /// <param name="platform">Platform to retrieve the path for.</param>
  218. /// <returns>Path for the requested folder. This can be absolute or relative, see <see cref="BuildFolder"/> enum
  219. /// for details.</returns>
  220. private static string GetBuildFolder(BuildFolder folder, PlatformType platform)
  221. {
  222. return Internal_GetBuildFolder(folder, platform);
  223. }
  224. /// <summary>
  225. /// Returns a list of names of all native binaries required for a specific platform.
  226. /// </summary>
  227. /// <param name="platform">Platform type for which to get the binaries for.</param>
  228. /// <returns>Array of names of native binary files.</returns>
  229. private static string[] GetNativeBinaries(PlatformType platform)
  230. {
  231. return Internal_GetNativeBinaries(platform);
  232. }
  233. /// <summary>
  234. /// Builds the executable and packages the game.
  235. /// </summary>
  236. public static void Build()
  237. {
  238. PlatformType activePlatform = ActivePlatform;
  239. PlatformInfo platformInfo = ActivePlatformInfo;
  240. string srcRoot = GetBuildFolder(BuildFolder.SourceRoot, activePlatform);
  241. string destRoot = GetBuildFolder(BuildFolder.DestinationRoot, activePlatform);
  242. // Prepare clean destination folder
  243. if(Directory.Exists(destRoot))
  244. Directory.Delete(destRoot, true);
  245. Directory.CreateDirectory(destRoot);
  246. // Compile game assembly
  247. string bansheeAssemblyFolder;
  248. if(platformInfo.Debug)
  249. bansheeAssemblyFolder = GetBuildFolder(BuildFolder.BansheeDebugAssemblies, activePlatform);
  250. else
  251. bansheeAssemblyFolder = GetBuildFolder(BuildFolder.BansheeReleaseAssemblies, activePlatform);
  252. string srcBansheeAssemblyFolder = Path.Combine(srcRoot, bansheeAssemblyFolder);
  253. string destBansheeAssemblyFolder = Path.Combine(destRoot, bansheeAssemblyFolder);
  254. Directory.CreateDirectory(destBansheeAssemblyFolder);
  255. CompilerInstance ci = ScriptCompiler.CompileAsync(ScriptAssemblyType.Game, ActivePlatform, platformInfo.Debug, destBansheeAssemblyFolder);
  256. // Copy engine assembly
  257. {
  258. string srcFile = Path.Combine(srcBansheeAssemblyFolder, EditorApplication.EngineAssemblyName);
  259. string destFile = Path.Combine(destBansheeAssemblyFolder, EditorApplication.EngineAssemblyName);
  260. File.Copy(srcFile, destFile);
  261. }
  262. // Copy builtin data
  263. string dataFolder = GetBuildFolder(BuildFolder.Data, activePlatform);
  264. string srcData = Path.Combine(srcRoot, dataFolder);
  265. string destData = Path.Combine(destRoot, dataFolder);
  266. DirectoryEx.Copy(srcData, destData);
  267. // Copy native binaries
  268. string binaryFolder = GetBuildFolder(BuildFolder.NativeBinaries, activePlatform);
  269. string srcBin = Path.Combine(srcRoot, binaryFolder);
  270. string destBin = destRoot;
  271. string[] nativeBinaries = GetNativeBinaries(activePlatform);
  272. foreach (var entry in nativeBinaries)
  273. {
  274. string srcFile = Path.Combine(srcBin, entry);
  275. string destFile = Path.Combine(destBin, entry);
  276. File.Copy(srcFile, destFile);
  277. }
  278. // Copy .NET framework assemblies
  279. string frameworkAssemblyFolder = GetBuildFolder(BuildFolder.FrameworkAssemblies, activePlatform);
  280. string srcFrameworkAssemblyFolder = Path.Combine(srcRoot, frameworkAssemblyFolder);
  281. string destFrameworkAssemblyFolder = Path.Combine(destRoot, frameworkAssemblyFolder);
  282. Directory.CreateDirectory(destFrameworkAssemblyFolder);
  283. string[] frameworkAssemblies = GetFrameworkAssemblies(activePlatform);
  284. foreach (var entry in frameworkAssemblies)
  285. {
  286. string srcFile = Path.Combine(srcFrameworkAssemblyFolder, entry + ".dll");
  287. string destFile = Path.Combine(destFrameworkAssemblyFolder, entry + ".dll");
  288. File.Copy(srcFile, destFile);
  289. }
  290. // Copy Mono
  291. string monoFolder = GetBuildFolder(BuildFolder.Mono, activePlatform);
  292. string srcMonoFolder = Path.Combine(srcRoot, monoFolder);
  293. string destMonoFolder = Path.Combine(destRoot, monoFolder);
  294. DirectoryEx.Copy(srcMonoFolder, destMonoFolder);
  295. string srcExecFile = GetMainExecutable(activePlatform);
  296. string destExecFile = Path.Combine(destBin, Path.GetFileName(srcExecFile));
  297. File.Copy(srcExecFile, destExecFile);
  298. InjectIcons(destExecFile, platformInfo);
  299. PackageResources(destRoot, platformInfo);
  300. CreateStartupSettings(destRoot, platformInfo);
  301. // Wait until compile finishes
  302. while (!ci.IsDone)
  303. Thread.Sleep(200);
  304. ci.Dispose();
  305. }
  306. /// <summary>
  307. /// Injects icons specified in <see cref="PlatformInfo"/> into an executable at the specified path.
  308. /// </summary>
  309. /// <param name="filePath">Absolute path to the executable to inject icons in.</param>
  310. /// <param name="info">Object containing references to icons to inject.</param>
  311. private static void InjectIcons(string filePath, PlatformInfo info)
  312. {
  313. IntPtr infoPtr = IntPtr.Zero;
  314. if (info != null)
  315. infoPtr = info.GetCachedPtr();
  316. Internal_InjectIcons(filePath, infoPtr);
  317. }
  318. /// <summary>
  319. /// Finds all used resources by the build and packages them into an output folder.
  320. /// </summary>
  321. /// <param name="buildFolder">Absolute path to the root folder of the build. This is where the packaged resource
  322. /// folder be placed.</param>
  323. /// <param name="info">Platform information about the current build.</param>
  324. private static void PackageResources(string buildFolder, PlatformInfo info)
  325. {
  326. IntPtr infoPtr = IntPtr.Zero;
  327. if (info != null)
  328. infoPtr = info.GetCachedPtr();
  329. Internal_PackageResources(buildFolder, infoPtr);
  330. }
  331. /// <summary>
  332. /// Creates a game settings asset that contains necessary data for starting up the game (for example initial scene).
  333. /// </summary>
  334. /// <param name="buildFolder">Absolute path to the root folder of the build. This is where the settings assets
  335. /// will be output.</param>
  336. /// <param name="info">Platform information about the current build.</param>
  337. private static void CreateStartupSettings(string buildFolder, PlatformInfo info)
  338. {
  339. IntPtr infoPtr = IntPtr.Zero;
  340. if (info != null)
  341. infoPtr = info.GetCachedPtr();
  342. Internal_CreateStartupSettings(buildFolder, infoPtr);
  343. }
  344. /// <summary>
  345. /// Returns a list of .NET framework managed assemblies (without extension) to be included for the specified platform.
  346. /// </summary>
  347. /// <param name="type">Platform type to retrieve the list of assemblies for.</param>
  348. /// <returns>A list of .NET framework managed assemblies (without extension) that will be included with the build.</returns>
  349. internal static string[] GetFrameworkAssemblies(PlatformType type)
  350. {
  351. return Internal_GetFrameworkAssemblies(type);
  352. }
  353. /// <summary>
  354. /// Returns the absolute path to the executable for the provided platform.
  355. /// </summary>
  356. /// <param name="type">Platform type to retrieve the executable location for.</param>
  357. /// <returns>Absolute path to the executable.</returns>
  358. internal static string GetMainExecutable(PlatformType type)
  359. {
  360. return Internal_GetMainExecutable(type);
  361. }
  362. /// <summary>
  363. /// Returns a list of semicolon separated defines that will be used when compiling scripts for the specified
  364. /// platform.
  365. /// </summary>
  366. /// <param name="type">Platfrom type to retrieve the defines for.</param>
  367. /// <returns>Semicolor separated defines that will be passed along to the script compiler.</returns>
  368. internal static string GetDefines(PlatformType type)
  369. {
  370. return Internal_GetDefines(type);
  371. }
  372. /// <summary>
  373. /// Returns an object containing all platform specific build data.
  374. /// </summary>
  375. /// <param name="type">Platform type to retrieve the data for.</param>
  376. /// <returns>An object containing all platform specific build data</returns>
  377. internal static PlatformInfo GetPlatformInfo(PlatformType type)
  378. {
  379. return Internal_GetPlatformInfo(type);
  380. }
  381. /// <summary>
  382. /// Types of various folders used by the build manager.
  383. /// </summary>
  384. private enum BuildFolder // Note: Must match C++ enum ScriptBuildFolder
  385. {
  386. /// <summary>Absolute path to the root folder where all the prebuilt binaries and data exist.</summary>
  387. SourceRoot,
  388. /// <summary>Absolute path to the root folder for a build for a specific platform.</summary>
  389. DestinationRoot,
  390. /// <summary>Folder where native binaries are stored. Relative to root.</summary>
  391. NativeBinaries,
  392. /// <summary>Folder where Banshee specific debug assemblies are stored. Relative to root.</summary>
  393. BansheeDebugAssemblies,
  394. /// <summary>Folder where Banshee specific release assemblies are stored. Relative to root.</summary>
  395. BansheeReleaseAssemblies,
  396. /// <summary>Folder where .NET framework assemblies are stored. Relative to root.</summary>
  397. FrameworkAssemblies,
  398. /// <summary>Folder where miscelaneous Mono files are stored. Relative to root.</summary>
  399. Mono,
  400. /// <summary>Folder where builtin data is stored. Relative to root.</summary>
  401. Data
  402. }
  403. [MethodImpl(MethodImplOptions.InternalCall)]
  404. private static extern PlatformType[] Internal_GetAvailablePlatforms();
  405. [MethodImpl(MethodImplOptions.InternalCall)]
  406. private static extern PlatformType Internal_GetActivePlatform();
  407. [MethodImpl(MethodImplOptions.InternalCall)]
  408. private static extern void Internal_SetActivePlatform(PlatformType value);
  409. [MethodImpl(MethodImplOptions.InternalCall)]
  410. private static extern PlatformInfo Internal_GetActivePlatformInfo();
  411. [MethodImpl(MethodImplOptions.InternalCall)]
  412. private static extern PlatformInfo Internal_GetPlatformInfo(PlatformType type);
  413. [MethodImpl(MethodImplOptions.InternalCall)]
  414. private static extern string[] Internal_GetFrameworkAssemblies(PlatformType type);
  415. [MethodImpl(MethodImplOptions.InternalCall)]
  416. private static extern string Internal_GetMainExecutable(PlatformType type);
  417. [MethodImpl(MethodImplOptions.InternalCall)]
  418. private static extern string Internal_GetDefines(PlatformType type);
  419. [MethodImpl(MethodImplOptions.InternalCall)]
  420. private static extern string[] Internal_GetNativeBinaries(PlatformType type);
  421. [MethodImpl(MethodImplOptions.InternalCall)]
  422. private static extern string Internal_GetBuildFolder(BuildFolder folder, PlatformType platform);
  423. [MethodImpl(MethodImplOptions.InternalCall)]
  424. private static extern void Internal_InjectIcons(string filePath, IntPtr info);
  425. [MethodImpl(MethodImplOptions.InternalCall)]
  426. private static extern void Internal_PackageResources(string buildFolder, IntPtr info);
  427. [MethodImpl(MethodImplOptions.InternalCall)]
  428. private static extern void Internal_CreateStartupSettings(string buildFolder, IntPtr info);
  429. }
  430. /** @} */
  431. }