/// <summary> /// Synchronously builds an AAB given the specified options and existing Android Player on disk. /// </summary> /// <returns>An error message if there was an error, or null if successful.</returns> public string CreateBundle(string aabFilePath, AssetPackConfig assetPackConfig) { if (_buildStatus != BuildStatus.Running) { throw new Exception("Unexpected call to CreateBundle() with status: " + _buildStatus); } var moduleDirectoryList = new List <DirectoryInfo>(); var workingDirectory = new DirectoryInfo(_workingDirectoryPath); var configParams = new BundletoolHelper.BuildBundleConfigParams { defaultTcfSuffix = TextureTargetingTools.GetBundleToolTextureCompressionFormatName( assetPackConfig.DefaultTextureCompressionFormat), minSdkVersion = _minSdkVersion }; // Create asset pack module directories. var index = 0; var assetPacks = assetPackConfig.DeliveredAssetPacks; foreach (var entry in assetPacks) { DisplayProgress( string.Format("Processing asset pack {0} of {1}", index + 1, assetPacks.Count), Mathf.Lerp(0.1f, ProgressCreateBaseModule, (float)index / assetPacks.Count)); index++; var assetPackName = entry.Key; var assetPack = entry.Value; configParams.enableTcfTargeting |= assetPack.CompressionFormatToAssetBundleFilePath != null; configParams.enableTcfTargeting |= assetPack.CompressionFormatToAssetPackDirectoryPath != null; configParams.containsInstallTimeAssetPack |= assetPack.DeliveryMode == AssetPackDeliveryMode.InstallTime; var assetPackDirectoryInfo = workingDirectory.CreateSubdirectory(assetPackName); var assetPackErrorMessage = CreateAssetPackModule(assetPackName, assetPack, assetPackDirectoryInfo); if (assetPackErrorMessage != null) { // Already displayed the error. return(assetPackErrorMessage); } moduleDirectoryList.Add(assetPackDirectoryInfo); } // Create base module directory. var baseDirectory = workingDirectory.CreateSubdirectory(AndroidAppBundle.BaseModuleName); IList <string> bundleMetadata; var baseErrorMessage = CreateBaseModule(baseDirectory, out bundleMetadata); if (baseErrorMessage != null) { // Already displayed the error. return(baseErrorMessage); } moduleDirectoryList.Add(baseDirectory); // Create a ZIP file for each module directory. var moduleFiles = new List <string>(); var numModules = moduleDirectoryList.Count; for (var i = 0; i < numModules; i++) { if (numModules == 1) { DisplayProgress("Processing base module", ProgressProcessModules); } else { DisplayProgress( string.Format("Processing module {0} of {1}", i + 1, numModules), Mathf.Lerp(ProgressProcessModules, ProgressRunBundletool, (float)i / numModules)); } var moduleDirectoryInfo = moduleDirectoryList[i]; var destinationDirectoryInfo = GetDestinationSubdirectory(moduleDirectoryInfo); // Create ZIP file path, for example /path/to/files/base becomes /path/to/files/base/base.zip var zipFilePath = Path.Combine(moduleDirectoryInfo.FullName, moduleDirectoryInfo.Name + ".zip"); var zipErrorMessage = _zipUtils.CreateZipFile(zipFilePath, destinationDirectoryInfo.FullName, "."); if (zipErrorMessage != null) { return(DisplayBuildError("Zip creation", zipErrorMessage)); } moduleFiles.Add(zipFilePath); } DisplayProgress("Running bundletool", ProgressRunBundletool); var buildBundleErrorMessage = _bundletool.BuildBundle(aabFilePath, moduleFiles, bundleMetadata, configParams); if (buildBundleErrorMessage != null) { return(DisplayBuildError("Bundletool", buildBundleErrorMessage)); } // Only sign the .aab if a custom keystore is configured. if (_jarSigner.UseCustomKeystore) { DisplayProgress("Signing bundle", 0.9f); var signingErrorMessage = _jarSigner.Sign(aabFilePath); if (signingErrorMessage != null) { return(DisplayBuildError("Signing", signingErrorMessage)); } } else { Debug.LogFormat("Skipped signing since a Custom Keystore isn't configured in Android Player Settings"); } MoveSymbolsZipFile(aabFilePath); Debug.LogFormat("Finished building app bundle: {0}", aabFilePath); _finishedAabFilePath = aabFilePath; _buildStatus = BuildStatus.Succeeding; return(null); }
/// <summary> /// Synchronously builds an Android App Bundle at the specified path using the specified Android Player. /// </summary> /// <returns>True if the build succeeded, false if it failed or was cancelled.</returns> public bool CreateBundle(string aabFilePath, string androidPlayerFilePath, AssetPackConfig assetPackConfig) { if (_buildStatus != BuildStatus.Running) { throw new Exception("Unexpected call to CreateBundle() with status: " + _buildStatus); } var moduleDirectoryList = new List <DirectoryInfo>(); var workingDirectory = new DirectoryInfo(_workingDirectoryPath); var configParams = new BundletoolHelper.BuildBundleConfigParams { defaultTcfSuffix = TextureTargetingTools.GetBundleToolTextureCompressionFormatName( assetPackConfig.DefaultTextureCompressionFormat), minSdkVersion = _minSdkVersion }; // Create asset pack module directories. var index = 0; var assetPacks = assetPackConfig.DeliveredAssetPacks; foreach (var entry in assetPacks) { DisplayProgress( string.Format("Processing asset pack {0} of {1}", index + 1, assetPacks.Count), Mathf.Lerp(0.1f, ProgressCreateBaseModule, (float)index / assetPacks.Count)); index++; var assetPackName = entry.Key; var assetPack = entry.Value; configParams.enableTcfTargeting |= assetPack.CompressionFormatToAssetBundleFilePath != null; configParams.containsInstallTimeAssetPack |= assetPack.DeliveryMode == AssetPackDeliveryMode.InstallTime; var assetPackDirectoryInfo = workingDirectory.CreateSubdirectory(assetPackName); if (!CreateAssetPackModule(assetPackName, assetPack, assetPackDirectoryInfo)) { return(false); } moduleDirectoryList.Add(assetPackDirectoryInfo); } // Create base module directory. var baseDirectory = workingDirectory.CreateSubdirectory(AndroidAppBundle.BaseModuleName); IList <string> bundleMetadata; if (!CreateBaseModule(baseDirectory, androidPlayerFilePath, out bundleMetadata)) { return(false); } moduleDirectoryList.Add(baseDirectory); // Create a ZIP file for each module directory. var moduleFiles = new List <string>(); var numModules = moduleDirectoryList.Count; for (var i = 0; i < numModules; i++) { if (numModules == 1) { DisplayProgress("Processing base module", ProgressProcessModules); } else { DisplayProgress( string.Format("Processing module {0} of {1}", i + 1, numModules), Mathf.Lerp(ProgressProcessModules, ProgressRunBundletool, (float)i / numModules)); } var moduleDirectoryInfo = moduleDirectoryList[i]; var destinationDirectoryInfo = GetDestinationSubdirectory(moduleDirectoryInfo); // Create ZIP file path, for example /path/to/files/base becomes /path/to/files/base/base.zip var zipFilePath = Path.Combine(moduleDirectoryInfo.FullName, moduleDirectoryInfo.Name + ".zip"); var zipErrorMessage = _zipUtils.CreateZipFile(zipFilePath, destinationDirectoryInfo.FullName, "."); if (zipErrorMessage != null) { DisplayBuildError("Zip creation", zipErrorMessage); return(false); } moduleFiles.Add(zipFilePath); } // If the .aab file exists, EditorUtility.SaveFilePanel() has already prompted for whether to overwrite. // Therefore, prevent Bundletool from throwing an IllegalArgumentException that "File already exists." File.Delete(aabFilePath); DisplayProgress("Running bundletool", ProgressRunBundletool); var buildBundleErrorMessage = _bundletool.BuildBundle(aabFilePath, moduleFiles, bundleMetadata, configParams); if (buildBundleErrorMessage != null) { DisplayBuildError("bundletool", buildBundleErrorMessage); return(false); } DisplayProgress("Signing bundle", 0.9f); var signingErrorMessage = _apkSigner.SignZip(aabFilePath); if (signingErrorMessage != null) { DisplayBuildError("Signing", signingErrorMessage); return(false); } Debug.LogFormat("Finished building app bundle: {0}", aabFilePath); _finishedAabFilePath = aabFilePath; _buildStatus = BuildStatus.Succeeding; return(true); }
private string CreateBundle(List <DirectoryInfo> moduleDirectoryList, CreateBundleOptions options, IList <string> bundleMetadata = null) { // Create a ZIP file for each module directory. var moduleFiles = new List <string>(); var numModules = moduleDirectoryList.Count; for (var i = 0; i < numModules; i++) { if (numModules == 1) { DisplayProgress("Processing base module", ProgressProcessModules); } else { DisplayProgress( string.Format("Processing module {0} of {1}", i + 1, numModules), Mathf.Lerp(ProgressProcessModules, ProgressRunBundletool, (float)i / numModules)); } var moduleDirectoryInfo = moduleDirectoryList[i]; var destinationDirectoryInfo = GetDestinationSubdirectory(moduleDirectoryInfo); // Create ZIP file path, for example /path/to/files/base becomes /path/to/files/base/base.zip var zipFilePath = Path.Combine(moduleDirectoryInfo.FullName, moduleDirectoryInfo.Name + ".zip"); var zipErrorMessage = _zipUtils.CreateZipFile(zipFilePath, destinationDirectoryInfo.FullName, "."); if (zipErrorMessage != null) { return(DisplayBuildError("Zip creation", zipErrorMessage)); } moduleFiles.Add(zipFilePath); } if (bundleMetadata == null) { bundleMetadata = new List <string>(); } DisplayProgress("Running bundletool", ProgressRunBundletool); var configParams = CreateBuildBundleConfigParams(options); var buildBundleErrorMessage = _bundletool.BuildBundle(options.AabFilePath, moduleFiles, bundleMetadata, configParams); if (buildBundleErrorMessage != null) { return(DisplayBuildError("Bundletool", buildBundleErrorMessage)); } // Only sign the .aab if a custom keystore is configured. if (_jarSigner.UseCustomKeystore) { DisplayProgress("Signing bundle", 0.9f); var signingErrorMessage = _jarSigner.Sign(options.AabFilePath); if (signingErrorMessage != null) { Debug.LogError("Failed to sign"); return(DisplayBuildError("Signing", signingErrorMessage)); } } else { Debug.LogFormat("Skipped signing since a Custom Keystore isn't configured in Android Player Settings"); } MoveSymbolsZipFile(options.AabFilePath); return(null); }