Skip to content

Commit

Permalink
Merge branch 'xcode-scheme-improvements' into 'main'
Browse files Browse the repository at this point in the history
XCode scheme improvements

See merge request Sharpmake/sharpmake!562
  • Loading branch information
jspelletier committed Oct 7, 2024
2 parents 20e3708 + 6325045 commit 69b7043
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 20 deletions.
44 changes: 30 additions & 14 deletions Sharpmake.Generators/Apple/XCodeProj.Template.cs
Original file line number Diff line number Diff line change
Expand Up @@ -491,19 +491,33 @@ private static class Template
};

public static string CommandLineArgumentsBegin =
@"
<CommandLineArguments>";
@" <CommandLineArguments>
";

public static string CommandLineArgument =
@"
<CommandLineArgument
@" <CommandLineArgument
argument = ""[argument]""
isEnabled = ""YES"">
</CommandLineArgument>";
</CommandLineArgument>
";

public static string CommandLineArgumentsEnd =
@"
</CommandLineArguments>";
@" </CommandLineArguments>";

public static string EnvironmentVariablesBegin =
@" <EnvironmentVariables>
";

public static string EnvironmentVariablesEnd =
@" </EnvironmentVariables>";

public static string EnvironmentVariable =
@" <EnvironmentVariable
key = ""[name]""
value = ""[value]""
isEnabled = ""YES"">
</EnvironmentVariable>
";

public static string SchemeTestableReference =
@"
Expand All @@ -522,26 +536,26 @@ private static class Template
/// This section is used to configure the executable to run for native projects.
/// </summary>
public static string SchemeRunnableNativeProject =
@"
<BuildableProductRunnable>
@" <BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = ""primary""
BlueprintIdentifier = ""[item.Uid]""
BuildableName = ""[item.OutputFile.BuildableName]""
BlueprintName = ""[item.Identifier]""
ReferencedContainer = ""container:[projectFile].xcodeproj"">
</BuildableReference>
</BuildableProductRunnable>";
</BuildableProductRunnable>
";

/// <summary>
/// This section is used to configure the executable to run for makefile projects.
/// </summary>
public static string SchemeRunnableMakeFileProject =
@"
<PathRunnable
@" <PathRunnable
runnableDebuggingMode = ""0""
FilePath = ""[runnableFilePath]"">
</PathRunnable>";
</PathRunnable>
";

/// <summary>
/// First part of schema file
Expand Down Expand Up @@ -595,13 +609,15 @@ private static class Template
debugDocumentVersioning = ""YES""
enableGPUFrameCaptureMode = ""[options.EnableGpuFrameCaptureMode]""
enableGPUValidationMode = ""[options.MetalAPIValidation]""
allowLocationSimulation = ""YES"">";
allowLocationSimulation = ""YES"">
";

/// <summary>
/// Secondpart of schema file
/// </summary>
public static string SchemeFileTemplatePart2 =
@"[commandLineArguments]
[environmentVariables]
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
Expand Down
45 changes: 39 additions & 6 deletions Sharpmake.Generators/Apple/XCodeProj.cs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ string projectFile
// Setup resolvers
var fileGenerator = new FileGenerator();

var defaultConfiguration = configurations.Where(conf => conf.UseAsDefaultForXCode == true).FirstOrDefault();
Project.Configuration activeConfiguration = defaultConfiguration != null ? defaultConfiguration : configurations[0];

// Build testable elements
var testableTargets = _nativeOrLegacyTargets.Values.Where(target => target.OutputFile.OutputType == Project.Configuration.OutputType.IosTestBundle);
var testableElements = new StringBuilder();
Expand All @@ -299,7 +302,7 @@ string projectFile
}

// Build commandLineArguments
var debugArguments = Options.GetObject<Options.XCode.Scheme.DebugArguments>(configurations[0]);
var debugArguments = Options.GetObject<Options.XCode.Scheme.DebugArguments>(activeConfiguration);
var commandLineArguments = new StringBuilder();
if (debugArguments != null)
{
Expand All @@ -311,34 +314,60 @@ string projectFile
}
commandLineArguments.Append(Template.CommandLineArgumentsEnd);
}
else
{
commandLineArguments.Append(RemoveLineTag);
}

// Write the scheme file
var defaultTarget = _nativeOrLegacyTargets.Values.Where(target => target.OutputFile.OutputType != Project.Configuration.OutputType.IosTestBundle).FirstOrDefault();

var options = new Options.ExplicitOptions();
Options.SelectOption(configurations[0],
Options.SelectOption(activeConfiguration,
Options.Option(Options.XCode.Compiler.EnableGpuFrameCaptureMode.AutomaticallyEnable, () => options["EnableGpuFrameCaptureMode"] = RemoveLineTag),
Options.Option(Options.XCode.Compiler.EnableGpuFrameCaptureMode.MetalOnly, () => options["EnableGpuFrameCaptureMode"] = "1"),
Options.Option(Options.XCode.Compiler.EnableGpuFrameCaptureMode.OpenGLOnly, () => options["EnableGpuFrameCaptureMode"] = "2"),
Options.Option(Options.XCode.Compiler.EnableGpuFrameCaptureMode.Disable, () => options["EnableGpuFrameCaptureMode"] = "3")
);
// An empty line means ON, "1" means OFF
// https://gitlab.kitware.com/cmake/cmake/-/issues/23857
Options.SelectOption(configurations[0],
Options.SelectOption(activeConfiguration,
Options.Option(Options.XCode.Scheme.MetalAPIValidation.Enable, () => options["MetalAPIValidation"] = RemoveLineTag),
Options.Option(Options.XCode.Scheme.MetalAPIValidation.Disable, () => options["MetalAPIValidation"] = "1")
);

var defaultConfiguration = configurations.Where(conf => conf.UseAsDefaultForXCode == true).FirstOrDefault();
Project.Configuration activeConfiguration = defaultConfiguration != null ? defaultConfiguration : configurations[0];
string targetName = $"&quot;{activeConfiguration.Target.Name}&quot;";
string buildImplicitDependencies = activeConfiguration.IsFastBuild ? "NO" : "YES";
bool useBuildableProductRunnableSection = true;
string runnableFilePath = string.Empty;
if (activeConfiguration.IsFastBuild && activeConfiguration.Output == Project.Configuration.OutputType.AppleApp && !activeConfiguration.XcodeUseNativeProjectForFastBuildApp)
{
useBuildableProductRunnableSection = false;
runnableFilePath = Path.Combine(activeConfiguration.TargetPath, activeConfiguration.TargetFileFullNameWithExtension);
var customRunnablePath = Options.GetObject<Options.XCode.Scheme.CustomRunnablePath>(activeConfiguration);
if (customRunnablePath != null)
runnableFilePath = customRunnablePath.Path;
else
runnableFilePath = Path.Combine(activeConfiguration.TargetPath, activeConfiguration.TargetFileFullNameWithExtension);
}

var environmentVariables = Options.GetObject<Options.XCode.Scheme.EnvironmentVariables>(activeConfiguration);
var environmentVariablesBuilder = new StringBuilder();
if (environmentVariables != null)
{
environmentVariablesBuilder.Append(Template.EnvironmentVariablesBegin);
foreach (var variable in environmentVariables.Variables)
{
using (fileGenerator.Declare("name", variable.Key))
using (fileGenerator.Declare("value", variable.Value))
{
environmentVariablesBuilder.Append(fileGenerator.Resolver.Resolve(Template.EnvironmentVariable));
}
}
environmentVariablesBuilder.Append(Template.EnvironmentVariablesEnd);
}
else
{
environmentVariablesBuilder.Append(RemoveLineTag);
}

using (fileGenerator.Declare("projectFile", projectFile))
Expand All @@ -347,8 +376,12 @@ string projectFile
using (fileGenerator.Declare("testableElements", testableElements))
using (fileGenerator.Declare("DefaultTarget", targetName))
using (fileGenerator.Declare("commandLineArguments", commandLineArguments))
using (fileGenerator.Declare("environmentVariables", environmentVariablesBuilder))
using (fileGenerator.Declare("buildImplicitDependencies", buildImplicitDependencies))
using (fileGenerator.Declare("runnableFilePath", runnableFilePath))
using (fileGenerator.Declare("project", activeConfiguration.Project))
using (fileGenerator.Declare("target", activeConfiguration.Target))
using (fileGenerator.Declare("conf", activeConfiguration))
{
fileGenerator.Write(Template.SchemeFileTemplatePart1);
if (useBuildableProductRunnableSection)
Expand Down
15 changes: 15 additions & 0 deletions Sharpmake/Options.XCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,21 @@ public DebugArguments(List<string> args)
{
}
}

public class EnvironmentVariables
{
public Dictionary<string, string> Variables { get; set; } = new Dictionary<string, string>();
}

/// <summary>
/// This option can be used to set a custom runnable path in the scheme file for fastbuild targets
/// </summary>
public class CustomRunnablePath : PathOption
{
public CustomRunnablePath(string path) : base(path)
{
}
}
}
}
}
Expand Down

0 comments on commit 69b7043

Please sign in to comment.