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 698e5884ccf05..c62916ed2d15a 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
@@ -159,6 +162,10 @@
true
AppleTestRunner.dll
<_MobileIntermediateOutputPath Condition="'$(RunAOTCompilation)' == 'true'">$(IntermediateOutputPath)mobile
+ true
+ false
+ false
+ true
Full
@@ -217,8 +224,9 @@
ForceInterpreter="$(MonoForceInterpreter)"
InvariantGlobalization="$(InvariantGlobalization)"
UseConsoleUITemplate="True"
- GenerateXcodeProject="True"
- BuildAppBundle="True"
+ GenerateXcodeProject="$(GenerateXcodeProject)"
+ GenerateCMakeProject="$(GenerateCMakeProject)"
+ BuildAppBundle="$(GenerateXcodeProject)"
Optimized="$(Optimized)"
DevTeamProvisioning="$(DevTeamProvisioning)"
OutputDirectory="$(BundleDir)"
@@ -226,17 +234,17 @@
-
-
+
+
-
+
<_appFiles Include="$(AppBundlePath)/../**/*" />
+ Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true' and '$(GenerateXcodeProject)' == 'true'" />
diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props
index e7d17e8005c17..635f2bfc037ce 100644
--- a/src/libraries/Directory.Build.props
+++ b/src/libraries/Directory.Build.props
@@ -116,6 +116,9 @@
$(TestArchiveTestsRoot)$(OSPlatformConfig)/
$(TestArchiveRoot)runtime/
+ true
+ $(ArtifactsDir)bundles\
+
$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'ref', '$(NetCoreAppCurrent)'))
$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'runtime', '$(NetCoreAppCurrent)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)'))
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 5c3c8dcf0c9b0..95e71caccc534 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -332,6 +332,85 @@
Condition="'$(TestAssemblies)' == 'true' and
'$(Coverage)' == '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);