public MobileBuildReportPlatformData[] CollectPlatformData(string buildPath) { var downloadSize = EstimateDownloadSize(buildPath); var temporaryDir = CommonTools.GetTemporaryDirectory(); var libraryFiles = new List <string>(); using (var archive = ZipFile.OpenRead(buildPath)) { foreach (var file in archive.Entries) { if (file.Name == "libunity.so") { var parent = file.FullName.Replace("/libunity.so", string.Empty); var architecture = parent.Substring(parent.LastIndexOf('/') + 1); var targetFile = Path.Combine(temporaryDir, architecture); file.ExtractToFile(targetFile); libraryFiles.Add(targetFile); } } } var androidData = new MobileBuildReportPlatformData[libraryFiles.Count]; for (int i = 0; i < libraryFiles.Count; i++) { androidData[i] = new MobileBuildReportPlatformData { Architecture = Path.GetFileName(libraryFiles[i]), DownloadSize = downloadSize }; #if UNITY_EDITOR_OSX var objdumpArgs = $"-section-headers {libraryFiles[i]}"; var objdumpOutput = CommonTools.RunProcessAndGetOutput(objdump, objdumpArgs, out string error, out int exitCode); if (exitCode != 0) { Debug.LogWarning($"Failed to collect libunity.so data with command: {objdump} {objdumpArgs}"); return(null); } using (var reader = new StringReader(objdumpOutput)) { string line; while ((line = reader.ReadLine()) != null) { var lineParts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (lineParts.Length == 0 || lineParts.Length != 5 || !int.TryParse(lineParts[0], out int n)) { continue; } if (androidData[i].Segments == null) { androidData[i].Segments = new Dictionary <string, long>(); } if (!androidData[i].Segments.ContainsKey(lineParts[4])) { androidData[i].Segments.Add(lineParts[4], 0); } androidData[i].Segments[lineParts[4]] += Convert.ToInt64(lineParts[2], 16); } } #endif } Directory.Delete(temporaryDir, true); return(androidData); }
public MobileBuildReportPlatformData[] CollectPlatformData(string buildPath) { var temporaryDir = CommonTools.GetTemporaryDirectory(); var frameworkFile = Path.Combine(temporaryDir, "UnityFramework"); long appSizeNoFramework; using (var archive = ZipFile.OpenRead(buildPath)) { var unityFramework = archive.Entries.FirstOrDefault(x => x.FullName.EndsWith(unityFrameworkRelativePath, StringComparison.InvariantCulture)); if (unityFramework == null) { throw new FileNotFoundException($"Framework {unityFrameworkRelativePath} not found in the app archive!"); } unityFramework.ExtractToFile(frameworkFile); appSizeNoFramework = new FileInfo(buildPath).Length - unityFramework.CompressedLength; } var foundArchs = new List <string>(); { var archOutput = CommonTools.RunProcessAndGetOutput(file, $"-b {frameworkFile}", out string error, out int exitCode); if (exitCode != 0) { Debug.LogWarning($"Failed to collect UnityFramework data with command: {size} -m {frameworkFile}"); return(null); } using (var reader = new StringReader(archOutput)) { string line; while ((line = reader.ReadLine()) != null) { var archString = line.Substring(line.LastIndexOf(' ') + 1); if (archString.StartsWith("arm", StringComparison.InvariantCulture)) { foundArchs.Add(archString.Replace("_", string.Empty)); } } } } var appleData = new MobileBuildReportPlatformData[foundArchs.Count]; { for (var i = 0; i < foundArchs.Count; i++) { var sizeArgs = $"-m -arch {foundArchs[i]} {frameworkFile}"; var sizeOutput = CommonTools.RunProcessAndGetOutput(size, sizeArgs, out string error, out int exitCode); if (exitCode != 0) { Debug.LogWarning($"Failed to collect UnityFramework data with command: {size} {sizeArgs}"); return(null); } appleData[i] = new MobileBuildReportPlatformData { Architecture = foundArchs[i] }; using (var reader = new StringReader(sizeOutput)) { string line; while ((line = reader.ReadLine()) != null) { if (line.StartsWith("Segment __", StringComparison.InvariantCulture)) { if (appleData[i].Segments == null) { appleData[i].Segments = new Dictionary <string, long>(); } var segmentName = line.Substring(8, line.IndexOf(':') - 8); var segmentSize = long.Parse(line.Substring(line.LastIndexOf(' ') + 1)); appleData[i].Segments.Add(segmentName, segmentSize); } } } var textSize = appleData[i].Segments.ContainsKey("__TEXT") ? appleData[i].Segments["__TEXT"] : 0; var dataSize = appleData[i].Segments.ContainsKey("__DATA") ? appleData[i].Segments["__DATA"] : 0; appleData[i].DownloadSize = appSizeNoFramework + textSize + dataSize / 5; } } Directory.Delete(temporaryDir, true); return(appleData); }