// Copyright Epic Games, Inc. All Rights Reserved. using EpicGames.Core; using Microsoft.Extensions.Logging; namespace UnrealBuildTool { /// /// Public Mac functions exposed to UAT /// public static class MacExports { /// /// Describes the architecture of the host. Note - this ignores translation. /// IsRunningUnderRosetta can be used to detect that we're running under translation /// public static UnrealArch HostArchitecture => IsRunningOnAppleArchitecture ? UnrealArch.Arm64 : UnrealArch.X64; /// /// Cached result for AppleArch check /// private static bool? IsRunningOnAppleArchitectureVar; /// /// Cached result for Rosetta check /// private static bool? IsRunningUnderRosettaVar; /// /// Returns true if we're running under Rosetta /// /// public static bool IsRunningUnderRosetta { get { if (!IsRunningUnderRosettaVar.HasValue) { string TranslatedOutput = Utils.RunLocalProcessAndReturnStdOut("/usr/sbin/sysctl", "sysctl", null); IsRunningUnderRosettaVar = TranslatedOutput.Contains("sysctl.proc_translated: 1"); } return IsRunningUnderRosettaVar.Value; } } /// /// Returns true if we're running on Apple architecture (either natively which dotnet will do, or under Rosetta) /// /// public static bool IsRunningOnAppleArchitecture { get { if (!IsRunningOnAppleArchitectureVar.HasValue) { // On an m1 mac this appears to be where the brand is. string BrandOutput = Utils.RunLocalProcessAndReturnStdOut("/usr/sbin/sysctl", "-n machdep.cpu.brand_string", null); IsRunningOnAppleArchitectureVar = BrandOutput.Contains("Apple") || IsRunningUnderRosetta; } return IsRunningOnAppleArchitectureVar.Value; } } /// /// Strips symbols from a file /// /// The input file /// The output file /// public static void StripSymbols(FileReference SourceFile, FileReference TargetFile, ILogger Logger) { MacToolChain ToolChain = new MacToolChain(null, ClangToolChainOptions.None, Logger); ToolChain.StripSymbols(SourceFile, TargetFile); } } }