diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml
index 40ca5bf9b2fab..f3d39704bef68 100644
--- a/eng/pipelines/runtime-staging.yml
+++ b/eng/pipelines/runtime-staging.yml
@@ -65,12 +65,10 @@ jobs:
buildConfig: Release
runtimeFlavor: mono
platforms:
- - MacCatalyst_x64
- iOSSimulator_x64
- tvOSSimulator_x64
# don't run tests on arm64 PRs until we can get significantly more devices
- ${{ if eq(variables['isFullMatrix'], true) }}:
- - MacCatalyst_arm64
- iOSSimulator_arm64
variables:
# map dependencies variables to local variables
@@ -101,6 +99,50 @@ jobs:
eq(variables['monoContainsChange'], true),
eq(variables['isFullMatrix'], true))
+#
+# MacCatalyst interp - requires AOT Compilation and Interp flags
+# Build the whole product using Mono and run libraries tests
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: mono
+ platforms:
+ - MacCatalyst_x64
+ # don't run tests on arm64 PRs until we can get significantly more devices
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
+ - MacCatalyst_arm64
+ variables:
+ # map dependencies variables to local variables
+ - name: librariesContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
+ - name: monoContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=adhoc /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildDarwinFrameworks=true
+ timeoutInMinutes: 180
+ condition: >-
+ or(
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isFullMatrix'], true))
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ interpreter: true
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ condition: >-
+ or(
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['monoContainsChange'], true),
+ eq(variables['isFullMatrix'], true))
+
#
# Build the whole product using Mono and run libraries tests
#
diff --git a/eng/testing/AppleRunnerTemplate.sh b/eng/testing/AppleRunnerTemplate.sh
index 47352018d1ac4..42f787af20d88 100644
--- a/eng/testing/AppleRunnerTemplate.sh
+++ b/eng/testing/AppleRunnerTemplate.sh
@@ -35,6 +35,8 @@ if [[ "$TARGET" == "ios-device" ]]; then SCHEME_SDK=Release-iphoneos; fi
if [[ "$TARGET" == "tvos-device" ]]; then SCHEME_SDK=Release-appletvos; fi
if [[ "$TARGET" == "maccatalyst" ]]; then SCHEME_SDK=Release-maccatalyst; fi
+if [[ "$TARGET" == "ios-device" || "$TARGET" == "tvos-device" ]]; then SIGNAL_APP_END="--signal-app-end"; fi
+
cd $EXECUTION_DIR
# it doesn't support parallel execution yet, so, here is a hand-made semaphore:
@@ -62,6 +64,7 @@ $HARNESS_RUNNER apple $XHARNESS_CMD \
--targets="$TARGET" \
--xcode="$XCODE_PATH" \
--output-directory="$XHARNESS_OUT" \
+ $SIGNAL_APP_END \
$ADDITIONAL_ARGS
_exitCode=$?
diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets
index ce6bfe2302ce6..db5e7c63644d2 100644
--- a/eng/testing/tests.mobile.targets
+++ b/eng/testing/tests.mobile.targets
@@ -2,6 +2,9 @@
$([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle'))
+ $(AppBundleRoot)tests\$(AssemblyName)
+ $(AppBundleRoot)runonly\$(AssemblyName)
+ $([MSBuild]::NormalizeDirectory('$(PublishDir)', 'AppBundle'))
$([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)'))
true
@@ -157,6 +160,10 @@
true
AppleTestRunner.dll
<_MobileIntermediateOutputPath Condition="'$(RunAOTCompilation)' == 'true'">$(IntermediateOutputPath)mobile
+ true
+ false
+ false
+ true
Full
@@ -214,8 +221,9 @@
ForceInterpreter="$(MonoForceInterpreter)"
InvariantGlobalization="$(InvariantGlobalization)"
UseConsoleUITemplate="True"
- GenerateXcodeProject="True"
- BuildAppBundle="True"
+ GenerateXcodeProject="$(GenerateXcodeProject)"
+ GenerateCMakeProject="$(GenerateCMakeProject)"
+ BuildAppBundle="$(GenerateXcodeProject)"
Optimized="$(Optimized)"
DevTeamProvisioning="$(DevTeamProvisioning)"
OutputDirectory="$(BundleDir)"
@@ -223,25 +231,20 @@
-
-
+
+
-
+
<_appFiles Include="$(AppBundlePath)/../**/*" />
-
-
-
- <_removeFiles Include="$(OutDir)*.*" />
-
+ Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true' and '$(GenerateXcodeProject)' == 'true'" />
-
-
+
+
+
+
+
+
+
+
+
+ $(TestArchiveRoot)tests/
+ $(TestArchiveRoot)runonly/
+
+ $(TestArchiveNormalTestsRoot)$(OSPlatformConfig)/
+ $(TestArchiveFunctionalTestsRoot)$(OSPlatformConfig)/
+
+ $(AppBundleRoot)/tests/
+ $(AppBundleRoot)/runonly/
+
+ $(AppBundleRoot)/tests.all/
+ $(AppBundleRoot)/runonly.all/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- /// The Apple OS we are targeting (iOS or tvOS)
+ /// The Apple OS we are targeting (ios, tvos, iossimulator, tvossimulator)
///
[Required]
public string TargetOS
@@ -64,7 +64,7 @@ public string TargetOS
public ITaskItem[] Assemblies { get; set; } = Array.Empty();
///
- /// Target arch, can be "arm64" (device) or "x64" (simulator) at the moment
+ /// Target arch, can be "arm64", "arm" or "x64" at the moment
///
[Required]
public string Arch { get; set; } = ""!;
@@ -106,6 +106,11 @@ public string TargetOS
///
public bool GenerateXcodeProject { get; set; }
+ ///
+ /// Generate CMake project
+ ///
+ public bool GenerateCMakeProject { get; set; }
+
///
/// Files to be ignored in AppDir
///
@@ -224,14 +229,12 @@ public override bool Execute()
throw new ArgumentException("Using DiagnosticPorts require diagnostics_tracing runtime component.");
}
+ var generator = new Xcode(Log, TargetOS, Arch);
+
if (GenerateXcodeProject)
{
- Xcode generator = new Xcode(Log, TargetOS, Arch);
- generator.EnableRuntimeLogging = EnableRuntimeLogging;
- generator.DiagnosticPorts = DiagnosticPorts;
-
XcodeProjectPath = generator.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles, assemblerFilesToLink,
- AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, Optimized, RuntimeComponents, NativeMainSource);
+ AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, Optimized, EnableRuntimeLogging, DiagnosticPorts, RuntimeComponents, NativeMainSource);
if (BuildAppBundle)
{
@@ -242,10 +245,15 @@ public override bool Execute()
}
else
{
- AppBundlePath = generator.BuildAppBundle(XcodeProjectPath, Arch, Optimized, DevTeamProvisioning);
+ AppBundlePath = generator.BuildAppBundle(XcodeProjectPath, Optimized, DevTeamProvisioning);
}
}
}
+ else if (GenerateCMakeProject)
+ {
+ generator.GenerateCMake(ProjectName, MainLibraryFileName, assemblerFiles, assemblerFilesToLink,
+ AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, Optimized, EnableRuntimeLogging, DiagnosticPorts, RuntimeComponents, NativeMainSource);
+ }
return true;
}
diff --git a/src/tasks/AppleAppBuilder/Xcode.cs b/src/tasks/AppleAppBuilder/Xcode.cs
index 2e938d8ea0e36..05a643c304727 100644
--- a/src/tasks/AppleAppBuilder/Xcode.cs
+++ b/src/tasks/AppleAppBuilder/Xcode.cs
@@ -9,10 +9,111 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
+public class XcodeCreateProject : Task
+{
+ private string targetOS = TargetNames.iOS;
+
+ ///
+ /// The Apple OS we are targeting (ios, tvos, iossimulator, tvossimulator)
+ ///
+ [Required]
+ public string TargetOS
+ {
+ get
+ {
+ return targetOS;
+ }
+
+ set
+ {
+ targetOS = value.ToLower();
+ }
+ }
+
+ ///
+ /// Target arch, can be "arm64", "arm" or "x64" at the moment
+ ///
+ [Required]
+ public string Arch { get; set; } = ""!;
+
+ ///
+ /// Path to the directory with the CMakeLists.txt to create a project for.
+ ///
+ [Required]
+ public string CMakeListsDirectory { get; set; } = ""!;
+
+ ///
+ /// Name of the generated project.
+ ///
+ [Required]
+ public string ProjectName { get; set; } = ""!;
+
+ public override bool Execute()
+ {
+ new Xcode(Log, TargetOS, Arch).CreateXcodeProject(ProjectName, CMakeListsDirectory);
+
+ return true;
+ }
+}
+
+public class XcodeBuildApp : Task
+{
+ private string targetOS = TargetNames.iOS;
+
+ ///
+ /// The Apple OS we are targeting (ios, tvos, iossimulator, tvossimulator)
+ ///
+ [Required]
+ public string TargetOS
+ {
+ get
+ {
+ return targetOS;
+ }
+
+ set
+ {
+ targetOS = value.ToLower();
+ }
+ }
+
+ ///
+ /// Target arch, can be "arm64", "arm" or "x64" at the moment
+ ///
+ [Required]
+ public string Arch { get; set; } = ""!;
+
+ ///
+ /// Path to the .xcodeproj file
+ ///
+ [Required]
+ public string XcodeProjectPath { get; set; } = ""!;
+
+ ///
+ /// DEVELOPER_TEAM provisioning, needed for arm64 builds.
+ ///
+ public string? DevTeamProvisioning { get; set; }
+
+ ///
+ /// Produce optimized binaries and use 'Release' config in xcode
+ ///
+ public bool Optimized { get; set; }
+
+ /// Path to the directory where the .app should be created
+ ///
+ public string? DestinationFolder { get; set; }
+
+ public override bool Execute()
+ {
+ new Xcode(Log, TargetOS, Arch).BuildAppBundle(XcodeProjectPath, Optimized, DevTeamProvisioning, DestinationFolder);
+
+ return true;
+ }
+}
+
internal class Xcode
{
private string RuntimeIdentifier { get; set; }
- private string SysRoot { get; set; }
private string Target { get; set; }
private string XcodeArch { get; set; }
private TaskLoggingHelper Logger { get; set; }
@@ -21,33 +122,71 @@ public Xcode(TaskLoggingHelper logger, string target, string arch)
{
Logger = logger;
Target = target;
- XcodeArch = (arch == "x64") ? "x86_64" : arch;
+ RuntimeIdentifier = $"{Target}-{arch}";
+ XcodeArch = arch switch {
+ "x64" => "x86_64",
+ "arm" => "armv7",
+ _ => arch
+ };
+ }
+
+ public string GenerateXCode(
+ string projectName,
+ string entryPointLib,
+ IEnumerable asmFiles,
+ IEnumerable asmLinkFiles,
+ string workspace,
+ string binDir,
+ string monoInclude,
+ bool preferDylibs,
+ bool useConsoleUiTemplate,
+ bool forceAOT,
+ bool forceInterpreter,
+ bool invariantGlobalization,
+ bool optimized,
+ bool enableRuntimeLogging,
+ string? diagnosticPorts,
+ string? runtimeComponents=null,
+ string? nativeMainSource = null)
+ {
+ var cmakeDirectoryPath = GenerateCMake(projectName, entryPointLib, asmFiles, asmLinkFiles, workspace, binDir, monoInclude, preferDylibs, useConsoleUiTemplate, forceAOT, forceInterpreter, invariantGlobalization, optimized, enableRuntimeLogging, diagnosticPorts, runtimeComponents, nativeMainSource);
+ CreateXcodeProject(projectName, cmakeDirectoryPath);
+ return Path.Combine(binDir, projectName, projectName + ".xcodeproj");
+ }
+
+ public void CreateXcodeProject(string projectName, string cmakeDirectoryPath)
+ {
+ string targetName;
switch (Target)
{
- case TargetNames.iOS:
- SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk iphoneos --show-sdk-path");
+ case TargetNames.MacCatalyst:
+ targetName = "Darwin";
break;
+ case TargetNames.iOS:
case TargetNames.iOSsim:
- SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk iphonesimulator --show-sdk-path");
+ targetName = "iOS";
break;
case TargetNames.tvOS:
- SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk appletvos --show-sdk-path");
- break;
case TargetNames.tvOSsim:
- SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk appletvsimulator --show-sdk-path");
+ targetName = "tvOS";
break;
default:
- SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk macosx --show-sdk-path");
+ targetName = Target.ToString();
break;
}
+ var deployTarget = (Target == TargetNames.MacCatalyst) ? " -DCMAKE_OSX_ARCHITECTURES=" + XcodeArch : " -DCMAKE_OSX_DEPLOYMENT_TARGET=10.1";
+ var cmakeArgs = new StringBuilder();
+ cmakeArgs
+ .Append("-S.")
+ .Append(" -B").Append(projectName)
+ .Append(" -GXcode")
+ .Append(" -DCMAKE_SYSTEM_NAME=").Append(targetName)
+ .Append(deployTarget);
- RuntimeIdentifier = $"{Target}-{arch}";
+ Utils.RunProcess(Logger, "cmake", cmakeArgs.ToString(), workingDir: cmakeDirectoryPath);
}
- public bool EnableRuntimeLogging { get; set; }
- public string? DiagnosticPorts { get; set; } = ""!;
-
- public string GenerateXCode(
+ public string GenerateCMake(
string projectName,
string entryPointLib,
IEnumerable asmFiles,
@@ -60,13 +199,15 @@ public string GenerateXCode(
bool forceAOT,
bool forceInterpreter,
bool invariantGlobalization,
- bool stripDebugSymbols,
+ bool optimized,
+ bool enableRuntimeLogging,
+ string? diagnosticPorts,
string? runtimeComponents=null,
string? nativeMainSource = null)
{
// bundle everything as resources excluding native files
var excludes = new List { ".dll.o", ".dll.s", ".dwarf", ".m", ".h", ".a", ".bc", "libmonosgen-2.0.dylib", "libcoreclr.dylib" };
- if (stripDebugSymbols)
+ if (optimized)
{
excludes.Add(".pdb");
}
@@ -181,9 +322,9 @@ public string GenerateXCode(
{
// these libraries are linked via modules.m
var name = Path.GetFileNameWithoutExtension(asm);
- aotSources += $"add_library({name} OBJECT {asm}){Environment.NewLine}";
- toLink += $" {name}{Environment.NewLine}";
- aotList += $" {name}";
+ aotSources += $"add_library({projectName}_{name} OBJECT {asm}){Environment.NewLine}";
+ toLink += $" {projectName}_{name}{Environment.NewLine}";
+ aotList += $" {projectName}_{name}";
}
foreach (string asmLinkFile in asmLinkFiles)
@@ -219,14 +360,14 @@ public string GenerateXCode(
defines.AppendLine("add_definitions(-DINVARIANT_GLOBALIZATION=1)");
}
- if (EnableRuntimeLogging)
+ if (enableRuntimeLogging)
{
defines.AppendLine("add_definitions(-DENABLE_RUNTIME_LOGGING=1)");
}
- if (!string.IsNullOrEmpty(DiagnosticPorts))
+ if (!string.IsNullOrEmpty(diagnosticPorts))
{
- defines.AppendLine($"\nadd_definitions(-DDIAGNOSTIC_PORTS=\"{DiagnosticPorts}\")");
+ defines.AppendLine($"\nadd_definitions(-DDIAGNOSTIC_PORTS=\"{diagnosticPorts}\")");
}
cmakeLists = cmakeLists.Replace("%Defines%", defines.ToString());
@@ -252,33 +393,6 @@ public string GenerateXCode(
File.WriteAllText(Path.Combine(binDir, "app.entitlements"), entitlementsTemplate.Replace("%Entitlements%", ent.ToString()));
}
- string targetName;
- switch (Target)
- {
- case TargetNames.MacCatalyst:
- targetName = "Darwin";
- break;
- case TargetNames.iOS:
- case TargetNames.iOSsim:
- targetName = "iOS";
- break;
- case TargetNames.tvOS:
- case TargetNames.tvOSsim:
- targetName = "tvOS";
- break;
- default:
- targetName = Target.ToString();
- break;
- }
- var deployTarget = (Target == TargetNames.MacCatalyst) ? " -DCMAKE_OSX_ARCHITECTURES=" + XcodeArch : " -DCMAKE_OSX_DEPLOYMENT_TARGET=10.1";
- var cmakeArgs = new StringBuilder();
- cmakeArgs
- .Append("-S.")
- .Append(" -B").Append(projectName)
- .Append(" -GXcode")
- .Append(" -DCMAKE_SYSTEM_NAME=").Append(targetName)
- .Append(deployTarget);
-
File.WriteAllText(Path.Combine(binDir, "runtime.h"),
Utils.GetEmbeddedResource("runtime.h"));
@@ -302,13 +416,11 @@ public string GenerateXCode(
.Replace("//%APPLE_RUNTIME_IDENTIFIER%", RuntimeIdentifier)
.Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib)));
- Utils.RunProcess(Logger, "cmake", cmakeArgs.ToString(), workingDir: binDir);
-
- return Path.Combine(binDir, projectName, projectName + ".xcodeproj");
+ return binDir;
}
public string BuildAppBundle(
- string xcodePrjPath, string architecture, bool optimized, string? devTeamProvisioning = null)
+ string xcodePrjPath, bool optimized, string? devTeamProvisioning = null, string? destination = null)
{
string sdk = "";
var args = new StringBuilder();
@@ -330,29 +442,28 @@ public string BuildAppBundle(
.Append(" DEVELOPMENT_TEAM=").Append(devTeamProvisioning);
}
-
- if (architecture == "arm64")
+ if (XcodeArch == "arm64" || XcodeArch == "armv7")
{
switch (Target)
{
case TargetNames.iOS:
sdk = "iphoneos";
- args.Append(" -arch arm64")
+ args.Append(" -arch " + XcodeArch)
.Append(" -sdk ").Append(sdk);
break;
case TargetNames.iOSsim:
sdk = "iphonesimulator";
- args.Append(" -arch arm64")
+ args.Append(" -arch " + XcodeArch)
.Append(" -sdk ").Append(sdk);
break;
case TargetNames.tvOS:
sdk = "appletvos";
- args.Append(" -arch arm64")
+ args.Append(" -arch " + XcodeArch)
.Append(" -sdk ").Append(sdk);
break;
case TargetNames.tvOSsim:
sdk = "appletvsimulator";
- args.Append(" -arch arm64")
+ args.Append(" -arch " + XcodeArch)
.Append(" -sdk ").Append(sdk);
break;
default:
@@ -372,12 +483,12 @@ public string BuildAppBundle(
{
case TargetNames.iOSsim:
sdk = "iphonesimulator";
- args.Append(" -arch x86_64")
+ args.Append(" -arch " + XcodeArch)
.Append(" -sdk ").Append(sdk);
break;
case TargetNames.tvOSsim:
sdk = "appletvsimulator";
- args.Append(" -arch x86_64")
+ args.Append(" -arch " + XcodeArch)
.Append(" -sdk ").Append(sdk);
break;
default:
@@ -400,6 +511,13 @@ public string BuildAppBundle(
string appPath = Path.Combine(Path.GetDirectoryName(xcodePrjPath)!, config + "-" + sdk,
Path.GetFileNameWithoutExtension(xcodePrjPath) + ".app");
+ if (destination != null)
+ {
+ var newAppPath = Path.Combine(destination, Path.GetFileNameWithoutExtension(xcodePrjPath) + ".app");
+ Directory.Move(appPath, newAppPath);
+ appPath = newAppPath;
+ }
+
long appSize = new DirectoryInfo(appPath)
.EnumerateFiles("*", SearchOption.AllDirectories)
.Sum(file => file.Length);