Пример #1
0
        public override BuildStepResult RunBuildStep(BuildContext context)
        {
            var arguments  = BuildContextInternals.GetBuildSettings(context).name;
            var profile    = GetRequiredComponent <DotsRuntimeBuildProfile>(context);
            var workingDir = profile.BeeRootDirectory;
            var outputDir  = new DirectoryInfo(this.GetOutputBuildDirectory(context));

            var result = BeeTools.Run(arguments, workingDir, context.BuildProgress);

            outputDir.Combine("Logs").GetFile("BuildLog.txt").WriteAllText(result.Output);
            workingDir.GetFile("runbuild" + ShellScriptExtension()).UpdateAllText(result.Command);

            if (result.Failed)
            {
                return(Failure(result.Error));
            }

            if (!string.IsNullOrEmpty(profile.ProjectName))
            {
                var outputTargetFile = outputDir.GetFile(profile.ProjectName + profile.Target.ExecutableExtension);
                context.SetValue(new DotsRuntimeBuildArtifact {
                    OutputTargetFile = outputTargetFile
                });
            }

            return(Success());
        }
Пример #2
0
        public override BuildStepResult RunBuildStep(BuildContext context)
        {
            m_TemporaryFileTracker = new TemporaryFileTracker();

            // Delete SubScenes build folder defensively (Eg. if unity crashes during build)
            var streamingAssetsSubscenes = "Assets/StreamingAssets/SubScenes";

            FileUtil.DeleteFileOrDirectory(streamingAssetsSubscenes);

            m_TemporaryFileTracker.CreateDirectory(streamingAssetsSubscenes);

            List <(string sourceFile, string destinationFile)> filesToCopy = new List <(string sourceFile, string destinationFile)>();

            void RegisterFileCopy(string sourceFile, string destinationFile)
            {
                filesToCopy.Add((sourceFile, destinationFile));
            }

            SubSceneBuildCode.PrepareAdditionalFiles(BuildContextInternals.GetBuildConfigurationGUID(context), type => GetRequiredComponent(context, type), RegisterFileCopy, Application.streamingAssetsPath, $"Library/SubsceneBundles");

            foreach (var(sourceFile, targetFile) in filesToCopy)
            {
                m_TemporaryFileTracker.TrackFile(targetFile);
                File.Copy(sourceFile, targetFile, true);
            }

            return(Success());
        }
Пример #3
0
        public override BuildResult Run(BuildContext context)
        {
            var manifest           = context.BuildManifest;
            var buildConfiguration = BuildContextInternals.GetBuildConfiguration(context);
            var profile            = context.GetComponentOrDefault <DotsRuntimeBuildProfile>();
            var rootAssembly       = context.GetComponentOrDefault <DotsRuntimeRootAssembly>();
            var targetName         = rootAssembly.MakeBeeTargetName(context.BuildConfigurationName);
            var scenes             = context.GetComponentOrDefault <SceneList>();
            var firstScene         = scenes.GetScenePathsForBuild().FirstOrDefault();

            s_AssemblyCache.BaseAssemblies = rootAssembly.RootAssembly.asset;
            s_AssemblyCache.PlatformName   = profile.Target.UnityPlatformName;

            // Record any log errors/exceptions to be able to stop the build if any
            ExportConfigurationLogHandler logHandler = new ExportConfigurationLogHandler();

            logHandler.Hook();

            using (var tmpWorld = new World(ConfigurationScene.Guid.ToString()))
            {
                var dataDirInfo =
                    WorldExport.GetOrCreateDataDirectoryFrom(rootAssembly.StagingDirectory.Combine(targetName));
                var logDirectory = WorldExport.GetOrCreateLogDirectoryFrom(targetName);
                var subScenePath = WorldExport
                                   .GetOrCreateSubSceneDirectoryFrom(rootAssembly.StagingDirectory.Combine(targetName)).ToString();
                var outputDir = BuildStepGenerateBeeFiles.GetFinalOutputDirectory(context, targetName);

                var hasFilter = context.TryGetComponent <ConversionSystemFilterSettings>(out var conversionFilter);

                // Run configuration systems
                ConfigurationSystemGroup configSystemGroup = tmpWorld.GetOrCreateSystem <ConfigurationSystemGroup>();
                var systems = TypeCache.GetTypesDerivedFrom(typeof(ConfigurationSystemBase));
                foreach (var type in systems)
                {
                    if (hasFilter && !conversionFilter.ShouldRunConversionSystem(type))
                    {
                        continue;
                    }

                    ConfigurationSystemBase baseSys = (ConfigurationSystemBase)tmpWorld.GetOrCreateSystem(type);
                    baseSys.BuildContext     = context;
                    baseSys.AssemblyCache    = s_AssemblyCache;
                    baseSys.LogDirectoryPath = logDirectory.FullName;
                    configSystemGroup.AddSystemToUpdateList(baseSys);
                }

                configSystemGroup.SortSystems();
                configSystemGroup.Update();

                // Export configuration scene
                var writeEntitySceneSettings = new WriteEntitySceneSettings()
                {
                    Codec              = Codec.LZ4,
                    IsDotsRuntime      = true,
                    OutputPath         = subScenePath,
                    BuildAssemblyCache = s_AssemblyCache
                };
                var(decompressedSize, compressedSize) = EditorEntityScenes.WriteEntitySceneSection(
                    tmpWorld.EntityManager, ConfigurationScene.Guid, "0", null, writeEntitySceneSettings,
                    out var objectRefCount, out var objRefs, default);
Пример #4
0
        /// <summary>
        /// Get the output build directory for this <see cref="BuildStep"/>.
        /// The output build directory can be overridden using a <see cref="OutputBuildDirectory"/> component.
        /// </summary>
        /// <param name="step">This build step.</param>
        /// <param name="context">The build context used throughout this build.</param>
        /// <returns>The output build directory.</returns>
        public static string GetOutputBuildDirectory(this BuildStep step, BuildContext context)
        {
            if (step.HasOptionalComponent <OutputBuildDirectory>(context))
            {
                return(step.GetOptionalComponent <OutputBuildDirectory>(context).OutputDirectory);
            }
            var settings = BuildContextInternals.GetBuildSettings(context);

            return($"Builds/{settings.name}");
        }
Пример #5
0
        public override BuildStepResult RunBuildStep(BuildContext context)
        {
            var manifest  = context.BuildManifest;
            var profile   = GetRequiredComponent <DotsRuntimeBuildProfile>(context);
            var outputDir = profile.BeeRootDirectory;

            var buildSettingsJObject = new JObject();

            BuildProgramDataFileWriter.WriteAll(outputDir.FullName);

            if (HasOptionalComponent <DotsRuntimeScriptingDefines>(context))
            {
                buildSettingsJObject["ScriptingDefines"] = new JArray(GetOptionalComponent <DotsRuntimeScriptingDefines>(context).ScriptingDefines);
            }

            buildSettingsJObject["PlatformTargetIdentifier"] = profile.Target.BeeTargetName;
            buildSettingsJObject["UseBurst"] = profile.EnableBurst;
            buildSettingsJObject["EnableManagedDebugging"] = profile.EnableManagedDebugging;
            buildSettingsJObject["RootAssembly"]           = profile.RootAssembly.name;
            buildSettingsJObject["EnableMultiThreading"]   = profile.EnableMultiThreading;
            buildSettingsJObject["FinalOutputDirectory"]   = this.GetOutputBuildDirectory(context);
            buildSettingsJObject["DotsConfig"]             = profile.Configuration.ToString();

            var buildSettings = BuildContextInternals.GetBuildSettings(context);

            //web is broken until we can get all components that modify a particular interface
            foreach (var component in BuildSettingsInternals.GetComponents <IDotsRuntimeBuildModifier>(buildSettings))
            {
                component.Modify(buildSettingsJObject);
            }

            var settingsDir = new NPath(outputDir.FullName).Combine("settings");

            settingsDir.Combine($"{buildSettings.name}.json")
            .UpdateAllText(buildSettingsJObject.ToString());

            WriteBeeExportManifestFile(profile, manifest);

            profile.Target.WriteBeeConfigFile(profile.BeeRootDirectory.ToString());

            return(Success());
        }
        /// <summary>
        /// Returns true if we need to use BuildOptions.AutoRunPlayer.
        /// For ex., when platform doesn't have RunStep implemented yet.
        /// This function should be removed when we'll have run steps implemented for all platforms
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private static bool UseAutoRunPlayer(BuildContext context)
        {
            var settings = BuildContextInternals.GetBuildSettings(context);
            var pipeline = settings.GetComponent <IBuildPipelineComponent>().Pipeline;
            var runStep  = pipeline.RunStep;

            // RunStep is provided no need to use AutoRunPlayer
            if (runStep != null && runStep.GetType() != typeof(RunStepNotImplemented))
            {
                return(false);
            }

            // See dots\Samples\Library\PackageCache\[email protected]\Editor\Unity.Build\BuildSettingsScriptedImporterEditor.cs
            const string k_CurrentActionKey = "BuildAction-CurrentAction";

            if (!EditorPrefs.HasKey(k_CurrentActionKey))
            {
                return(false);
            }

            var value = EditorPrefs.GetInt(k_CurrentActionKey);

            return(value == 1);
        }
        public static bool Prepare(BuildContext context, BuildStep step, bool liveLink, TemporaryFileTracker tracker, out BuildStepResult failure, out BuildPlayerOptions buildPlayerOptions)
        {
            buildPlayerOptions = default;
            var profile = step.GetRequiredComponent <ClassicBuildProfile>(context);

            if (profile.Target <= 0)
            {
                failure = BuildStepResult.Failure(step, $"Invalid build target '{profile.Target.ToString()}'.");
                return(false);
            }

            if (profile.Target != EditorUserBuildSettings.activeBuildTarget)
            {
                failure = BuildStepResult.Failure(step, $"{nameof(EditorUserBuildSettings.activeBuildTarget)} must be switched before {nameof(BuildStepBuildClassicPlayer)} step.");
                return(false);
            }

            var scenesList = step.GetRequiredComponent <SceneList>(context).GetScenePathsForBuild();

            if (scenesList.Length == 0)
            {
                failure = BuildStepResult.Failure(step, "There are no scenes to build.");
                return(false);
            }

            var outputPath = step.GetOutputBuildDirectory(context);

            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            var productName      = step.GetRequiredComponent <GeneralSettings>(context).ProductName;
            var extension        = profile.GetExecutableExtension();
            var locationPathName = Path.Combine(outputPath, productName + extension);

            buildPlayerOptions = new BuildPlayerOptions()
            {
                scenes           = scenesList,
                target           = profile.Target,
                locationPathName = locationPathName,
                targetGroup      = UnityEditor.BuildPipeline.GetBuildTargetGroup(profile.Target),
            };

            buildPlayerOptions.options = BuildOptions.None;
            switch (profile.Configuration)
            {
            case BuildConfiguration.Debug:
                buildPlayerOptions.options |= BuildOptions.AllowDebugging | BuildOptions.Development;
                break;

            case BuildConfiguration.Develop:
                buildPlayerOptions.options |= BuildOptions.Development;
                break;
            }

            var sourceBuild = step.GetOptionalComponent <InternalSourceBuildConfiguration>(context);

            if (sourceBuild.Enabled)
            {
                buildPlayerOptions.options |= BuildOptions.InstallInBuildFolder;
            }

            if (UseAutoRunPlayer(context))
            {
                UnityEngine.Debug.Log($"Using BuildOptions.AutoRunPlayer, since RunStep is not provided for {profile.Target}");
                buildPlayerOptions.options |= BuildOptions.AutoRunPlayer;
            }

            if (liveLink)
            {
                File.WriteAllText(tracker.TrackFile(k_BootstrapFilePath), BuildContextInternals.GetBuildSettingsGUID(context));
            }
            else
            {
                // Make sure we didn't leak a bootstrap file from a previous crashed build
                tracker.EnsureFileDoesntExist(k_BootstrapFilePath);
            }

            failure = default;
            return(true);
        }
Пример #8
0
        public override BuildStepResult RunBuildStep(BuildContext context)
        {
            m_TempFileTracker = new TemporaryFileTracker();
            var generalSettings = GetRequiredComponent <GeneralSettings>(context);
            var profile         = GetRequiredComponent <ClassicBuildProfile>(context);
            var sceneList       = GetRequiredComponent <SceneList>(context);

            if (profile.Target <= 0)
            {
                return(BuildStepResult.Failure(this, $"Invalid build target '{profile.Target.ToString()}'."));
            }

            if (profile.Target != EditorUserBuildSettings.activeBuildTarget)
            {
                return(BuildStepResult.Failure(this, $"{nameof(EditorUserBuildSettings.activeBuildTarget)} must be switched before {nameof(BuildStepBuildClassicLiveLink)} step."));
            }

            //any initial scenes that cannot be live linked must be added to the scenes list
            var embeddedScenes = new List <string>(sceneList.GetScenePathsToLoad().Where(path => !SceneImporterData.CanLiveLinkScene(path)));

            //if none of the startup scenes are embedded, add empty scene
            if (embeddedScenes.Count == 0)
            {
                embeddedScenes.Add(k_EmptyScenePath);
            }

            //add any additional scenes that cannot be live linked
            foreach (var path in sceneList.GetScenePathsForBuild())
            {
                if (!SceneImporterData.CanLiveLinkScene(path) && !embeddedScenes.Contains(path))
                {
                    embeddedScenes.Add(path);
                }
            }

            var outputPath = this.GetOutputBuildDirectory(context);

            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            var buildPlayerOptions = new BuildPlayerOptions
            {
                scenes           = embeddedScenes.ToArray(),
                target           = profile.Target,
                locationPathName = Path.Combine(outputPath, generalSettings.ProductName + profile.GetExecutableExtension()),
                targetGroup      = UnityEditor.BuildPipeline.GetBuildTargetGroup(profile.Target),
                options          = BuildOptions.Development | BuildOptions.ConnectToHost
            };

            var sourceBuild = GetOptionalComponent <SourceBuildConfiguration>(context);

            if (sourceBuild.Enabled)
            {
                buildPlayerOptions.options |= BuildOptions.InstallInBuildFolder;
            }

            if (profile.Configuration == BuildType.Debug)
            {
                buildPlayerOptions.options |= BuildOptions.AllowDebugging;
            }

            if (UseAutoRunPlayer(context))
            {
                UnityEngine.Debug.Log($"Using BuildOptions.AutoRunPlayer, since RunStep is not provided for {profile.Target}");
                buildPlayerOptions.options |= BuildOptions.AutoRunPlayer;
            }

            var settings = BuildContextInternals.GetBuildConfiguration(context);

            if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(settings, out var guid, out long _))
            {
                using (var stream = new StreamWriter(m_TempFileTracker.TrackFile(k_BootstrapPath)))
                {
                    stream.WriteLine(guid);
                    stream.WriteLine(EditorAnalyticsSessionInfo.id);
                }
            }

            var report = UnityEditor.BuildPipeline.BuildPlayer(buildPlayerOptions);
            var result = new BuildStepResult(this, report);

            context.SetValue(report);
            return(result);
        }
        public override BuildStepResult RunBuildStep(BuildContext context)
        {
            m_TemporaryFileTracker = new TemporaryFileTracker();

            var profile = GetRequiredComponent <ClassicBuildProfile>(context);

            if (profile.Target == UnityEditor.BuildTarget.NoTarget)
            {
                return(Failure($"Invalid build target '{profile.Target.ToString()}'."));
            }
            if (profile.Target != EditorUserBuildSettings.activeBuildTarget)
            {
                return(Failure($"ActiveBuildTarget must be switched before the {nameof(BuildStepSubSceneBundles)} step."));
            }

            var buildConfigurationGuid = new Hash128(BuildContextInternals.GetBuildConfigurationGUID(context));
            var content   = new UnityEditor.Build.Pipeline.BundleBuildContent(new AssetBundleBuild[0]);
            var sceneList = GetRequiredComponent <SceneList>(context);
            var visited   = new HashSet <Hash128>();

            foreach (var scenePath in sceneList.GetScenePathsForBuild())
            {
                var sceneGuid     = AssetDatabase.AssetPathToGUID(scenePath);
                var subSceneGuids = SceneMetaDataImporter.GetSubSceneGuids(sceneGuid);
                foreach (var subSceneGuid in subSceneGuids)
                {
                    if (!visited.Add(subSceneGuid))
                    {
                        continue;
                    }

                    var hash128Guid = EntityScenesPaths.CreateBuildConfigurationSceneFile(subSceneGuid, buildConfigurationGuid);
                    content.CustomAssets.Add(new UnityEditor.Build.Pipeline.Interfaces.CustomContent
                    {
                        Asset     = hash128Guid,
                        Processor = SubSceneImporter.ConvertToBuild
                    });
                }
            }

            if (content.CustomAssets.Count == 0)
            {
                return(Success());
            }

            var buildPath = Path.GetDirectoryName(EntityScenesPaths.GetLoadPath(new Hash128(), EntityScenesPaths.PathType.EntitiesUnityObjectReferences, 0));

            // Delete SubScenes build folder defensively (Eg. if unity crashes during build)
            FileUtil.DeleteFileOrDirectory(buildPath);

            m_TemporaryFileTracker.CreateDirectory(buildPath);

            var group      = UnityEditor.BuildPipeline.GetBuildTargetGroup(profile.Target);
            var parameters = new UnityEditor.Build.Pipeline.BundleBuildParameters(profile.Target, group, buildPath);

            parameters.BundleCompression = UnityEngine.BuildCompression.Uncompressed;

            var status = UnityEditor.Build.Pipeline.ContentPipeline.BuildAssetBundles(parameters, content, out UnityEditor.Build.Pipeline.Interfaces.IBundleBuildResults result);

            context.SetValue(result);

            var succeeded = status >= UnityEditor.Build.Pipeline.ReturnCode.Success;

            return(succeeded ? Success() : Failure($"BuildAssetBundles failed with status '{status}'."));
        }
Пример #10
0
 public TinyExportDriver(BuildContext context, DirectoryInfo exportDataRoot)
 {
     BuildSettings    = BuildContextInternals.GetBuildSettings(context);
     m_ExportDataRoot = exportDataRoot;
 }