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); }