static void BuildJobSlave()
        {
            string   text = File.ReadAllText("./build.json");
            BuildJob job  = JsonUtility.FromJson <BuildJob>(text);

            BuildJob(job);
        }
Exemple #2
0
        static AssetBundleManifest BuildJob(BuildJob job)
        {
            var    sw             = Stopwatch.StartNew();
            var    unity_manifest = job.Build();
            string resultFile     = string.Format("{0}/result_{1}.json", job.output, job.slaveID);

            sw.Stop();
            return(OutputResult(resultFile, sw.ElapsedMilliseconds * .001f, unity_manifest));
        }
        static AssetBundleManifest BuildJob(BuildJob job)
        {
            var    sw             = new Stopwatch();
            var    unity_manifest = job.Build();
            string resultFile     = string.Format("{0}/result_{1}.json", job.output, job.slaveID);

            sw.Stop();
            return(OutputResult(resultFile, sw.UseSecs, unity_manifest));
        }
Exemple #4
0
        static void BuildJobSlave()
        {
            string buildJobPath = null;

            string[] CommandLineArgs = System.Environment.GetCommandLineArgs();
            int      i = ArrayUtility.FindIndex <string>(CommandLineArgs, (x) => x == "-buildJob");

            if (i != -1)
            {
                buildJobPath = CommandLineArgs[i + 1];
            }
            string   text = File.ReadAllText(buildJobPath);
            BuildJob job  = JsonUtility.FromJson <BuildJob>(text);

            BuildJob(job);
        }
        public BuildJob[] BuildJobs(int nJobs, string output, BuildAssetBundleOptions options, BuildTarget target)
        {
            Assert.IsTrue(nJobs > 0);

            BuildDependency();

            HashSet <BuildGroup>          groups = new HashSet <BuildGroup>();
            Func <BundleNode, BuildGroup> lookUp = (BundleNode node) =>
            {
                foreach (var group in groups)
                {
                    if (group.Contains(node))
                    {
                        return(group);
                    }
                }
                return(null);
            };
            Action <BundleNode, BundleNode> merge = (a, b) =>
            {
                var group1 = lookUp(a);
                var group2 = lookUp(b);
                if (group1 != group2)
                {
                    group1.UnionWith(group2);
                    groups.Remove(group2);
                }
            };

            foreach (var bundle in bundleNodes.Values)
            {
                var group = new BuildGroup();
                group.Add(bundle);
                groups.Add(group);
            }

            foreach (var bundle in bundleNodes.Values)
            {
                foreach (var dep in bundle.deps)
                {
                    merge(bundle, dep);
                }
            }

            while (groups.Count > nJobs)
            {
                List <BuildGroup> sortedGroups = new List <BuildGroup>(groups);
                sortedGroups.Sort((a, b) => { return(a.Weight.CompareTo(b.Weight)); });

                var g1 = sortedGroups[0];
                var g2 = sortedGroups[1];
                g1.UnionWith(g2);
                groups.Remove(g2);
            }

            List <BuildJob> jobs = new List <BuildJob>();

            foreach (var group in groups)
            {
                BuildJob job = new BuildJob();
                job.output  = output;
                job.slaveID = jobs.Count;
                job.options = (int)options;
                job.target  = (int)target;
                List <BuildJob.AssetBundleBuild> jobBuilds = new List <BuildJob.AssetBundleBuild>();
                foreach (BundleNode bn in group)
                {
                    var jobBuild = new BuildJob.AssetBundleBuild();
                    jobBuild.assetBundleName = bn.bundleName;
                    jobBuild.assetNames      = new List <string>(bn.assets.Keys).ToArray();
                    jobBuild.weight          = bn.weight;
                    job.weight += bn.weight;
                    jobBuilds.Add(jobBuild);
                }
                job.builds = jobBuilds.ToArray();
                jobs.Add(job);
            }
            return(jobs.ToArray());
        }
Exemple #6
0
        public static AssetBundleManifest BuildAssetBundles(string output, AssetBundleBuild[] builds, BuildAssetBundleOptions options, BuildTarget target)
        {
            output = Path.GetFullPath(output);

            var tree = new BuildTree();

            foreach (var build in builds)
            {
                foreach (var asset in build.assetNames)
                {
                    tree.AddBuildAsset(asset, build.assetBundleName);
                }
            }

            int slaveCount = System.Environment.ProcessorCount; //TODO:
            var jobs       = tree.BuildJobs(Mathf.Max(slaveCount, 1), output, options, target);

            AssetBundleManifest[] results = new AssetBundleManifest[jobs.Length];

            bool allFinish = true;

            if (jobs.Length == 1)
            {
                var job = jobs[0];
                File.WriteAllText("build_0.json", JsonUtility.ToJson(job, true));
                if ((options & BuildAssetBundleOptions.DryRunBuild) == 0)
                {
                    results[0] = BuildJob(job);
                }
            }
            else
            {
                //dryrun return null
                if ((options & BuildAssetBundleOptions.DryRunBuild) != 0)
                {
                    return(null);
                }

                List <string> cmds = new List <string>();
                for (int jobID = 0; jobID < jobs.Length; ++jobID)
                {
                    BuildJob job = jobs[jobID];
                    File.WriteAllText(string.Format("build_{0}.json", jobID), JsonUtility.ToJson(job, true));

                    if ((options & BuildAssetBundleOptions.DryRunBuild) == 0)
                    {
                        string cmd = string.Format(" -quit" +
                                                   " -batchmode" +
                                                   " -logfile {0}/log_{1}.txt" +
                                                   //" -projectPath {0} " +
                                                   " -executeMethod MultiProcessBuild.BuildPipeline.BuildJobSlave" +
                                                   " -buildJob {0}/build_{1}.json",
                                                   Path.GetFullPath("."), jobID);
                        cmds.Add(cmd);
                    }
                }

                var exitCodes = MultiProcess.UnityFork(cmds.ToArray(), "building", "waiting for sub process...");
                for (int jobID = 0; jobID < jobs.Length; ++jobID)
                {
                    var ExitCode = exitCodes[jobID];;
                    if (ExitCode != 0)
                    {
                        allFinish = false;
                        UnityEngine.Debug.LogErrorFormat("slave {0} code:{1}", jobID, ExitCode);
                    }
                    else
                    {
                        UnityEngine.Debug.LogFormat("slave {0} code:{1}", jobID, ExitCode);
                        string resultFile = string.Format(string.Format("{0}/result_{1}.json", output, jobID));
                        results[jobID] = JsonUtility.FromJson <AssetBundleManifest>(File.ReadAllText(resultFile));
                    }
                }
            }

            if (allFinish)
            {
                AssetBundleManifest manifest = new AssetBundleManifest();
                manifest.buildTime = 0f;
                List <AssetBundleManifest.AssetBundleBuild> totalBuilds = new List <AssetBundleManifest.AssetBundleBuild>();
                foreach (var result in results)
                {
                    totalBuilds.AddRange(result.builds);
                    manifest.buildTime = Mathf.Max(manifest.buildTime, result.buildTime);
                }
                totalBuilds.Sort((a, b) => { return(a.assetBundleName.CompareTo(b.assetBundleName)); });
                manifest.builds = totalBuilds.ToArray();
                File.WriteAllText(string.Format("{0}/result.json", output), JsonUtility.ToJson(manifest, true));
                UnityEngine.Debug.LogFormat("all slave finish.");
                return(manifest);
            }
            else
            {
                UnityEngine.Debug.LogErrorFormat("some slave error.");
                return(null);
            }
        }
        public static AssetBundleManifest BuildAssetBundles(string output, AssetBundleBuild[] builds, BuildAssetBundleOptions options, BuildTarget target)
        {
            output = Path.GetFullPath(output);

            var tree = new BuildTree();

            foreach (var build in builds)
            {
                foreach (var asset in build.assetNames)
                {
                    tree.AddBuildAsset(asset, build.assetBundleName);
                }
            }

            List <string> slaves    = new List <string>();
            int           i         = 0;
            string        slaveRoot = Path.GetFullPath(Profile.SlaveRoot);

            while (true)
            {
                string slaveProj = Path.Combine(slaveRoot, string.Format("slave_{0}", i++));
                if (!Directory.Exists(slaveProj))
                {
                    break;
                }
                slaves.Add(slaveProj);
            }

            string Unity = EditorApplication.applicationPath;

#if UNITY_EDITOR_OSX
            Unity += "/Contents/MacOS/Unity";
#endif

            var jobs = tree.BuildJobs(slaves.Count + 1, output, options, target);

            List <Process>        pss     = new List <Process>();
            AssetBundleManifest[] results = new AssetBundleManifest[jobs.Length];
            for (int jobID = 1; jobID < jobs.Length; ++jobID)
            {
                int      slaveID   = jobID - 1;
                BuildJob job       = jobs[jobID];
                string   slaveProj = slaves[slaveID];
                File.WriteAllText(slaveProj + "/build.json", JsonUtility.ToJson(job, true));

                if ((options & BuildAssetBundleOptions.DryRunBuild) == 0)
                {
                    string cmd = string.Format(" -quit" +
                                               " -batchmode" +
                                               " -logfile {0}/log.txt" +
                                               " -projectPath {0} " +
                                               " -executeMethod MultiProcessBuild.BuildPipeline.BuildJobSlave",
                                               slaveProj);
                    var ps = Process.Start(Unity, cmd);
                    pss.Add(ps);
                }
            }

            bool allFinish = true;
            if (jobs.Length > 0)
            {
                var job = jobs[0];
                File.WriteAllText("build.json", JsonUtility.ToJson(job, true));

                if ((options & BuildAssetBundleOptions.DryRunBuild) == 0)
                {
                    var result = BuildJob(job);
                    results[0] = result;
                    if (result == null)
                    {
                        allFinish = false;
                    }
                }
            }

            //dryrun return null
            if ((options & BuildAssetBundleOptions.DryRunBuild) != 0)
            {
                return(null);
            }

            int progress      = 0;
            int totalProgress = pss.Count;
            try
            {
                while (progress < totalProgress)
                {
                    EditorUtility.DisplayProgressBar("building", "waiting for sub process...", (float)progress / totalProgress);
                    for (int slaveID = 0; slaveID < pss.Count; ++slaveID)
                    {
                        var ps = pss[slaveID];
                        if (ps == null)
                        {
                            continue;
                        }

                        if (ps.WaitForExit(200))
                        {
                            progress++;

                            var ExitCode = ps.ExitCode;
                            if (ExitCode != 0)
                            {
                                allFinish = false;
                                UnityEngine.Debug.LogErrorFormat("slave {0} code:{1}", slaveID, ExitCode);
                            }
                            else
                            {
                                UnityEngine.Debug.LogFormat("slave {0} code:{1}", slaveID, ExitCode);
                                string resultFile = string.Format(string.Format("{0}/result_{1}.json", output, slaveID + 1));
                                results[slaveID + 1] = JsonUtility.FromJson <AssetBundleManifest>(File.ReadAllText(resultFile));
                            }
                            ps.Dispose();
                            pss[slaveID] = null;
                        }
                    }
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }

            if (allFinish)
            {
                AssetBundleManifest manifest = new AssetBundleManifest();
                manifest.buildTime = 0f;
                List <AssetBundleManifest.AssetBundleBuild> totalBuilds = new List <AssetBundleManifest.AssetBundleBuild>();
                foreach (var result in results)
                {
                    totalBuilds.AddRange(result.builds);
                    manifest.buildTime = Mathf.Max(manifest.buildTime, result.buildTime);
                }
                totalBuilds.Sort((a, b) => { return(a.assetBundleName.CompareTo(b.assetBundleName)); });
                manifest.builds = totalBuilds.ToArray();
                File.WriteAllText(string.Format("{0}/result.json", output), JsonUtility.ToJson(manifest, true));
                UnityEngine.Debug.LogFormat("all slave finish.");
                return(manifest);
            }
            else
            {
                UnityEngine.Debug.LogErrorFormat("some slave error.");
                return(null);
            }
        }