From 478b68b9b9b94ccd05e3297f1b4e7c0798ef999b Mon Sep 17 00:00:00 2001 From: Anthony Potvin Date: Wed, 15 Jan 2025 13:01:48 -0500 Subject: [PATCH] [XCode] Expose extra strip options for XCode, and fixed Testability + StripLinkedProduct default values to make more sense. - 3 new options: StripStyle, StripSwiftSymbols and AdditionalStripFlags, to tweak the options passed to strip command line. (apply to both XCode native projects and Fastbuild). - Changing default values for Testability and StripLinkedProduct: Testability has unwanted edge effects of ignoring other options, this is especially confusing when it's done by default. stripping is not something we want to do by default, but so far it was ignored by default due to Testability. --- .../Apple/XCodeProj.Template.cs | 3 ++ .../Apple/BaseApplePlatform.cs | 50 +++++++++++++++---- Sharpmake/Options.XCode.cs | 44 +++++++++++++++- .../HelloXCode.CommonProject.sharpmake.cs | 7 ++- 4 files changed, 91 insertions(+), 13 deletions(-) diff --git a/Sharpmake.Generators/Apple/XCodeProj.Template.cs b/Sharpmake.Generators/Apple/XCodeProj.Template.cs index a3f66a2bf..b3607ffd0 100644 --- a/Sharpmake.Generators/Apple/XCodeProj.Template.cs +++ b/Sharpmake.Generators/Apple/XCodeProj.Template.cs @@ -305,6 +305,9 @@ private static class Template PROVISIONING_PROFILE_SPECIFIER = ""[item.Options.ProvisioningProfile]""; SKIP_INSTALL = [item.Options.SkipInstall]; STRIP_INSTALLED_PRODUCT = [item.Options.StripLinkedProduct]; + STRIP_STYLE= [item.Options.StripStyle]; + STRIPFLAGS = ""[item.Options.AdditionalStripFlags]""; + STRIP_SWIFT_SYMBOLS = [item.Options.StripSwiftSymbols]; SYMROOT = ""[item.Options.BuildDirectory]""; VALID_ARCHS = ""[item.Options.ValidArchs]""; GENERATE_MASTER_OBJECT_FILE = [item.Options.GenerateMasterObjectFile]; diff --git a/Sharpmake.Platforms/Sharpmake.CommonPlatforms/Apple/BaseApplePlatform.cs b/Sharpmake.Platforms/Sharpmake.CommonPlatforms/Apple/BaseApplePlatform.cs index 0f3c32d12..34f0ab1e6 100644 --- a/Sharpmake.Platforms/Sharpmake.CommonPlatforms/Apple/BaseApplePlatform.cs +++ b/Sharpmake.Platforms/Sharpmake.CommonPlatforms/Apple/BaseApplePlatform.cs @@ -221,7 +221,7 @@ public void SetupExtraLinkerSettings(IFileGenerator fileGenerator, Project.Confi configuration.Output == Project.Configuration.OutputType.Dll )) { - var debugFormat = Options.GetObject(configuration); + var debugFormat = Options.GetObject(configuration); if (debugFormat == Options.XCode.Compiler.DebugInformationFormat.DwarfWithDSym) { string outputPath = Path.Combine(configuration.TargetPath, configuration.TargetFileFullNameWithExtension + ".dSYM"); @@ -233,22 +233,37 @@ public void SetupExtraLinkerSettings(IFileGenerator fileGenerator, Project.Confi $"{fastBuildOutputFile} -o {outputPath}", useStdOutAsOutput: true); - var stripDebugSymbols = Options.GetObject(configuration); - if (stripDebugSymbols == Options.XCode.Linker.StripLinkedProduct.Enable) + // Stripping + if (Options.GetObject(configuration) == Options.XCode.Linker.StripLinkedProduct.Enable) { + List stripOptionList = new List(); + switch (Options.GetObject(configuration)) + { + case Options.XCode.Linker.StripStyle.AllSymbols: + stripOptionList.Add("-s"); + break; + case Options.XCode.Linker.StripStyle.NonGlobalSymbols: + stripOptionList.Add("-x"); + break; + case Options.XCode.Linker.StripStyle.DebuggingSymbolsOnly: + stripOptionList.Add("-S"); + break; + } + if (Options.GetObject(configuration) == Options.XCode.Linker.StripSwiftSymbols.Enable) + stripOptionList.Add("-T"); + + var additionalStripFlags = Options.GetObject(configuration); + if (additionalStripFlags != null) + stripOptionList.Add(XCodeUtil.ResolveProjectVariable(configuration.Project, additionalStripFlags.Value)); + + string stripOptions = string.Join(" ", stripOptionList); + string strippedSentinelFile = Path.Combine(configuration.IntermediatePath, configuration.TargetFileName + ".stripped"); yield return new Project.Configuration.BuildStepExecutable( "/usr/bin/strip", asStampSteps ? string.Empty : dsymutilSentinelFile, asStampSteps ? string.Empty : strippedSentinelFile, - // From MacOS strip manual page: - // -r : Save all symbols referenced dynamically. - // -S : Remove the debuging symbol table entries (those created by the -g optin to cc and other compilers). - // -T : The intent of this flag is to remove Swift symbols from the Mach-O symbol table, - // It removes the symbols whose names begin with '_$S' or '_$s' only when it finds an __objc_imageinfo section with and it has non-zero swift version. - // In the future the implementation of this flag may change to match the intent. - // -x : Remove all local symbols (saving only global symbols) - $"-rSTx {fastBuildOutputFile}", + $"{stripOptions} {fastBuildOutputFile}", useStdOutAsOutput: true ); } @@ -1372,6 +1387,19 @@ public virtual void SelectLinkerOptions(IGenerationContext context) Options.Option(Options.XCode.Linker.StripLinkedProduct.Enable, () => options["StripLinkedProduct"] = "YES") ); + context.SelectOption( + Options.Option(Options.XCode.Linker.StripStyle.AllSymbols, () => options["StripStyle"] = "all"), + Options.Option(Options.XCode.Linker.StripStyle.NonGlobalSymbols, () => options["StripStyle"] = "non-global"), + Options.Option(Options.XCode.Linker.StripStyle.DebuggingSymbolsOnly, () => options["StripStyle"] = "debugging") + ); + + context.SelectOption( + Options.Option(Options.XCode.Linker.StripSwiftSymbols.Disable, () => options["StripSwiftSymbols"] = "NO"), + Options.Option(Options.XCode.Linker.StripSwiftSymbols.Enable, () => options["StripSwiftSymbols"] = "YES") + ); + + options["AdditionalStripFlags"] = XCodeUtil.ResolveProjectVariable(context.Project, Options.StringOption.Get(conf)); + context.SelectOption( Options.Option(Options.XCode.Linker.PerformSingleObjectPrelink.Disable, () => options["GenerateMasterObjectFile"] = "NO"), Options.Option(Options.XCode.Linker.PerformSingleObjectPrelink.Enable, () => options["GenerateMasterObjectFile"] = "YES") diff --git a/Sharpmake/Options.XCode.cs b/Sharpmake/Options.XCode.cs index 8367bfec8..4f608e780 100644 --- a/Sharpmake/Options.XCode.cs +++ b/Sharpmake/Options.XCode.cs @@ -610,10 +610,15 @@ public enum AssetCatalogWarnings Enable } + /// + /// Testability is used for automated tests in XCode. + /// Activating it will disable other options, like stripping and private symbols. + /// See https://developer.apple.com/documentation/xcode/build-settings-reference#Enable-Testability + /// public enum Testability { - [Default] Enable, + [Default] Disable } @@ -1119,13 +1124,50 @@ public enum UIAppSupportsHDR public static class Linker { + /// + /// Enables symbols stripping after the binary is linked. + /// public enum StripLinkedProduct { + [Default] Disable, + Enable + } + + /// + /// When stripping is enabled. + /// The level of symbol stripping to be performed on the linked product of the build. + /// + public enum StripStyle + { + AllSymbols, // Completely strips the binary, removing the symbol table and relocation information (strip option -s) + NonGlobalSymbols, // Strips non-global symbols, but saves external symbols (strip option -x) [Default] + DebuggingSymbolsOnly // Strips debugging symbols, but saves local and global symbols (strip option -S) + } + + /// + /// When stripping is enabled. + /// Adjust the level of symbol stripping so that when the linked product of the build is stripped, all Swift symbols will be removed. + /// + public enum StripSwiftSymbols + { + [Default] + Disable, Enable } + /// + /// Additional Strip Flags. + /// For a complete list, see documentation for /usr/bin/strip. + /// + public class AdditionalStripFlags : StringOption + { + public AdditionalStripFlags(string value) : base(value) + { + } + } + /// /// Xcode has a setting called Single-Object Prelink, which allows libraries and frameworks to include the necessary symbols /// from other libraries so that the underlying libraries do not need to be linked against in an application using your framework. diff --git a/samples/HelloXCode/HelloXCode.CommonProject.sharpmake.cs b/samples/HelloXCode/HelloXCode.CommonProject.sharpmake.cs index 4ca2967b5..94c8636bb 100644 --- a/samples/HelloXCode/HelloXCode.CommonProject.sharpmake.cs +++ b/samples/HelloXCode/HelloXCode.CommonProject.sharpmake.cs @@ -60,8 +60,13 @@ public virtual void ConfigureAll(Configuration conf, CommonTarget target) conf.Output = Configuration.OutputType.Lib; // defaults to creating static libs conf.Options.Add(Options.XCode.Editor.Indent.Spaces); - if (target.Optimization == Optimization.Debug) + if (target.Optimization == Optimization.Release) + { conf.Options.Add(Sharpmake.Options.XCode.Compiler.DebugInformationFormat.DwarfWithDSym); + conf.Options.Add(Sharpmake.Options.XCode.Linker.StripLinkedProduct.Enable); + conf.Options.Add(Sharpmake.Options.XCode.Linker.StripStyle.DebuggingSymbolsOnly); + conf.Options.Add(Sharpmake.Options.XCode.Linker.StripSwiftSymbols.Enable); + } else conf.Options.Add(Sharpmake.Options.XCode.Compiler.DebugInformationFormat.Dwarf); }