private static void PerformPostBuild( BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) { BuildAction[] buildActions = BuildSettings.postBuildActions.buildActions; if (buildActions != null) { for (int i = 0; i < buildActions.Length; i++) { BuildAction action = buildActions[i]; // Check if execute method has been overriden. MethodInfo m = action.GetType().GetMethod("PerBuildExecute"); if (m.GetBaseDefinition().DeclaringType != m.DeclaringType && action.actionType == BuildAction.ActionType.PerPlatform) { // Check build filter and execute if true. if (action.filter == null || action.filter.Evaluate(releaseType, platform, architecture, distribution, configKey) && action.actionEnabled) { BuildNotificationList.instance.AddNotification(new BuildNotification( BuildNotification.Category.Notification, string.Format("Performing Post-Build Action ({0}/{1}).", i + 1, buildActions.Length), string.Format("{0}: {1}", action.actionName, configKey), true, null)); action.PerBuildExecute(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath); } else { BuildNotificationList.instance.AddNotification(new BuildNotification( BuildNotification.Category.Notification, string.Format("Skipping Post-Build Action ({0}/{1}).", i + 1, buildActions.Length), string.Format("{0}: {1}", action.actionName, configKey), true, null)); } } } } }
private void PopulateAvailablePlatforms() { if (availablePlatformTypeList.Count > 0) { return; } Type ti = typeof(BuildPlatform); availablePlatformNameList.Clear(); availablePlatformTypeList.Clear(); foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { foreach (Type t in asm.GetTypes()) { if (ti.IsAssignableFrom(t) && ti != t) { BuildPlatform instance = ScriptableObject.CreateInstance(t) as BuildPlatform; availablePlatformNameList.Add(instance.platformName); availablePlatformTypeList.Add(t); } } } }
public static void Generate( DateTime buildTime, string currentVersion = "", BuildReleaseType currentReleaseType = null, BuildPlatform currentBuildPlatform = null, BuildArchitecture currentBuildArchitecture = null, BuildDistribution currentBuildDistribution = null) { // Find the BuildConstants file. string currentFilePath = FindFile(); string filePath = !string.IsNullOrEmpty(currentFilePath) ? currentFilePath : Path.Combine(Constants.AssetsDirectoryName, DefaultFilePath); // Generate strings string versionString = currentVersion; string releaseTypeString = currentReleaseType == null ? NONE : SanitizeString(currentReleaseType.typeName); string platformString = currentBuildPlatform == null ? NONE : SanitizeString(currentBuildPlatform.platformName); string archString = currentBuildArchitecture == null ? NONE : SanitizeString(currentBuildArchitecture.name); string distributionString = currentBuildDistribution == null ? NONE : SanitizeString(currentBuildDistribution.distributionName); // Delete any existing version. if (File.Exists(filePath)) { File.Delete(filePath); } // Create a buffer that we'll use to check for any duplicated names. List <string> enumBuffer = new List <string>(); AssetDatabaseUtility.EnsureDirectoriesExist(); using (StreamWriter writer = new StreamWriter(filePath)) { // Start of file and class. writer.WriteLine("// This file is auto-generated. Do not modify or move this file."); writer.WriteLine(); writer.WriteLine("public static class BuildConstants"); writer.WriteLine("{"); // Write ReleaseType enum. writer.WriteLine(" public enum ReleaseType"); writer.WriteLine(" {"); writer.WriteLine(" {0},", NONE); enumBuffer.Add(NONE); foreach (BuildReleaseType releaseType in BuildSettings.releaseTypeList.releaseTypes) { string addedString = SanitizeString(releaseType.typeName); if (!enumBuffer.Contains(addedString)) { enumBuffer.Add(addedString); writer.WriteLine(" {0},", addedString); } } writer.WriteLine(" }"); writer.WriteLine(); // Validate ReleaseType string. if (!enumBuffer.Contains(releaseTypeString)) { releaseTypeString = NONE; } // Write Platform enum. enumBuffer.Clear(); writer.WriteLine(" public enum Platform"); writer.WriteLine(" {"); writer.WriteLine(" {0},", NONE); enumBuffer.Add(NONE); foreach (BuildPlatform platform in BuildSettings.platformList.platforms) { string addedString = SanitizeString(platform.platformName); if (platform.enabled && !enumBuffer.Contains(addedString)) { enumBuffer.Add(addedString); writer.WriteLine(" {0},", addedString); } } writer.WriteLine(" }"); writer.WriteLine(); // Validate Platform string. if (!enumBuffer.Contains(platformString)) { platformString = NONE; } // Write Architecture enum. enumBuffer.Clear(); writer.WriteLine(" public enum Architecture"); writer.WriteLine(" {"); writer.WriteLine(" {0},", NONE); enumBuffer.Add(NONE); foreach (BuildPlatform platform in BuildSettings.platformList.platforms) { if (platform.enabled) { foreach (BuildArchitecture arch in platform.architectures) { string addedString = SanitizeString(arch.name); if (arch.enabled && !enumBuffer.Contains(addedString)) { enumBuffer.Add(addedString); writer.WriteLine(" {0},", addedString); } } } } writer.WriteLine(" }"); writer.WriteLine(); // Validate Architecture string. if (!enumBuffer.Contains(archString)) { archString = NONE; } // Write Distribution enum. enumBuffer.Clear(); writer.WriteLine(" public enum Distribution"); writer.WriteLine(" {"); writer.WriteLine(" {0},", NONE); enumBuffer.Add(NONE); foreach (BuildPlatform platform in BuildSettings.platformList.platforms) { if (platform.enabled) { foreach (BuildDistribution dist in platform.distributionList.distributions) { string addedString = SanitizeString(dist.distributionName); if (dist.enabled && !enumBuffer.Contains(addedString)) { enumBuffer.Add(addedString); writer.WriteLine(" {0},", addedString); } } } } writer.WriteLine(" }"); writer.WriteLine(); // Validate Distribution string. if (!enumBuffer.Contains(distributionString)) { distributionString = NONE; } // Write current values. writer.WriteLine(" public static readonly System.DateTime buildDate = new System.DateTime({0});", buildTime.Ticks); writer.WriteLine(" public const string version = \"{0}\";", versionString); writer.WriteLine(" public const ReleaseType releaseType = ReleaseType.{0};", releaseTypeString); writer.WriteLine(" public const Platform platform = Platform.{0};", platformString); writer.WriteLine(" public const Architecture architecture = Architecture.{0};", archString); writer.WriteLine(" public const Distribution distribution = Distribution.{0};", distributionString); // End of class. writer.WriteLine("}"); writer.WriteLine(); } // Refresh AssetDatabse so that changes take effect. AssetDatabase.Refresh(); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); EditorGUILayout.BeginHorizontal(); property.serializedObject.Update(); bool show = property.isExpanded; UnityBuildGUIUtility.DropdownHeader("Build Platforms", ref show, false, GUILayout.ExpandWidth(true)); property.isExpanded = show; UnityBuildGUIUtility.HelpButton("Parameter-Details#build-platforms"); EditorGUILayout.EndHorizontal(); platformList = fieldInfo.GetValue(property.serializedObject.targetObject) as BuildPlatformList; PopulateAvailablePlatforms(); list = property.FindPropertyRelative("platforms"); list.serializedObject.Update(); if (show) { EditorGUILayout.BeginVertical(UnityBuildGUIUtility.dropdownContentStyle); DrawPlatforms(property); if (list.arraySize > 0) { GUILayout.Space(20); } // Draw all available platforms. GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); index = EditorGUILayout.Popup(index, availablePlatformNameList.ToArray(), UnityBuildGUIUtility.popupStyle, GUILayout.ExpandWidth(false), GUILayout.MaxWidth(250)); if (GUILayout.Button("Add Platform", GUILayout.ExpandWidth(false), GUILayout.MaxWidth(150))) { BuildPlatform addedBuildPlatform = ScriptableObject.CreateInstance(availablePlatformTypeList[index]) as BuildPlatform; platformList.platforms.Add(addedBuildPlatform); AssetDatabase.AddObjectToAsset(addedBuildPlatform, BuildSettings.instance); AssetDatabaseUtility.ImportAsset(AssetDatabase.GetAssetPath(BuildSettings.instance)); platformList.platforms[platformList.platforms.Count - 1].enabled = true; for (int i = platformList.platforms.Count - 1; i >= 0; i--) { if (!platformList.platforms[i].enabled) { platformList.platforms.RemoveAt(i); } } } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } EditorGUI.EndProperty(); }
private string[] RefreshPlatforms(string keyChain, ConfigDictionary refreshedConfigSet, ConfigDictionary prevConfigSet) { List <string> childKeys = new List <string>(); List <BuildPlatform> platforms = BuildSettings.platformList.platforms; for (int i = 0; i < platforms.Count; i++) { // Skip if platform is disabled or if it doesn't have any enabled architectures. if (!platforms[i].enabled || !platforms[i].atLeastOneArch) { continue; } string key = keyChain + "/" + platforms[i].platformName; Configuration relConfig = new Configuration(); // Check for duplicate key. if (refreshedConfigSet.ContainsKey(key)) { continue; } // Copy previous settings if they exist. if (prevConfigSet != null && prevConfigSet.ContainsKey(key)) { relConfig.enabled = prevConfigSet[key].enabled; } // Refresh architectures. BuildArchitecture[] architectures = platforms[i].architectures; if (architectures.Length > 0) { relConfig.childKeys = RefreshArchitectures(key, refreshedConfigSet, platforms[i].variantKey, architectures, platforms[i].distributionList.distributions, prevConfigSet); } // Scan ahead for other versions of this platform with different variants. for (int j = i; j < platforms.Count; j++) { BuildPlatform otherPlatform = platforms[j]; if (otherPlatform.platformName == platforms[i].platformName && otherPlatform.enabled && otherPlatform.atLeastOneArch) { List <string> currentKeys = new List <string>(relConfig.childKeys); string[] additionalKeys = RefreshArchitectures(key, refreshedConfigSet, otherPlatform.variantKey, otherPlatform.architectures, otherPlatform.distributionList.distributions, prevConfigSet); for (int k = 0; k < additionalKeys.Length; k++) { if (!currentKeys.Contains(additionalKeys[k])) { currentKeys.Add(additionalKeys[k]); } } relConfig.childKeys = currentKeys.ToArray(); } } // Save configuration. refreshedConfigSet.Add(key, relConfig); // Add key to list to send back to parent. childKeys.Add(key); } return(childKeys.ToArray()); }
public bool ParseKeychain(string keychain, out BuildReleaseType releaseType, out BuildPlatform platform, out BuildArchitecture architecture, out BuildDistribution distribution) { bool success = false; string[] keys = keychain.Split('/'); int keyCount = keys.Length; int targetKey = 0; releaseType = null; platform = null; architecture = null; distribution = null; // Parse release type. if (keyCount > targetKey) { for (int i = 0; i < BuildSettings.releaseTypeList.releaseTypes.Length; i++) { BuildReleaseType rt = BuildSettings.releaseTypeList.releaseTypes[i]; if (keys[targetKey] == rt.typeName) { releaseType = rt; break; } } } if (releaseType == null) { return(false); } // Parse platform. if (keyCount > ++targetKey) { // Scan ahead and try to parse a variant key. string variantKey = ""; if (keys[targetKey + 1].Contains("(")) { int startIndex = keys[targetKey + 1].IndexOf('('); int endIndex = keys[targetKey + 1].IndexOf(')'); variantKey = keys[targetKey + 1].Substring(startIndex + 1, endIndex - startIndex - 1); keys[targetKey + 1] = keys[targetKey + 1].Remove(startIndex).Trim(); } for (int i = 0; i < BuildSettings.platformList.platforms.Count; i++) { BuildPlatform p = BuildSettings.platformList.platforms[i]; if (keys[targetKey] == p.platformName && p.variantKey == variantKey) { platform = p; break; } } } if (platform == null) { return(false); } // Parse architecture. if (platform.architectures.Length == 1) { // Only one architecture, so it won't even appear in dictionary. Just get it directly. ++targetKey; architecture = platform.architectures[0]; success = true; } else if (keyCount > ++targetKey) { for (int i = 0; i < platform.architectures.Length; i++) { BuildArchitecture arch = platform.architectures[i]; if (keys[targetKey] == arch.name) { architecture = arch; success = true; break; } } } if (architecture == null) { return(false); } // TODO: Parse variants. // Parse distribution. if (keyCount > ++targetKey) { success = false; for (int i = 0; i < platform.distributionList.distributions.Length; i++) { BuildDistribution dist = platform.distributionList.distributions[i]; if (keys[targetKey] == dist.distributionName) { distribution = dist; success = true; break; } } } return(success); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); EditorGUILayout.BeginHorizontal(); property.serializedObject.Update(); bool show = property.isExpanded; UnityBuildGUIUtility.DropdownHeader("Build Platforms", ref show, false, GUILayout.ExpandWidth(true)); property.isExpanded = show; UnityBuildGUIUtility.HelpButton("Parameter-Details#build-platforms"); EditorGUILayout.EndHorizontal(); platformList = fieldInfo.GetValue(property.serializedObject.targetObject) as BuildPlatformList; PopulateAvailablePlatforms(); list = property.FindPropertyRelative("platforms"); list.serializedObject.Update(); if (show) { EditorGUILayout.BeginVertical(UnityBuildGUIUtility.dropdownContentStyle); // Draw all created/enabled platforms. int enabledCount = 0; for (int i = 0; i < list.arraySize; i++) { SerializedProperty platformProperty = list.GetArrayElementAtIndex(i); SerializedProperty platformEnabled = platformProperty.FindPropertyRelative("enabled"); if (platformEnabled.boolValue) { ++enabledCount; EditorGUILayout.PropertyField(platformProperty, GUILayout.MaxHeight(0)); } } if (enabledCount > 0) { GUILayout.Space(20); } // Draw all available platforms. GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); index = EditorGUILayout.Popup(index, availablePlatformNameList.ToArray(), UnityBuildGUIUtility.popupStyle, GUILayout.ExpandWidth(false), GUILayout.MaxWidth(250)); if (GUILayout.Button("Add Platform", GUILayout.ExpandWidth(false), GUILayout.MaxWidth(150))) { BuildPlatform addedBuildPlatform = GetBuildPlatform(availablePlatformTypeList[index]); platformList.platforms.Add(addedBuildPlatform); platformList.platforms[platformList.platforms.Count - 1].enabled = true; for (int i = platformList.platforms.Count - 1; i >= 0; i--) { if (!platformList.platforms[i].enabled) { platformList.platforms.RemoveAt(i); } } } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } EditorGUI.EndProperty(); }
private static bool BuildPlayer(string notification, BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, DateTime buildTime, BuildOptions options, string configKey) { bool success = true; if (options == BuildOptions.None) { options = releaseType.buildOptions; } // Generate build path string buildPath = GenerateBuildPath(BuildSettings.basicSettings.buildPath, releaseType, platform, architecture, distribution, buildTime); string binName = string.Format(architecture.binaryNameFormat, SanitizeFileName(releaseType.productName)); // Save current environment settings string preBuildDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(platform.targetGroup); string preBuildCompanyName = PlayerSettings.companyName; string preBuildProductName = PlayerSettings.productName; string preBuildBundleIdentifier = PlayerSettings.GetApplicationIdentifier(platform.targetGroup); // Configure environment settings to match the build configuration ConfigureEnvironment(releaseType, platform, architecture, distribution, buildTime); // Pre-build actions PerformPreBuild(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath); // Report build starting BuildNotificationList.instance.AddNotification(new BuildNotification( BuildNotification.Category.Notification, notification, configKey, true, null)); // Build player FileUtil.DeleteFileOrDirectory(buildPath); string error = ""; UnityEditor.Build.Reporting.BuildReport buildReport = BuildPipeline.BuildPlayer(releaseType.sceneList.GetSceneFileList(), Path.Combine(buildPath, binName), architecture.target, options); if (buildReport.summary.result == UnityEditor.Build.Reporting.BuildResult.Failed) { error = buildReport.summary.totalErrors + " occurred."; } if (!string.IsNullOrEmpty(error)) { success = false; BuildNotificationList.instance.AddNotification(new BuildNotification( BuildNotification.Category.Error, "Build Failed:", configKey.ToString() + "\n" + error, true, null)); } // Post-build actions PerformPostBuild(releaseType, platform, architecture, distribution, buildTime, ref options, configKey, buildPath); // Restore pre-build environment settings PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, preBuildDefines); PlayerSettings.companyName = preBuildCompanyName; PlayerSettings.productName = preBuildProductName; PlayerSettings.SetApplicationIdentifier(platform.targetGroup, preBuildBundleIdentifier); return(success); }
public static string ResolvePath(string prototype, BuildReleaseType releaseType, BuildPlatform buildPlatform, BuildArchitecture arch, BuildDistribution dist, DateTime buildTime) { StringBuilder sb = new StringBuilder(prototype); sb.Replace("$YEAR", buildTime.ToString("yyyy")); sb.Replace("$MONTH", buildTime.ToString("MM")); sb.Replace("$DAY", buildTime.ToString("dd")); sb.Replace("$TIME", buildTime.ToString("hhmmss")); string archName = arch.name; if (buildPlatform.variants != null && buildPlatform.variants.Length > 0) { archName += " (" + buildPlatform.variantKey.Replace(",", ", ") + ")"; } sb.Replace("$RELEASE_TYPE", SanitizeFolderName(releaseType.typeName)); sb.Replace("$PLATFORM", SanitizeFolderName(buildPlatform.platformName)); sb.Replace("$ARCHITECTURE", SanitizeFolderName(archName)); sb.Replace("$DISTRIBUTION", SanitizeFolderName(dist != null ? dist.distributionName : BuildConstantsGenerator.NONE)); sb.Replace("$VERSION", SanitizeFolderName(BuildSettings.productParameters.buildVersion)); sb.Replace("$BUILD", BuildSettings.productParameters.buildCounter.ToString()); sb.Replace("$PRODUCT_NAME", SanitizeFolderName(releaseType.productName)); return(sb.ToString()); }
public static string GenerateBuildPath(string prototype, BuildReleaseType releaseType, BuildPlatform buildPlatform, BuildArchitecture arch, BuildDistribution dist, DateTime buildTime) { string resolvedProto = ResolvePath(prototype, releaseType, buildPlatform, arch, dist, buildTime); string buildPath = Path.Combine(BuildSettings.basicSettings.baseBuildFolder, resolvedProto); buildPath = Path.GetFullPath(buildPath).TrimEnd('\\').TrimEnd('/'); return(buildPath); }
public void InitializeErrors() { AddNotification(new BuildNotification( BuildNotification.Category.Error, "No ReleaseType Found", "At least one ReleaseType is required to perform a build.", false, () => BuildSettings.releaseTypeList.releaseTypes.Length == 0)); AddNotification(new BuildNotification( BuildNotification.Category.Error, "No Build Platform Found", "At least one Build Platform with one enabled Architecture is required to perform a build.", false, () => { bool validError = true; int platformCount = BuildSettings.platformList.platforms.Count; if (platformCount > 0) { for (int i = 0; i < platformCount; i++) { BuildPlatform platform = BuildSettings.platformList.platforms[i]; if (platform.enabled && platform.atLeastOneArch) { validError = false; break; } } } return(validError); })); AddNotification(new BuildNotification( BuildNotification.Category.Error, "Invalid ReleaseType Name", "One or more ReleaseType names is invalid. They may not be empty or '" + BuildConstantsGenerator.NONE + "'.", false, () => { bool validError = false; int count = BuildSettings.releaseTypeList.releaseTypes.Length; for (int i = 0; i < count; i++) { string typeName = BuildSettings.releaseTypeList.releaseTypes[i].typeName.Trim(); if (string.IsNullOrEmpty(typeName) || typeName.Equals(BuildConstantsGenerator.NONE, StringComparison.OrdinalIgnoreCase)) { validError = true; break; } } return(validError); })); AddNotification(new BuildNotification( BuildNotification.Category.Error, "Invalid Distribution Name", "One or more Distribution names is invalid. They may not be empty or '" + BuildConstantsGenerator.NONE + "'.", false, () => { bool validError = false; int platformCount = BuildSettings.platformList.platforms.Count; for (int i = 0; i < platformCount; i++) { BuildPlatform platform = BuildSettings.platformList.platforms[i]; int distroCount = platform.distributionList.distributions.Length; for (int j = 0; j < distroCount; j++) { string distributionName = platform.distributionList.distributions[j].distributionName.Trim(); if (string.IsNullOrEmpty(distributionName) || distributionName.Equals(BuildConstantsGenerator.NONE, StringComparison.OrdinalIgnoreCase)) { validError = true; break; } } } return(validError); })); }