static void BuildJobSlave() { string text = File.ReadAllText("./build.json"); BuildJob job = JsonUtility.FromJson <BuildJob>(text); BuildJob(job); }
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)); }
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()); }
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); } }