static void MakeSymbolLinkFlatDir(string source, string dest) { Directory.CreateDirectory(dest); source = Path.GetFullPath(source); List <Process> pss = new List <Process>(); foreach (var x in Directory.GetFiles(source, "*.*", SearchOption.TopDirectoryOnly)) { var relPath = x.Replace(source, ""); relPath = relPath.TrimStart('\\'); relPath = relPath.TrimStart('/'); pss.Add(MakeSymbolLink(x, Path.Combine(dest, relPath))); } foreach (var x in Directory.GetDirectories(source, "*.*", SearchOption.TopDirectoryOnly)) { var relPath = x.Replace(source, ""); relPath = relPath.TrimStart('\\'); relPath = relPath.TrimStart('/'); pss.Add(MakeSymbolLink(x, Path.Combine(dest, relPath))); } if (pss.Count > 0) { MultiProcess.Start(pss.ToArray(), "waiting", "make symbol link..."); } }
public void SyncSlaveProjects() { #if UNITY_EDITOR_WIN string bin = "robocopy"; #else string bin = "rsync"; #endif List <string> cmds = new List <string>(); //Copy Libaray string library = Path.GetFullPath("Library"); for (int i = 0; i < Profile.SlaveCount; ++i) { string slaveDir = Path.GetFullPath(Profile.SlaveRoot); slaveDir = Path.Combine(slaveDir, string.Format("slave_{0}", i)); if (!Directory.Exists(slaveDir)) { continue; } #if UNITY_EDITOR_OSX MakeSymbolLinkFlatDir(Path.GetFullPath("Assets"), Path.Combine(slaveDir, "Assets")); #endif #if UNITY_EDITOR_WIN cmds.Add(string.Format("/s {0} {1}", library, Path.Combine(slaveDir, "Library"))); #else cmds.Add(string.Format("-r {0} {1}", library, slaveDir)); #endif } if (cmds.Count > 0) { MultiProcess.Start(bin, cmds.ToArray(), "waiting", "syncing master project to slave projects."); } }
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); AssetBundleManifest[] results = new AssetBundleManifest[jobs.Length]; List <string> cmds = new List <string>(); 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); cmds.Add(cmd); } } 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); } MultiProcess.Start(Unity, cmds.ToArray(), "building", "waiting for sub process...", (ps, idx) => { var ExitCode = ps.ExitCode; if (ExitCode != 0) { allFinish = false; UnityEngine.Debug.LogErrorFormat("slave {0} code:{1}", idx, ExitCode); } else { UnityEngine.Debug.LogFormat("slave {0} code:{1}", idx, ExitCode); string resultFile = string.Format(string.Format("{0}/result_{1}.json", output, idx + 1)); results[idx + 1] = 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); } }