[net8.0] Merge main into net8.0.
This commit is contained in:
Коммит
ce19b092c2
|
@ -509,6 +509,7 @@
|
|||
SdkDevPath=$(_SdkDevPath)
|
||||
SdkRootDirectory=$(_XamarinSdkRootDirectory)
|
||||
SdkVersion=$(_SdkVersion)
|
||||
SkipMarkingNSObjectsInUserAssemblies=$(_SkipMarkingNSObjectsInUserAssemblies)
|
||||
TargetArchitectures=$(TargetArchitectures)
|
||||
TargetFramework=$(_ComputedTargetFrameworkMoniker)
|
||||
UseLlvm=$(MtouchUseLlvm)
|
||||
|
@ -1408,10 +1409,16 @@
|
|||
<_AssemblyPublishDir Condition="'$(_PlatformName)' == 'macOS' Or '$(_PlatformName)' == 'MacCatalyst'">$(_RelativeAppBundlePath)\Contents\$(_CustomBundleName)\</_AssemblyPublishDir>
|
||||
<_DylibPublishDir Condition="'$(_PlatformName)' == 'iOS' Or '$(_PlatformName)' == 'tvOS' Or '$(_PlatformName)' == 'watchOS'">$(_RelativeAppBundlePath)\</_DylibPublishDir>
|
||||
<_DylibPublishDir Condition="'$(_PlatformName)' == 'macOS' Or '$(_PlatformName)' == 'MacCatalyst'">$(_RelativeAppBundlePath)\Contents\$(_CustomBundleName)\</_DylibPublishDir>
|
||||
<!-- _ParsedRuntimeConfigFilePath must be relative to the project directory, since it's not copied to the publish directory by the the CopyFilesToPublishDirectory targets -->
|
||||
<_ParsedRuntimeConfigFilePath Condition="'$(_ParsedRuntimeConfigFilePath)' == ''">$([MSBuild]::MakeRelative($(MSBuildProjectDirectory),$(_AbsolutePublishDir)\$(_AssemblyPublishDir)\$(_RuntimeConfigurationFile)))</_ParsedRuntimeConfigFilePath>
|
||||
<_ParsedRuntimeConfigFilePath Condition="'$(_ParsedRuntimeConfigFilePath)' == ''">$(DeviceSpecificIntermediateOutputPath)$(_RuntimeConfigurationFile)</_ParsedRuntimeConfigFilePath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Add runtimeconfig.bin to ResolvedFileToPublish so we process it in ComputeBundlePath and copy the file to the app bundle -->
|
||||
<ResolvedFileToPublish Include="$(_ParsedRuntimeConfigFilePath)" Condition="'$(GenerateRuntimeConfigurationFiles)' == 'true'">
|
||||
<RelativePath>$([System.IO.Path]::GetFileName('$(_ParsedRuntimeConfigFilePath)'))</RelativePath>
|
||||
<PublishFolderType>Assembly</PublishFolderType>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</ResolvedFileToPublish>
|
||||
|
||||
<!--
|
||||
Remove any items we've already handled elsewhere
|
||||
-->
|
||||
|
@ -1651,15 +1658,20 @@
|
|||
Outputs="@(_CompressedPlugIns -> '$(_IntermediateDecompressionDir)%(Filename)%(Extension).stamp')"
|
||||
>
|
||||
|
||||
<Ditto
|
||||
<ItemGroup>
|
||||
<_CompressedPlugIns Update="@(_CompressedPlugIns)">
|
||||
<ExtractionPath>$([MSBuild]::EnsureTrailingSlash('$(_IntermediateDecompressionDir)%(_CompressedPlugIns.Filename)%(_CompressedPlugIns.Extension)'))</ExtractionPath>
|
||||
</_CompressedPlugIns>
|
||||
</ItemGroup>
|
||||
|
||||
<Unzip
|
||||
SessionId="$(BuildSessionId)"
|
||||
Condition="'$(IsMacEnabled)' == 'true'"
|
||||
AdditionalArguments="-x -k"
|
||||
CopyFromWindows="true"
|
||||
Source="%(_CompressedPlugIns.Identity)"
|
||||
Destination="$(_IntermediateDecompressionDir)%(Filename)%(Extension)"
|
||||
ZipFilePath="%(_CompressedPlugIns.Identity)"
|
||||
ExtractionPath="%(_CompressedPlugIns.ExtractionPath)"
|
||||
>
|
||||
</Ditto>
|
||||
<Output TaskParameter="TouchedFiles" ItemName="FileWrites" />
|
||||
</Unzip>
|
||||
</Target>
|
||||
|
||||
<Target Name="_CollectDecompressedPlugIns"
|
||||
|
@ -1668,24 +1680,15 @@
|
|||
|
||||
<ItemGroup>
|
||||
<!-- Set TargetDirectory and SourceDirectory for all directories we have to publish -->
|
||||
<_DecompressedPlugIns Include="@(_CompressedPlugIns -> '$(_IntermediateDecompressionDir)%(Filename)%(Extension)')" />
|
||||
<_DecompressedPlugIns Include="@(_CompressedPlugIns -> '%(ExtractionPath)')" PublishFolderType="PlugIns" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<_DecompressedPlugIns Update="@(_DecompressedPlugIns)">
|
||||
<TargetDirectory>$(_RelativePublishDir)$(_RelativeAppBundlePath)$(_AppPlugInsRelativePath)</TargetDirectory>
|
||||
<SourceDirectory>$(_IntermediateDecompressionDir)%(Filename)%(Extension)</SourceDirectory>
|
||||
<SourceDirectory>%(ExtractionPath)</SourceDirectory>
|
||||
</_DecompressedPlugIns>
|
||||
</ItemGroup>
|
||||
|
||||
<Touch
|
||||
SessionId="$(BuildSessionId)"
|
||||
Condition="'$(IsMacEnabled)' == 'true'"
|
||||
AlwaysCreate="true"
|
||||
Files="@(_CompressedPlugIns -> '$(_IntermediateDecompressionDir)%(Filename)%(Extension).stamp')"
|
||||
>
|
||||
<Output TaskParameter="TouchedFiles" ItemName="FileWrites" />
|
||||
</Touch>
|
||||
|
||||
<ItemGroup>
|
||||
<_DirectoriesToPublish Include="@(_DecompressedPlugIns)" />
|
||||
</ItemGroup>
|
||||
|
@ -1753,6 +1756,7 @@
|
|||
<MlaunchEnvironmentVariables Include="__XAMARIN_DEBUG_MODE__=$(XamarinDebugMode)" Condition="'$(XamarinDebugMode)' != ''" />
|
||||
<MlaunchEnvironmentVariables Include="__XAMARIN_DEBUG_PORT__=$(XamarinDebugPort)" Condition="'$(XamarinDebugPort)' != ''" />
|
||||
<MlaunchEnvironmentVariables Include="__XAMARIN_DEBUG_HOSTS__=$(XamarinDebugHosts.Replace(';', '%3B'))" Condition="'$(XamarinDebugHosts)' != ''" />
|
||||
<MlaunchEnvironmentVariables Include="__XAMARIN_DEBUG_CONNECT_TIMEOUT__=$(XamarinDebugConnectTimeout)" Condition="'$(XamarinDebugConnectTimeout)' != ''" />
|
||||
<!-- It's not possible to set an item group from the command line, so add support for setting a property (with semi-colon separated items) that we'll include into the item group -->
|
||||
<MlaunchAdditionalArguments Include="$(MlaunchAdditionalArgumentsProperty)" Condition="'$(MlaunchAdditionalArgumentsProperty)' != ''" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -72,9 +72,6 @@ namespace Xamarin.MacDev.Tasks {
|
|||
|
||||
public string ResourceRules { get; set; } = String.Empty;
|
||||
|
||||
[Required]
|
||||
public string SdkPlatform { get; set; } = String.Empty;
|
||||
|
||||
[Required]
|
||||
public bool SdkIsSimulator { get; set; }
|
||||
|
||||
|
@ -92,6 +89,12 @@ namespace Xamarin.MacDev.Tasks {
|
|||
IPhoneDeviceType supportedDevices;
|
||||
AppleSdkVersion sdkVersion;
|
||||
|
||||
public string SdkPlatform {
|
||||
get {
|
||||
return GetSdkPlatform (SdkIsSimulator);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
PDictionary plist;
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace Xamarin.MacDev.Tasks {
|
|||
[Required]
|
||||
public bool SdkIsSimulator { get; set; }
|
||||
|
||||
public string ConnectTimeout { get; set; }
|
||||
#endregion
|
||||
|
||||
public override bool Execute ()
|
||||
|
@ -52,6 +53,11 @@ namespace Xamarin.MacDev.Tasks {
|
|||
builder.Append ("Port: ");
|
||||
builder.AppendLine (DebuggerPort);
|
||||
|
||||
if (!string.IsNullOrEmpty (ConnectTimeout)) {
|
||||
builder.Append ("Connect Timeout: ");
|
||||
builder.AppendLine (ConnectTimeout);
|
||||
}
|
||||
|
||||
var text = builder.ToString ();
|
||||
|
||||
try {
|
||||
|
|
|
@ -53,6 +53,9 @@ namespace Xamarin.MacDev.Tasks {
|
|||
[Output]
|
||||
public string NoStrip { get; set; }
|
||||
|
||||
[Output]
|
||||
public string SkipMarkingNSObjectsInUserAssemblies { get; set; }
|
||||
|
||||
[Output]
|
||||
public int Verbosity { get; set; }
|
||||
|
||||
|
@ -165,6 +168,9 @@ namespace Xamarin.MacDev.Tasks {
|
|||
item.SetMetadata ("Value", value.Substring (colon + 1));
|
||||
envVariables.Add (item);
|
||||
break;
|
||||
case "skip-marking-nsobjects-in-user-assemblies":
|
||||
SkipMarkingNSObjectsInUserAssemblies = ParseBool (value) ? "true" : "false";
|
||||
break;
|
||||
case "xml":
|
||||
if (xml == null)
|
||||
xml = new List<string> ();
|
||||
|
|
|
@ -11,9 +11,6 @@ namespace Xamarin.MacDev.Tasks {
|
|||
public abstract class ReadAppManifestTaskBase : XamarinTask {
|
||||
public ITaskItem? AppManifest { get; set; }
|
||||
|
||||
[Required]
|
||||
public string? SdkVersion { get; set; }
|
||||
|
||||
[Output]
|
||||
public string? CLKComplicationGroup { get; set; }
|
||||
|
||||
|
@ -70,7 +67,7 @@ namespace Xamarin.MacDev.Tasks {
|
|||
if (Platform == ApplePlatform.MacCatalyst) {
|
||||
// The minimum version in the Info.plist is the macOS version. However, the rest of our tooling
|
||||
// expects the iOS version, so expose that.
|
||||
if (!MacCatalystSupport.TryGetiOSVersion (Sdks.GetAppleSdk (Platform).GetSdkPath (SdkVersion, false), MinimumOSVersion!, out var convertedVersion, out var knownMacOSVersions))
|
||||
if (!MacCatalystSupport.TryGetiOSVersion (Sdks.GetAppleSdk (Platform).GetSdkPath (string.Empty, false), MinimumOSVersion!, out var convertedVersion, out var knownMacOSVersions))
|
||||
Log.LogError (MSBStrings.E0187, MinimumOSVersion, string.Join (", ", knownMacOSVersions));
|
||||
MinimumOSVersion = convertedVersion;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
using Xamarin.Bundler;
|
||||
using Xamarin.Localization.MSBuild;
|
||||
using Xamarin.MacDev;
|
||||
using Xamarin.Messaging.Build.Client;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Xamarin.MacDev.Tasks {
|
||||
/// <summary>
|
||||
/// This task will extract the specified zip file into the specified extraction path.
|
||||
/// This task works on Windows too, but if the task encounters a symlink while extracting, an error will be shown.
|
||||
/// </summary>
|
||||
public class Unzip : XamarinTask, ITaskCallback {
|
||||
[Required]
|
||||
public ITaskItem? ZipFilePath { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ExtractionPath { get; set; } = string.Empty;
|
||||
|
||||
// The file or directory to extract from the zip file.
|
||||
// If not specified, the entire zip file is extracted.
|
||||
public string Resource { get; set; } = string.Empty;
|
||||
|
||||
[Output]
|
||||
public ITaskItem [] TouchedFiles { get; set; } = Array.Empty<ITaskItem> ();
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
if (ShouldExecuteRemotely ())
|
||||
return new TaskRunner (SessionId, BuildEngine4).RunAsync (this).Result;
|
||||
|
||||
return ExecuteLocally ();
|
||||
}
|
||||
|
||||
public void Cancel ()
|
||||
{
|
||||
if (ShouldExecuteRemotely ())
|
||||
BuildConnection.CancelAsync (BuildEngine4).Wait ();
|
||||
}
|
||||
|
||||
public bool ShouldCopyToBuildServer (ITaskItem item) => true;
|
||||
|
||||
public bool ShouldCreateOutputFile (ITaskItem item) => true;
|
||||
|
||||
public IEnumerable<ITaskItem> GetAdditionalItemsToBeCopied () => Enumerable.Empty<ITaskItem> ();
|
||||
|
||||
bool ExecuteLocally ()
|
||||
{
|
||||
var createdFiles = new List<string> ();
|
||||
if (!CompressionHelper.TryDecompress (Log, ZipFilePath!.ItemSpec, Resource, ExtractionPath, createdFiles, out var _))
|
||||
return false;
|
||||
|
||||
TouchedFiles = createdFiles.Select (v => new TaskItem (v)).ToArray ();
|
||||
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -111,6 +111,7 @@ Copyright (C) 2018 Microsoft. All rights reserved.
|
|||
<UsingTask TaskName="Xamarin.MacDev.Tasks.SymbolStrip" AssemblyFile="$(_TaskAssemblyName)" />
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.TextureAtlas" AssemblyFile="$(_TaskAssemblyName)" />
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.UnpackLibraryResources" AssemblyFile="$(_TaskAssemblyName)" />
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.Unzip" AssemblyFile="$(_TaskAssemblyName)" />
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.WriteAppManifest" AssemblyFile="$(_TaskAssemblyName)" />
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.WriteItemsToFile" AssemblyFile="$(_TaskAssemblyName)" />
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.Zip" AssemblyFile="$(_TaskAssemblyName)" />
|
||||
|
@ -554,7 +555,6 @@ Copyright (C) 2018 Microsoft. All rights reserved.
|
|||
ResourceRules="$(_PreparedResourceRules)"
|
||||
TargetArchitectures="$(TargetArchitectures)"
|
||||
TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)"
|
||||
SdkPlatform="$(_SdkPlatform)"
|
||||
SdkIsSimulator="$(_SdkIsSimulator)"
|
||||
SdkVersion="$(_SdkVersion)"
|
||||
SupportedOSPlatformVersion="$(SupportedOSPlatformVersion)"
|
||||
|
@ -579,7 +579,6 @@ Copyright (C) 2018 Microsoft. All rights reserved.
|
|||
Condition="'$(IsMacEnabled)' == 'true'"
|
||||
SessionId="$(BuildSessionId)"
|
||||
AppManifest="$(_TemporaryAppManifest)"
|
||||
SdkVersion="$(_SdkVersion)"
|
||||
TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)"
|
||||
>
|
||||
<Output TaskParameter="CFBundleExecutable" PropertyName="_ExecutableName" />
|
||||
|
@ -1851,6 +1850,7 @@ Copyright (C) 2018 Microsoft. All rights reserved.
|
|||
<Output TaskParameter="PackageDebugSymbols" PropertyName="PackageDebugSymbols" />
|
||||
<Output TaskParameter="Registrar" PropertyName="Registrar" />
|
||||
<Output TaskParameter="RequirePInvokeWrappers" PropertyName="_RequirePInvokeWrappers" />
|
||||
<Output TaskParameter="SkipMarkingNSObjectsInUserAssemblies" PropertyName="_SkipMarkingNSObjectsInUserAssemblies" />
|
||||
<Output TaskParameter="Verbosity" PropertyName="_BundlerVerbosity" />
|
||||
<Output TaskParameter="XmlDefinitions" ItemName="_BundlerXmlDefinitions" />
|
||||
<Output TaskParameter="NoStrip" PropertyName="EnableAssemblyILStripping" />
|
||||
|
@ -2369,6 +2369,7 @@ Copyright (C) 2018 Microsoft. All rights reserved.
|
|||
SessionId="$(BuildSessionId)"
|
||||
Condition="'$(IsMacEnabled)' == 'true'"
|
||||
AppBundleDir="$(_AppResourcesPath)"
|
||||
ConnectTimeout="$(IOSDebugConnectTimeout)"
|
||||
DebugOverWiFi="$(IOSDebugOverWiFi)"
|
||||
DebugIPAddresses="$(_DebugIPAddresses)"
|
||||
DebuggerPort="$(IOSDebuggerPort)"
|
||||
|
|
|
@ -47,24 +47,6 @@ namespace Xamarin.iOS.Tasks.Windows.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
internal static string Unzip_Error {
|
||||
get {
|
||||
return ResourceManager.GetString("Unzip_Error", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Unzip_Unzipped {
|
||||
get {
|
||||
return ResourceManager.GetString("Unzip_Unzipped", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Unzip_Unzipping {
|
||||
get {
|
||||
return ResourceManager.GetString("Unzip_Unzipping", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string CollectDynamicFrameworks_InvalidFramework {
|
||||
get {
|
||||
return ResourceManager.GetString("CollectDynamicFrameworks_InvalidFramework", resourceCulture);
|
||||
|
|
|
@ -12,15 +12,6 @@
|
|||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Unzip_Error" xml:space="preserve">
|
||||
<value>There was an error unzipping the file {0}: {1}</value>
|
||||
</data>
|
||||
<data name="Unzip_Unzipped" xml:space="preserve">
|
||||
<value>Successfully unzipped the file {0}</value>
|
||||
</data>
|
||||
<data name="Unzip_Unzipping" xml:space="preserve">
|
||||
<value>Unzipping {0}...</value>
|
||||
</data>
|
||||
<data name="CollectDynamicFrameworks_InvalidFramework" xml:space="preserve">
|
||||
<value>Skipping invalid framework {0}. Reason: {1}</value>
|
||||
<comment>0: framework name; 1: why the framework was skipped</comment>
|
||||
|
|
|
@ -8,7 +8,7 @@ using Xamarin.iOS.Tasks.Windows.Properties;
|
|||
using Xamarin.iOS.Windows;
|
||||
|
||||
namespace Xamarin.iOS.HotRestart.Tasks {
|
||||
public class Codesign : Task, ICancelableTask {
|
||||
public class CodesignHotRestartApp : Task, ICancelableTask {
|
||||
#region Inputs
|
||||
|
||||
[Required]
|
|
@ -9,7 +9,7 @@ using Xamarin.MacDev;
|
|||
#nullable enable
|
||||
|
||||
namespace Xamarin.iOS.HotRestart.Tasks {
|
||||
public class CompileAppManifest : Task {
|
||||
public class CompileHotRestartAppManifest : Task {
|
||||
static readonly string [] IgnorePlistKeys = {
|
||||
"XSAppIconAssets",
|
||||
"CFBundleIconName",
|
|
@ -36,9 +36,6 @@ namespace Xamarin.iOS.HotRestart.Tasks {
|
|||
// Single-project property that maps to CFBundleIdentifier
|
||||
public string ApplicationId { get; set; }
|
||||
|
||||
// Single-project property that maps to CFBundleDisplayName
|
||||
public string ApplicationTitle { get; set; }
|
||||
|
||||
[Required]
|
||||
public string AppManifest { get; set; }
|
||||
|
||||
|
@ -65,9 +62,6 @@ namespace Xamarin.iOS.HotRestart.Tasks {
|
|||
[Output]
|
||||
public string DetectedBundleId { get; set; }
|
||||
|
||||
[Output]
|
||||
public string DetectedAppDisplayName { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Execute ()
|
||||
|
@ -105,16 +99,6 @@ namespace Xamarin.iOS.HotRestart.Tasks {
|
|||
|
||||
DetectedBundleId = identity.BundleId;
|
||||
|
||||
var appDisplayName = plist.GetCFBundleDisplayName ();
|
||||
|
||||
if (string.IsNullOrEmpty (appDisplayName)) {
|
||||
if (GenerateApplicationManifest && !string.IsNullOrEmpty (ApplicationTitle)) {
|
||||
appDisplayName = ApplicationTitle;
|
||||
}
|
||||
}
|
||||
|
||||
DetectedAppDisplayName = appDisplayName;
|
||||
|
||||
if (!TryGetSigningCertificates (out certs, false))
|
||||
return false;
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using Xamarin.iOS.Tasks.Windows.Properties;
|
||||
|
||||
namespace Xamarin.iOS.Tasks.Windows {
|
||||
public class Unzip : Task {
|
||||
[Required]
|
||||
public string ZipFilePath { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ExtractionPath { get; set; }
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
LogTaskProperty ("ZipFilePath", ZipFilePath);
|
||||
LogTaskProperty ("ExtractionPath", ExtractionPath);
|
||||
|
||||
try {
|
||||
Log.LogMessage (Resources.Unzip_Unzipping, ZipFilePath);
|
||||
|
||||
Zip.Extract (ZipFilePath, ExtractionPath);
|
||||
|
||||
Log.LogMessage (Resources.Unzip_Unzipped, ZipFilePath);
|
||||
} catch (Exception ex) {
|
||||
Log.LogError (Resources.Unzip_Error, ZipFilePath, ex.Message);
|
||||
}
|
||||
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
|
||||
//TODO: Ideally we should get this from the LoggingExtensions in Xamarin.MacDev.Tasks. We would need the reference for that
|
||||
void LogTaskProperty (string propertyName, string value)
|
||||
{
|
||||
Log.LogMessage (MessageImportance.Normal, " {0}: {1}", propertyName, value ?? "<null>");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,13 +12,13 @@ Copyright (C) 2011-2013 Xamarin. All rights reserved.
|
|||
***********************************************************************************************
|
||||
-->
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.Unzip" AssemblyFile="$(CoreiOSSdkDirectory)Xamarin.iOS.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.WriteItemsToFile" AssemblyFile="$(CoreiOSSdkDirectory)Xamarin.iOS.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.Zip" AssemblyFile="$(CoreiOSSdkDirectory)Xamarin.iOS.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.Tasks.CopyArchiveFiles" AssemblyFile="$(CoreiOSSdkDirectory)Xamarin.iOS.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.Tasks.ILLink" AssemblyFile="$(CoreiOSSdkDirectory)Xamarin.iOS.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.Tasks.Windows.CreateArchiveDirectory" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.Tasks.Windows.ResolveUniversalTypeIdentifiers" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.Tasks.Windows.Unzip" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)Xamarin.Messaging.Build.targets" Condition="Exists('$(MSBuildThisFileDirectory)Xamarin.Messaging.Build.targets') And '$(MessagingBuildTargetsImported)' != 'true'" />
|
||||
<Import Project="$(MSBuildThisFileDirectory)Xamarin.iOS.Windows.After.targets" Condition="Exists('$(MSBuildThisFileDirectory)Xamarin.iOS.Windows.After.targets')" />
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.CompileEntitlements" AssemblyFile="Xamarin.iOS.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.Tasks.UnpackLibraryResources" AssemblyFile="Xamarin.iOS.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.Codesign" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.CodesignHotRestartApp" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.CollectDynamicFrameworks" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.CompileAppManifest" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.DetectSigningIdentity" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.CompileHotRestartAppManifest" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.DetectHotRestartSigningIdentity" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.PrepareAppBundle" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.UnpackFrameworks" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
|
||||
|
||||
|
@ -35,22 +35,21 @@
|
|||
<Target Name="_DetectHotRestartSigningIdentity" AfterTargets="_DetectAppManifest"
|
||||
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsHotRestartBuild)' == 'true' And '$(IsHotRestartEnvironmentReady)' == 'true'" >
|
||||
|
||||
<HotRestart.Tasks.DetectSigningIdentity
|
||||
<DetectHotRestartSigningIdentity
|
||||
Condition="'$(EnableCodeSigning)' != 'false'"
|
||||
GenerateApplicationManifest="$(GenerateApplicationManifest)"
|
||||
ApplicationId="$(ApplicationId)"
|
||||
ApplicationTitle="$(ApplicationTitle)"
|
||||
AppManifest="$(AppBundleManifest)"
|
||||
ProvisioningProfile="$(CodesignProvision)"
|
||||
SigningKey="$(CodesignKey)">
|
||||
|
||||
<Output TaskParameter="DetectedAppId" PropertyName="_AppIdentifier" />
|
||||
<Output TaskParameter="DetectedBundleId" PropertyName="_BundleIdentifier" />
|
||||
<Output TaskParameter="DetectedAppDisplayName" PropertyName="_AppDisplayName" />
|
||||
<Output TaskParameter="DetectedCodeSigningPath" PropertyName="_CodeSigningPath" />
|
||||
<Output TaskParameter="DetectedProvisioningProfileId" PropertyName="_ProvisioningProfileId" />
|
||||
<Output TaskParameter="DetectedProvisioningProfilePath" PropertyName="_ProvisioningProfilePath" />
|
||||
</HotRestart.Tasks.DetectSigningIdentity>
|
||||
</DetectHotRestartSigningIdentity>
|
||||
|
||||
</Target>
|
||||
|
||||
<Target Name="_CollectHotRestartBundleResources" Condition="'$(IsHotRestartBuild)' == 'true'">
|
||||
|
@ -193,7 +192,7 @@
|
|||
Inputs="$(AppBundleManifest);$(HotRestartAppBundlePath)\Extracted"
|
||||
Outputs="$(HotRestartSignedAppDir)$([System.IO.Path]::GetFileName('$(AppBundleManifest)'));$(HotRestartSignedAppDir)Extracted">
|
||||
|
||||
<HotRestart.Tasks.CompileAppManifest
|
||||
<CompileHotRestartAppManifest
|
||||
AppBundlePath="$(HotRestartAppBundlePath)"
|
||||
AppManifestPath="$(AppBundleManifest)"
|
||||
ApplicationTitle="$(ApplicationTitle)"/>
|
||||
|
@ -332,7 +331,7 @@
|
|||
Inputs="@(_CodeSignHotRestartInputs)"
|
||||
Outputs="@(_CodeSignHotRestartInputs -> '%(Outputs)')">
|
||||
|
||||
<HotRestart.Tasks.Codesign
|
||||
<CodesignHotRestartApp
|
||||
AppBundlePath="$(HotRestartAppBundlePath)"
|
||||
BundleIdentifier="$(_BundleIdentifier)"
|
||||
CodeSigningPath="$(_CodeSigningPath)"
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
using Microsoft.Build.Framework;
|
||||
using Xamarin.Messaging.Build.Client;
|
||||
|
||||
namespace Xamarin.iOS.Tasks {
|
||||
public class FindWatchOS2AppBundle : FindWatchOS2AppBundleTaskBase, ICancelableTask {
|
||||
public override bool Execute ()
|
||||
{
|
||||
if (!ShouldExecuteRemotely ())
|
||||
return base.Execute ();
|
||||
|
||||
var taskRunner = new TaskRunner (SessionId, BuildEngine4);
|
||||
|
||||
taskRunner.FixReferencedItems (WatchAppReferences);
|
||||
|
||||
return taskRunner.RunAsync (this).Result;
|
||||
}
|
||||
|
||||
public void Cancel ()
|
||||
{
|
||||
if (ShouldExecuteRemotely ())
|
||||
BuildConnection.CancelAsync (BuildEngine4).Wait ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,26 +5,35 @@ using Microsoft.Build.Utilities;
|
|||
|
||||
using Xamarin.MacDev.Tasks;
|
||||
using Xamarin.MacDev;
|
||||
using Xamarin.Messaging.Build.Client;
|
||||
using Xamarin.Utils;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Xamarin.iOS.Tasks {
|
||||
public abstract class FindWatchOS2AppBundleTaskBase : XamarinTask {
|
||||
public class FindWatchOS2AppBundle : XamarinTask, ICancelableTask {
|
||||
#region Inputs
|
||||
|
||||
[Required]
|
||||
public ITaskItem [] WatchAppReferences { get; set; }
|
||||
public ITaskItem [] WatchAppReferences { get; set; } = Array.Empty<ITaskItem> ();
|
||||
|
||||
#endregion Inputs
|
||||
|
||||
#region Outputs
|
||||
|
||||
[Output]
|
||||
public string WatchOS2AppBundle { get; set; }
|
||||
public string WatchOS2AppBundle { get; set; } = string.Empty;
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
if (ShouldExecuteRemotely ()) {
|
||||
var taskRunner = new TaskRunner (SessionId, BuildEngine4);
|
||||
taskRunner.FixReferencedItems (WatchAppReferences);
|
||||
return taskRunner.RunAsync (this).Result;
|
||||
}
|
||||
|
||||
var pwd = PathUtils.ResolveSymbolicLinks (Environment.CurrentDirectory);
|
||||
|
||||
if (WatchAppReferences.Length > 0) {
|
||||
|
@ -35,5 +44,11 @@ namespace Xamarin.iOS.Tasks {
|
|||
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
|
||||
public void Cancel ()
|
||||
{
|
||||
if (ShouldExecuteRemotely ())
|
||||
BuildConnection.CancelAsync (BuildEngine4).Wait ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
using Microsoft.Build.Framework;
|
||||
using Xamarin.Messaging.Build.Client;
|
||||
|
||||
namespace Xamarin.iOS.Tasks {
|
||||
public class GetMlaunchArguments : GetMlaunchArgumentsTaskBase, ICancelableTask {
|
||||
public override bool Execute ()
|
||||
{
|
||||
if (ShouldExecuteRemotely ())
|
||||
return new TaskRunner (SessionId, BuildEngine4).RunAsync (this).Result;
|
||||
|
||||
return base.Execute ();
|
||||
}
|
||||
|
||||
public void Cancel ()
|
||||
{
|
||||
if (ShouldExecuteRemotely ())
|
||||
BuildConnection.CancelAsync (BuildEngine4).Wait ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,41 +11,44 @@ using Microsoft.Build.Framework;
|
|||
using Xamarin.Localization.MSBuild;
|
||||
using Xamarin.MacDev;
|
||||
using Xamarin.MacDev.Tasks;
|
||||
using Xamarin.Messaging.Build.Client;
|
||||
using Xamarin.Utils;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Xamarin.iOS.Tasks {
|
||||
public abstract class GetMlaunchArgumentsTaskBase : XamarinTask {
|
||||
public class GetMlaunchArguments : XamarinTask, ICancelableTask {
|
||||
|
||||
[Required]
|
||||
public bool SdkIsSimulator { get; set; }
|
||||
|
||||
[Required]
|
||||
public string SdkVersion { get; set; }
|
||||
public string SdkVersion { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
public string AppBundlePath { get; set; }
|
||||
public string AppBundlePath { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
public string AppManifestPath { get; set; }
|
||||
public string AppManifestPath { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
public string SdkDevPath { get; set; }
|
||||
public string SdkDevPath { get; set; } = string.Empty;
|
||||
|
||||
public ITaskItem [] AdditionalArguments { get; set; } = Array.Empty<ITaskItem> ();
|
||||
public string DeviceName { get; set; }
|
||||
public string DeviceName { get; set; } = string.Empty;
|
||||
public ITaskItem [] EnvironmentVariables { get; set; } = Array.Empty<ITaskItem> ();
|
||||
public string LaunchApp { get; set; }
|
||||
public string InstallApp { get; set; }
|
||||
public string LaunchApp { get; set; } = string.Empty;
|
||||
public string InstallApp { get; set; } = string.Empty;
|
||||
public bool CaptureOutput { get; set; } // Set to true to capture output. If StandardOutput|ErrorPath is not set, write to the current terminal's stdout/stderr (requires WaitForExit)
|
||||
public string StandardOutputPath { get; set; } // Set to a path to capture output there
|
||||
public string StandardErrorPath { get; set; } // Set to a path to capture output there
|
||||
public string StandardOutputPath { get; set; } = string.Empty; // Set to a path to capture output there
|
||||
public string StandardErrorPath { get; set; } = string.Empty;// Set to a path to capture output there
|
||||
public bool WaitForExit { get; set; } // Required for capturing stdout/stderr output
|
||||
|
||||
[Required]
|
||||
public string MlaunchPath { get; set; }
|
||||
public string MlaunchPath { get; set; } = string.Empty;
|
||||
|
||||
[Output]
|
||||
public string MlaunchArguments { get; set; }
|
||||
public string MlaunchArguments { get; set; } = string.Empty;
|
||||
|
||||
public IPhoneDeviceType DeviceType {
|
||||
get {
|
||||
|
@ -61,7 +64,7 @@ namespace Xamarin.iOS.Tasks {
|
|||
}
|
||||
}
|
||||
|
||||
List<string> GetDeviceTypes ()
|
||||
List<string>? GetDeviceTypes ()
|
||||
{
|
||||
var tmpfile = Path.GetTempFileName ();
|
||||
try {
|
||||
|
@ -199,17 +202,26 @@ namespace Xamarin.iOS.Tasks {
|
|||
static string GetTerminalName (int fd)
|
||||
{
|
||||
if (isatty (fd) != 1)
|
||||
return null;
|
||||
return string.Empty;
|
||||
|
||||
return Marshal.PtrToStringAuto (ttyname (fd));
|
||||
}
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
if (ShouldExecuteRemotely ())
|
||||
return new TaskRunner (SessionId, BuildEngine4).RunAsync (this).Result;
|
||||
|
||||
MlaunchArguments = GenerateCommandLineCommands ();
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
|
||||
public void Cancel ()
|
||||
{
|
||||
if (ShouldExecuteRemotely ())
|
||||
BuildConnection.CancelAsync (BuildEngine4).Wait ();
|
||||
}
|
||||
|
||||
[DllImport ("/usr/lib/libc.dylib")]
|
||||
extern static IntPtr ttyname (int filedes);
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
// permanent connection variables
|
||||
static long monodevelop_port = -1;
|
||||
static int sdb_fd = -1;
|
||||
static long sdb_timeout_time = -1;
|
||||
static int heapshot_fd = -1; // this is the socket to write 'heapshot' to to requests heapshots from the profiler
|
||||
static long heapshot_port = -1;
|
||||
static char *profiler_description = NULL;
|
||||
|
@ -593,6 +594,15 @@ void monotouch_configure_debugging ()
|
|||
unsetenv ("__XAMARIN_DEBUG_HOSTS__");
|
||||
}
|
||||
|
||||
evar = getenv ("__XAMARIN_DEBUG_CONNECT_TIMEOUT__");
|
||||
if (evar && *evar) {
|
||||
if (sdb_timeout_time == -1) {
|
||||
sdb_timeout_time = strtol (evar, NULL, 10);
|
||||
LOG (PRODUCT ": Found connect timeout %i in environment variables\n", sdb_timeout_time);
|
||||
}
|
||||
unsetenv ("__XAMARIN_DEBUG_CONNECT_TIMEOUT__");
|
||||
}
|
||||
|
||||
#if MONOTOUCH && (defined(__i386__) || defined (__x86_64__))
|
||||
// Try to read shared memory as well
|
||||
key_t shmkey;
|
||||
|
@ -681,6 +691,8 @@ void monotouch_configure_debugging ()
|
|||
#endif
|
||||
} else if (!strncmp ("Port: ", line, 6) && monodevelop_port == -1) {
|
||||
monodevelop_port = strtol (line + 6, NULL, 10);
|
||||
} else if (!strncmp ("Connect Timeout: ", line, 17) && sdb_timeout_time == -1) {
|
||||
sdb_timeout_time = strtol (line + 17, NULL, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -703,7 +715,7 @@ void monotouch_configure_debugging ()
|
|||
if (monodevelop_port <= 0) {
|
||||
LOG (PRODUCT ": Invalid IDE Port: %i\n", monodevelop_port);
|
||||
} else {
|
||||
LOG (PRODUCT ": IDE Port: %i Transport: %s\n", monodevelop_port, debugging_mode == DebuggingModeHttp ? "HTTP" : (debugging_mode == DebuggingModeUsb ? "USB" : "WiFi"));
|
||||
LOG (PRODUCT ": IDE Port: %i Transport: %s Connect Timeout: %i\n", monodevelop_port, debugging_mode == DebuggingModeHttp ? "HTTP" : (debugging_mode == DebuggingModeUsb ? "USB" : "WiFi"), sdb_timeout_time);
|
||||
if (debugging_mode == DebuggingModeUsb) {
|
||||
monotouch_connect_usb ();
|
||||
} else if (debugging_mode == DebuggingModeWifi) {
|
||||
|
@ -1251,8 +1263,15 @@ monotouch_load_debugger ()
|
|||
transport.recv = sdb_recv;
|
||||
|
||||
mono_debugger_agent_register_transport (&transport);
|
||||
|
||||
mono_debugger_agent_parse_options ("transport=custom_transport,address=dummy,embedding=1");
|
||||
|
||||
char *options;
|
||||
if (sdb_timeout_time != -1) {
|
||||
options = xamarin_strdup_printf ("transport=custom_transport,address=dummy,embedding=1,timeout=%d", sdb_timeout_time);
|
||||
} else {
|
||||
options = xamarin_strdup_printf ("transport=custom_transport,address=dummy,embedding=1");
|
||||
}
|
||||
mono_debugger_agent_parse_options (options);
|
||||
// Can't free the 'options' variable, because mono_debugger_agent_parse_option stores the pointer instead of creating a copy :/
|
||||
|
||||
LOG (PRODUCT ": Debugger loaded with custom transport (fd: %i)\n", sdb_fd);
|
||||
#else
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
// Copyright 2009, Novell, Inc.
|
||||
// Copyright 2010, Novell, Inc.
|
||||
// Copyright 2011, 2014 Xamarin Inc
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
using Foundation;
|
||||
using ObjCRuntime;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace AVFoundation {
|
||||
|
||||
#if !MONOMAC
|
||||
// Convience enum for native string values - AVAudioSession.h
|
||||
public enum AVAudioSessionCategory {
|
||||
Ambient,
|
||||
SoloAmbient,
|
||||
Playback,
|
||||
Record,
|
||||
PlayAndRecord,
|
||||
AudioProcessing,
|
||||
MultiRoute
|
||||
}
|
||||
|
||||
public partial class AVAudioSession : NSObject {
|
||||
public NSError? SetActive (bool beActive)
|
||||
{
|
||||
NSError outError;
|
||||
if (SetActive (beActive, out outError))
|
||||
return null;
|
||||
return outError;
|
||||
}
|
||||
|
||||
#if !TVOS && !WATCH
|
||||
public NSError? SetActive (bool active, AVAudioSessionSetActiveOptions options)
|
||||
{
|
||||
NSError outError;
|
||||
if (SetActive (active, options, out outError))
|
||||
return null;
|
||||
return outError;
|
||||
}
|
||||
#endif
|
||||
|
||||
public NSError? SetCategory (NSString theCategory)
|
||||
{
|
||||
NSError outError;
|
||||
|
||||
if (SetCategory (theCategory, out outError))
|
||||
return null;
|
||||
return outError;
|
||||
}
|
||||
|
||||
internal NSString? CategoryToToken (AVAudioSessionCategory category)
|
||||
{
|
||||
switch (category) {
|
||||
case AVAudioSessionCategory.Ambient:
|
||||
return AVAudioSession.CategoryAmbient;
|
||||
case AVAudioSessionCategory.SoloAmbient:
|
||||
return AVAudioSession.CategorySoloAmbient;
|
||||
case AVAudioSessionCategory.Playback:
|
||||
return AVAudioSession.CategoryPlayback;
|
||||
case AVAudioSessionCategory.Record:
|
||||
return AVAudioSession.CategoryRecord;
|
||||
case AVAudioSessionCategory.PlayAndRecord:
|
||||
return AVAudioSession.CategoryPlayAndRecord;
|
||||
#if !TVOS && !WATCH
|
||||
case AVAudioSessionCategory.AudioProcessing:
|
||||
return AVAudioSession.CategoryAudioProcessing;
|
||||
#endif
|
||||
case AVAudioSessionCategory.MultiRoute:
|
||||
return AVAudioSession.CategoryMultiRoute;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public NSError? SetCategory (AVAudioSessionCategory category)
|
||||
{
|
||||
return SetCategory (CategoryToToken (category)!);
|
||||
}
|
||||
|
||||
public NSError? SetCategory (AVAudioSessionCategory category, AVAudioSessionCategoryOptions options)
|
||||
{
|
||||
NSError error;
|
||||
if (SetCategory (CategoryToToken (category)!, options, out error))
|
||||
return null;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
using AudioToolbox;
|
||||
|
||||
namespace AVFoundation {
|
||||
#if XAMCORE_5_0
|
||||
public delegate int AVAudioSinkNodeReceiverHandler (AudioTimeStamp timestamp, uint frameCount, AudioBuffers inputData);
|
||||
#else
|
||||
public delegate int AVAudioSinkNodeReceiverHandler (AudioTimeStamp timestamp, uint frameCount, ref AudioBuffers inputData);
|
||||
public delegate int AVAudioSinkNodeReceiverHandler2 (AudioTimeStamp timestamp, uint frameCount, AudioBuffers inputData);
|
||||
#endif // XAMCORE_5_0
|
||||
|
||||
public partial class AVAudioSinkNode {
|
||||
#if !XAMCORE_5_0
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("Use the overload that takes a delegate that does not take a 'ref AudioBuffers' instead. Assigning a value to the 'inputData' parameter in the callback has no effect.")]
|
||||
#endif // !XAMCORE_5_0
|
||||
public AVAudioSinkNode (AVAudioSinkNodeReceiverHandler receiverHandler)
|
||||
: this (GetHandler (receiverHandler))
|
||||
{
|
||||
}
|
||||
|
||||
#if !XAMCORE_5_0
|
||||
public AVAudioSinkNode (AVAudioSinkNodeReceiverHandler2 receiverHandler)
|
||||
: this (GetHandler (receiverHandler))
|
||||
{
|
||||
}
|
||||
#endif // !XAMCORE_5_0
|
||||
|
||||
static AVAudioSinkNodeReceiverHandlerRaw GetHandler (AVAudioSinkNodeReceiverHandler receiverHandler)
|
||||
{
|
||||
AVAudioSinkNodeReceiverHandlerRaw rv = (timestamp, frameCount, inputData) => {
|
||||
unsafe {
|
||||
var ts = *(AudioTimeStamp*) timestamp;
|
||||
var abuffers = new AudioBuffers (inputData);
|
||||
#if XAMCORE_5_0
|
||||
return receiverHandler (ts, frameCount, abuffers);
|
||||
#else
|
||||
return receiverHandler (ts, frameCount, ref abuffers);
|
||||
#endif // XAMCORE_5_0
|
||||
}
|
||||
};
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if !XAMCORE_5_0
|
||||
static AVAudioSinkNodeReceiverHandlerRaw GetHandler (AVAudioSinkNodeReceiverHandler2 receiverHandler)
|
||||
{
|
||||
AVAudioSinkNodeReceiverHandlerRaw rv = (timestamp, frameCount, inputData) => {
|
||||
unsafe {
|
||||
var ts = *(AudioTimeStamp*) timestamp;
|
||||
var abuffers = new AudioBuffers (inputData);
|
||||
return receiverHandler (ts, frameCount, abuffers);
|
||||
}
|
||||
};
|
||||
return rv;
|
||||
}
|
||||
#endif // !XAMCORE_5_0
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ using Foundation;
|
|||
|
||||
namespace CoreMidi {
|
||||
|
||||
#if !XAMCORE_5_0
|
||||
#if NET
|
||||
[SupportedOSPlatform ("macos")]
|
||||
[SupportedOSPlatform ("ios12.0")]
|
||||
|
@ -33,4 +34,127 @@ namespace CoreMidi {
|
|||
[MarshalAs (UnmanagedType.ByValArray, SizeConst = 5)]
|
||||
public byte [] Reserved;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NET
|
||||
[SupportedOSPlatform ("macos")]
|
||||
[SupportedOSPlatform ("ios12.0")]
|
||||
[SupportedOSPlatform ("maccatalyst")]
|
||||
[UnsupportedOSPlatform ("tvos")]
|
||||
#else
|
||||
[NoWatch]
|
||||
[NoTV]
|
||||
[Mac (10, 14)]
|
||||
[iOS (12, 0)]
|
||||
#endif
|
||||
[NativeName ("MIDICIDeviceIdentification")]
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
#if XAMCORE_5_0
|
||||
public struct MidiCIDeviceIdentification {
|
||||
#elif COREBUILD
|
||||
public struct MidiCIDeviceIdentification_Blittable {
|
||||
#else
|
||||
internal struct MidiCIDeviceIdentification_Blittable {
|
||||
#endif
|
||||
byte manufacturer1;
|
||||
byte manufacturer2;
|
||||
byte manufacturer3;
|
||||
|
||||
byte family1;
|
||||
byte family2;
|
||||
|
||||
byte modelnumber1;
|
||||
byte modelnumber2;
|
||||
|
||||
byte revisionLevel1;
|
||||
byte revisionLevel2;
|
||||
byte revisionLevel3;
|
||||
byte revisionLevel4;
|
||||
|
||||
byte reserved1;
|
||||
byte reserved2;
|
||||
byte reserved3;
|
||||
byte reserved4;
|
||||
byte reserved5;
|
||||
|
||||
public byte [] Manufacturer {
|
||||
get { return new byte [] { manufacturer1, manufacturer2, manufacturer3 }; }
|
||||
set {
|
||||
if (value is null)
|
||||
throw new ArgumentNullException (nameof (value));
|
||||
if (value.Length != 3)
|
||||
throw new ArgumentOutOfRangeException (nameof (value), "Array length must be exactly 3");
|
||||
manufacturer1 = value [0];
|
||||
manufacturer2 = value [1];
|
||||
manufacturer3 = value [2];
|
||||
}
|
||||
}
|
||||
|
||||
public byte [] Family {
|
||||
get { return new byte [] { family1, family2 }; }
|
||||
set {
|
||||
if (value is null)
|
||||
throw new ArgumentNullException (nameof (value));
|
||||
if (value.Length != 2)
|
||||
throw new ArgumentOutOfRangeException (nameof (value), "Array length must be exactly 2");
|
||||
family1 = value [0];
|
||||
family2 = value [1];
|
||||
}
|
||||
}
|
||||
|
||||
public byte [] ModelNumber {
|
||||
get { return new byte [] { modelnumber1, modelnumber2 }; }
|
||||
set {
|
||||
if (value is null)
|
||||
throw new ArgumentNullException (nameof (value));
|
||||
if (value.Length != 2)
|
||||
throw new ArgumentOutOfRangeException (nameof (value), "Array length must be exactly 2");
|
||||
modelnumber1 = value [0];
|
||||
modelnumber2 = value [1];
|
||||
}
|
||||
}
|
||||
|
||||
public byte [] RevisionLevel {
|
||||
get { return new byte [] { revisionLevel1, revisionLevel2, revisionLevel3, revisionLevel4 }; }
|
||||
set {
|
||||
if (value is null)
|
||||
throw new ArgumentNullException (nameof (value));
|
||||
if (value.Length != 4)
|
||||
throw new ArgumentOutOfRangeException (nameof (value), "Array length must be exactly 4");
|
||||
revisionLevel1 = value [0];
|
||||
revisionLevel2 = value [1];
|
||||
revisionLevel3 = value [2];
|
||||
revisionLevel4 = value [3];
|
||||
}
|
||||
}
|
||||
|
||||
public byte [] Reserved {
|
||||
get { return new byte [] { reserved1, reserved2, reserved3, reserved4, reserved5 }; }
|
||||
set {
|
||||
if (value is null)
|
||||
throw new ArgumentNullException (nameof (value));
|
||||
if (value.Length != 5)
|
||||
throw new ArgumentOutOfRangeException (nameof (value), "Array length must be exactly 5");
|
||||
reserved1 = value [0];
|
||||
reserved2 = value [1];
|
||||
reserved3 = value [2];
|
||||
reserved4 = value [3];
|
||||
reserved5 = value [4];
|
||||
}
|
||||
}
|
||||
|
||||
#if !XAMCORE_5_0
|
||||
|
||||
internal MidiCIDeviceIdentification ToMidiCIDeviceIdentification ()
|
||||
{
|
||||
var rv = new MidiCIDeviceIdentification ();
|
||||
rv.Manufacturer = Manufacturer;
|
||||
rv.Family = Family;
|
||||
rv.ModelNumber = ModelNumber;
|
||||
rv.RevisionLevel = RevisionLevel;
|
||||
rv.Reserved = Reserved;
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1986,6 +1986,12 @@ namespace AVFoundation {
|
|||
[Export ("setActive:error:")]
|
||||
bool SetActive (bool beActive, out NSError outError);
|
||||
|
||||
[return: NullAllowed]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetActive (beActive, out var outError) ? null : outError")]
|
||||
NSError SetActive (bool beActive);
|
||||
|
||||
#if !NET
|
||||
[NoTV, NoMac]
|
||||
[Export ("setActive:withFlags:error:")]
|
||||
|
@ -1998,6 +2004,18 @@ namespace AVFoundation {
|
|||
[Export ("setCategory:error:")]
|
||||
bool SetCategory (NSString theCategory, out NSError outError);
|
||||
|
||||
[return: NullAllowed]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetCategory (theCategory, out var outError) ? null : outError")]
|
||||
NSError SetCategory (NSString theCategory);
|
||||
|
||||
[return: NullAllowed]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetCategory (category.GetConstant ()!, out var outError) ? null : outError")]
|
||||
NSError SetCategory (AVAudioSessionCategory category);
|
||||
|
||||
[NoTV, NoMac]
|
||||
[Deprecated (PlatformName.iOS, 6, 0, message: "Use 'SetPreferredSampleRate' instead.")]
|
||||
[MacCatalyst (13, 1)]
|
||||
|
@ -2025,6 +2043,11 @@ namespace AVFoundation {
|
|||
[Export ("setMode:error:")]
|
||||
bool SetMode (NSString mode, out NSError error);
|
||||
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetMode (mode.GetConstant ()!, out error)")]
|
||||
bool SetMode (AVAudioSessionMode mode, out NSError error);
|
||||
|
||||
[NoTV, NoMac]
|
||||
[Export ("preferredHardwareSampleRate")]
|
||||
[Deprecated (PlatformName.iOS, 6, 0, message: "Use 'PreferredSampleRate' instead.")]
|
||||
|
@ -2065,31 +2088,38 @@ namespace AVFoundation {
|
|||
[Deprecated (PlatformName.MacCatalyst, 13, 1, message: "Use 'OutputNumberOfChannels' instead.")]
|
||||
nint CurrentHardwareOutputNumberOfChannels { get; }
|
||||
|
||||
#if !XAMCORE_5_0
|
||||
[Obsolete ("Use 'AVAudioSessionCategory' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionCategoryAmbient")]
|
||||
NSString CategoryAmbient { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionCategory' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionCategorySoloAmbient")]
|
||||
NSString CategorySoloAmbient { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionCategory' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionCategoryPlayback")]
|
||||
NSString CategoryPlayback { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionCategory' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionCategoryRecord")]
|
||||
NSString CategoryRecord { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionCategory' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionCategoryPlayAndRecord")]
|
||||
NSString CategoryPlayAndRecord { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionCategory' enum values instead.")]
|
||||
[NoTV]
|
||||
[NoWatch]
|
||||
[NoMac]
|
||||
|
@ -2098,32 +2128,39 @@ namespace AVFoundation {
|
|||
[Deprecated (PlatformName.MacCatalyst, 13, 1)]
|
||||
[Field ("AVAudioSessionCategoryAudioProcessing")]
|
||||
NSString CategoryAudioProcessing { get; }
|
||||
#endif // !XAMCORE_5_0
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionMode' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeDefault")]
|
||||
NSString ModeDefault { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionMode' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeVoiceChat")]
|
||||
NSString ModeVoiceChat { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionMode' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeVideoRecording")]
|
||||
NSString ModeVideoRecording { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionMode' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeMeasurement")]
|
||||
NSString ModeMeasurement { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionMode' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeGameChat")]
|
||||
NSString ModeGameChat { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionMode' enum values instead.")]
|
||||
[Watch (5, 0), TV (12, 0), NoMac, iOS (12, 0)]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeVoicePrompt")]
|
||||
|
@ -2134,6 +2171,12 @@ namespace AVFoundation {
|
|||
[Export ("setActive:withOptions:error:")]
|
||||
bool SetActive (bool active, AVAudioSessionSetActiveOptions options, out NSError outError);
|
||||
|
||||
[return: NullAllowed]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetActive (active, options, out var outError) ? null : outError")]
|
||||
NSError SetActive (bool active, AVAudioSessionSetActiveOptions options);
|
||||
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Export ("availableCategories")]
|
||||
|
@ -2144,11 +2187,48 @@ namespace AVFoundation {
|
|||
[Export ("setCategory:withOptions:error:")]
|
||||
bool SetCategory (string category, AVAudioSessionCategoryOptions options, out NSError outError);
|
||||
|
||||
[return: NullAllowed]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetCategory (category.GetConstant ()!, options, out var outError) ? null : outError")]
|
||||
NSError SetCategory (AVAudioSessionCategory category, AVAudioSessionCategoryOptions options);
|
||||
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetCategory (category.GetConstant ()!, options, out outError)")]
|
||||
bool SetCategory (AVAudioSessionCategory category, AVAudioSessionCategoryOptions options, out NSError outError);
|
||||
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Export ("setCategory:mode:options:error:")]
|
||||
bool SetCategory (string category, string mode, AVAudioSessionCategoryOptions options, out NSError outError);
|
||||
|
||||
[NoMac]
|
||||
[iOS (10, 0), TV (10, 0)]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetCategory (category.GetConstant ()!, mode, options, out outError)")]
|
||||
bool SetCategory (AVAudioSessionCategory category, string mode, AVAudioSessionCategoryOptions options, out NSError outError);
|
||||
|
||||
[return: NullAllowed]
|
||||
[NoMac]
|
||||
[iOS (10, 0), TV (10, 0)]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetCategory (category.GetConstant ()!, mode, options, out var outError) ? null : outError")]
|
||||
NSError SetCategory (AVAudioSessionCategory category, string mode, AVAudioSessionCategoryOptions options);
|
||||
|
||||
[NoMac]
|
||||
[iOS (10, 0), TV (10, 0)]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetCategory (category.GetConstant ()!, mode.GetConstant ()!, options, out outError)")]
|
||||
bool SetCategory (AVAudioSessionCategory category, AVAudioSessionMode mode, AVAudioSessionCategoryOptions options, out NSError outError);
|
||||
|
||||
[return: NullAllowed]
|
||||
[NoMac]
|
||||
[iOS (10, 0), TV (10, 0)]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetCategory (category.GetConstant ()!, mode.GetConstant ()!, options, out var outError) ? null : outError")]
|
||||
NSError SetCategory (AVAudioSessionCategory category, AVAudioSessionMode mode, AVAudioSessionCategoryOptions options);
|
||||
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Export ("categoryOptions")]
|
||||
|
@ -2256,21 +2336,27 @@ namespace AVFoundation {
|
|||
[Notification, Field ("AVAudioSessionMediaServicesWereLostNotification")]
|
||||
NSString MediaServicesWereLostNotification { get; }
|
||||
|
||||
#if !XAMCORE_5_0
|
||||
[Obsolete ("Use 'AVAudioSessionCategory' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionCategoryMultiRoute")]
|
||||
NSString CategoryMultiRoute { get; }
|
||||
#endif // !XAMCORE_5_0
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionMode' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeMoviePlayback")]
|
||||
NSString ModeMoviePlayback { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionMode' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeVideoChat")]
|
||||
NSString ModeVideoChat { get; }
|
||||
|
||||
[Obsolete ("Use 'AVAudioSessionMode' enum values instead.")]
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeSpokenAudio")]
|
||||
|
@ -2528,6 +2614,16 @@ namespace AVFoundation {
|
|||
|
||||
[Watch (5, 0), NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetCategory (category.GetConstant ()!, mode, policy, options, out outError)")]
|
||||
bool SetCategory (AVAudioSessionCategory category, string mode, AVAudioSessionRouteSharingPolicy policy, AVAudioSessionCategoryOptions options, [NullAllowed] out NSError outError);
|
||||
|
||||
[TV (11, 0), Watch (5, 0), iOS (11, 0), NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Wrap ("SetCategory (category.GetConstant ()!, mode.GetConstant ()!, policy, options, out outError)")]
|
||||
bool SetCategory (AVAudioSessionCategory category, AVAudioSessionMode mode, AVAudioSessionRouteSharingPolicy policy, AVAudioSessionCategoryOptions options, [NullAllowed] out NSError outError);
|
||||
|
||||
[TV (11, 0), Watch (5, 0), iOS (11, 0), NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Export ("routeSharingPolicy")]
|
||||
AVAudioSessionRouteSharingPolicy RouteSharingPolicy { get; }
|
||||
|
||||
|
@ -2590,6 +2686,76 @@ namespace AVFoundation {
|
|||
NSString SpatialPlaybackCapabilitiesChangedNotification { get; }
|
||||
}
|
||||
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
enum AVAudioSessionCategory {
|
||||
[Field ("AVAudioSessionCategoryAmbient")]
|
||||
Ambient,
|
||||
|
||||
[Field ("AVAudioSessionCategorySoloAmbient")]
|
||||
SoloAmbient,
|
||||
|
||||
[Field ("AVAudioSessionCategoryPlayback")]
|
||||
Playback,
|
||||
|
||||
[Field ("AVAudioSessionCategoryRecord")]
|
||||
Record,
|
||||
|
||||
[Field ("AVAudioSessionCategoryPlayAndRecord")]
|
||||
PlayAndRecord,
|
||||
|
||||
[NoTV]
|
||||
[NoWatch]
|
||||
[Deprecated (PlatformName.iOS, 10, 0)]
|
||||
[Deprecated (PlatformName.MacCatalyst, 13, 1)]
|
||||
[Field ("AVAudioSessionCategoryAudioProcessing")]
|
||||
AudioProcessing,
|
||||
|
||||
[Field ("AVAudioSessionCategoryMultiRoute")]
|
||||
MultiRoute,
|
||||
}
|
||||
|
||||
[NoMac] // Apple's documentation says the enum is available on macOS, but none of the individual values are, so just don't expose the enum on macOS.
|
||||
enum AVAudioSessionMode {
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeDefault")]
|
||||
Default,
|
||||
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeVoiceChat")]
|
||||
VoiceChat,
|
||||
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeVideoRecording")]
|
||||
VideoRecording,
|
||||
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeMeasurement")]
|
||||
Measurement,
|
||||
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeGameChat")]
|
||||
GameChat,
|
||||
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeMoviePlayback")]
|
||||
MoviePlayback,
|
||||
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeVideoChat")]
|
||||
VideoChat,
|
||||
|
||||
[iOS (9, 0)]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeSpokenAudio")]
|
||||
SpokenAudio,
|
||||
|
||||
[Watch (5, 0), TV (12, 0), iOS (12, 0)]
|
||||
[MacCatalyst (13, 1)]
|
||||
[Field ("AVAudioSessionModeVoicePrompt")]
|
||||
VoicePrompt,
|
||||
}
|
||||
|
||||
[NoMac]
|
||||
[MacCatalyst (13, 1)]
|
||||
[BaseType (typeof (NSObject))]
|
||||
|
@ -15634,7 +15800,7 @@ namespace AVFoundation {
|
|||
#endif
|
||||
}
|
||||
|
||||
delegate int AVAudioSinkNodeReceiverHandler (AudioTimeStamp timestamp, uint frameCount, ref AudioBuffers inputData);
|
||||
delegate int AVAudioSinkNodeReceiverHandlerRaw (IntPtr timestamp, uint frameCount, IntPtr inputData);
|
||||
|
||||
[Watch (6, 0), TV (13, 0), iOS (13, 0)]
|
||||
[MacCatalyst (13, 1)]
|
||||
|
@ -15643,7 +15809,7 @@ namespace AVFoundation {
|
|||
interface AVAudioSinkNode {
|
||||
[Export ("initWithReceiverBlock:")]
|
||||
[DesignatedInitializer]
|
||||
NativeHandle Constructor (AVAudioSinkNodeReceiverHandler receiverHandler);
|
||||
NativeHandle Constructor (AVAudioSinkNodeReceiverHandlerRaw receiverHandler);
|
||||
}
|
||||
|
||||
[TV (13, 0), NoWatch, iOS (13, 0)]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using ObjCRuntime;
|
||||
|
||||
#nullable enable
|
||||
|
@ -66,7 +67,7 @@ public static partial class AttributeFactory {
|
|||
return new [] { PlatformEnum, typeof (int), typeof (int), typeof (int), typeof (string) };
|
||||
}
|
||||
|
||||
public static bool TryGetCtorArguments (object [] constructorArguments, PlatformName platform, out object? []? ctorValues, out Type []? ctorTypes)
|
||||
public static bool TryGetCtorArguments (object [] constructorArguments, PlatformName platform, [NotNullWhen (true)] out object? []? ctorValues, [NotNullWhen (true)] out Type []? ctorTypes)
|
||||
{
|
||||
ctorValues = null;
|
||||
ctorTypes = null;
|
||||
|
|
|
@ -2440,6 +2440,8 @@ public partial class Generator : IMemberGatherer {
|
|||
bool IsInSupportedFramework (MemberInfo klass, PlatformName platform)
|
||||
{
|
||||
string ns = FindNamespace (klass);
|
||||
if (string.IsNullOrEmpty (ns))
|
||||
return false;
|
||||
var list = GetFrameworkListForPlatform (platform);
|
||||
return list.Contains (ns.ToLower (CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
|
|
@ -363,8 +363,17 @@ namespace CoreMidi {
|
|||
[Export ("supportsPropertyCapability")]
|
||||
bool SupportsPropertyCapability { get; }
|
||||
|
||||
#if XAMCORE_5_0
|
||||
[Export ("deviceIdentification")]
|
||||
MidiCIDeviceIdentification DeviceIdentification { get; }
|
||||
#else
|
||||
[Internal]
|
||||
[Export ("deviceIdentification")]
|
||||
MidiCIDeviceIdentification_Blittable _DeviceIdentification { get; }
|
||||
|
||||
[Wrap ("_DeviceIdentification.ToMidiCIDeviceIdentification ()", IsVirtual = true)]
|
||||
MidiCIDeviceIdentification DeviceIdentification { get; }
|
||||
#endif
|
||||
|
||||
[Export ("profileStateForChannel:")]
|
||||
MidiCIProfileState GetProfileState (byte channel);
|
||||
|
|
|
@ -262,9 +262,9 @@ AVFOUNDATION_SOURCES = \
|
|||
AVFoundation/AVAudioFormat.cs \
|
||||
AVFoundation/AVAudioPlayer.cs \
|
||||
AVFoundation/AVAudioRecorder.cs \
|
||||
AVFoundation/AVAudioSession.cs \
|
||||
AVFoundation/AVAudioSessionDataSourceDescription.cs \
|
||||
AVFoundation/AVAudioSessionPortDescription.cs \
|
||||
AVFoundation/AVAudioSinkNode.cs \
|
||||
AVFoundation/AVCaptureConnection.cs \
|
||||
AVFoundation/AVCaptureDeviceDiscoverySession.cs \
|
||||
AVFoundation/AVCaptureDeviceInput.cs \
|
||||
|
|
|
@ -59,8 +59,6 @@ namespace Cecil.Tests {
|
|||
"CoreMedia.CMSampleBufferError CoreMedia.CMSampleBuffer::CMSampleBufferCreateForImageBuffer(System.IntPtr,System.IntPtr,System.Boolean,System.IntPtr,System.IntPtr,System.IntPtr,CoreMedia.CMSampleTimingInfo&,System.IntPtr&)",
|
||||
"CoreMedia.CMTime ObjCRuntime.Messaging::CMTime_objc_msgSend_CMTime_out_Boolean(System.IntPtr,System.IntPtr,CoreMedia.CMTime,System.Boolean&)",
|
||||
"CoreMedia.CMTime ObjCRuntime.Messaging::CMTime_objc_msgSendSuper_CMTime_out_Boolean(System.IntPtr,System.IntPtr,CoreMedia.CMTime,System.Boolean&)",
|
||||
"CoreMidi.MidiCIDeviceIdentification ObjCRuntime.Messaging::MidiCIDeviceIdentification_objc_msgSend(System.IntPtr,System.IntPtr)",
|
||||
"CoreMidi.MidiCIDeviceIdentification ObjCRuntime.Messaging::MidiCIDeviceIdentification_objc_msgSendSuper(System.IntPtr,System.IntPtr)",
|
||||
"Foundation.NSRange ObjCRuntime.Messaging::NSRange_objc_msgSend_NativeHandle_IntPtr_NativeHandle_bool_IntPtr_NativeHandle(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle,System.IntPtr,ObjCRuntime.NativeHandle,System.Boolean,System.IntPtr,ObjCRuntime.NativeHandle)",
|
||||
"Foundation.NSRange ObjCRuntime.Messaging::NSRange_objc_msgSend_NativeHandle_IntPtr_NativeHandle_bool_IntPtr_out_IntPtr(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle,System.IntPtr,ObjCRuntime.NativeHandle,System.Boolean,System.IntPtr,System.IntPtr&)",
|
||||
"Foundation.NSRange ObjCRuntime.Messaging::NSRange_objc_msgSend_NativeHandle_NSRange_IntPtr_bool_NativeHandle(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle,Foundation.NSRange,System.IntPtr,System.Boolean,ObjCRuntime.NativeHandle)",
|
||||
|
@ -1173,8 +1171,6 @@ namespace Cecil.Tests {
|
|||
"System.Void ObjCRuntime.Messaging::CGRect_objc_msgSendSuper_stret_UIntPtr_out_NSRange_bool(CoreGraphics.CGRect&,System.IntPtr,System.IntPtr,System.UIntPtr,Foundation.NSRange&,System.Boolean)",
|
||||
"System.Void ObjCRuntime.Messaging::CMTime_objc_msgSend_stret_CMTime_out_Boolean(CoreMedia.CMTime&,System.IntPtr,System.IntPtr,CoreMedia.CMTime,System.Boolean&)",
|
||||
"System.Void ObjCRuntime.Messaging::CMTime_objc_msgSendSuper_stret_CMTime_out_Boolean(CoreMedia.CMTime&,System.IntPtr,System.IntPtr,CoreMedia.CMTime,System.Boolean&)",
|
||||
"System.Void ObjCRuntime.Messaging::MidiCIDeviceIdentification_objc_msgSend_stret(CoreMidi.MidiCIDeviceIdentification&,System.IntPtr,System.IntPtr)",
|
||||
"System.Void ObjCRuntime.Messaging::MidiCIDeviceIdentification_objc_msgSendSuper_stret(CoreMidi.MidiCIDeviceIdentification&,System.IntPtr,System.IntPtr)",
|
||||
"System.Void ObjCRuntime.Messaging::NSRange_objc_msgSend_stret_NativeHandle_NSRange_IntPtr_bool_NativeHandle(Foundation.NSRange&,System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle,Foundation.NSRange,System.IntPtr,System.Boolean,ObjCRuntime.NativeHandle)",
|
||||
"System.Void ObjCRuntime.Messaging::NSRange_objc_msgSendSuper_stret_NativeHandle_NSRange_IntPtr_bool_NativeHandle(Foundation.NSRange&,System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle,Foundation.NSRange,System.IntPtr,System.Boolean,ObjCRuntime.NativeHandle)",
|
||||
"System.Void ObjCRuntime.Messaging::void_objc_msgSend_AudioComponentDescription_UInt32_NativeHandle(System.IntPtr,System.IntPtr,AudioUnit.AudioComponentDescription,System.UInt32,ObjCRuntime.NativeHandle)",
|
||||
|
|
|
@ -1446,6 +1446,25 @@ partial class TestRuntime {
|
|||
|
||||
IgnoreInCIfHttpStatusCodes (ex, HttpStatusCode.BadGateway, HttpStatusCode.GatewayTimeout, HttpStatusCode.ServiceUnavailable);
|
||||
IgnoreInCIIfNetworkConnectionLost (ex);
|
||||
IgnoreInCIIfDnsResolutionFailed (ex);
|
||||
}
|
||||
|
||||
public static void IgnoreInCIIfDnsResolutionFailed (Exception ex)
|
||||
{
|
||||
var se = FindInner<System.Net.Sockets.SocketException> (ex);
|
||||
if (se is null)
|
||||
return;
|
||||
|
||||
var isDnsResolutionFailed = false;
|
||||
if (se.ErrorCode == 8 /* EAI_NONAME: 'hostname or servname not provided, or not known' */) {
|
||||
isDnsResolutionFailed = true;
|
||||
} else if (se.Message.Contains ("hostname or servname not provided, or not known")) {
|
||||
isDnsResolutionFailed = true;
|
||||
}
|
||||
if (!isDnsResolutionFailed)
|
||||
return;
|
||||
|
||||
IgnoreInCI ($"Ignored due to DNS resolution failure '{se.Message}'");
|
||||
}
|
||||
|
||||
public static void IgnoreInCIIfForbidden (Exception ex)
|
||||
|
@ -1489,6 +1508,16 @@ partial class TestRuntime {
|
|||
IgnoreInCI ($"Ignored due to CFNetwork error {(CFNetworkErrors) (long) nex.Code}");
|
||||
}
|
||||
|
||||
static T? FindInner<T> (Exception? ex) where T : Exception
|
||||
{
|
||||
while (ex is not null) {
|
||||
if (ex is T target)
|
||||
return target;
|
||||
ex = ex.InnerException;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static bool TryGetHttpStatusCode (Exception ex, out HttpStatusCode status)
|
||||
{
|
||||
status = (HttpStatusCode) 0;
|
||||
|
|
|
@ -419,7 +419,7 @@ namespace Xamarin.Tests {
|
|||
switch (platform) {
|
||||
case ApplePlatform.iOS:
|
||||
var appExecutable = Path.Combine (appPath, Path.GetFileName (project_path));
|
||||
Assert.That (appPath, Does.Exist, "There is an .app");
|
||||
Assert.That (appPath, Does.Not.Exist, "There is an .app");
|
||||
Assert.That (appExecutable, Does.Not.Empty, "There is no executable");
|
||||
Assert.That (Path.Combine (appPath, Configuration.GetBaseLibraryName (platform, true)), Does.Not.Exist, "Platform assembly is in the bundle");
|
||||
break;
|
||||
|
|
|
@ -381,6 +381,21 @@ namespace GeneratorTests {
|
|||
bgen.AssertWarning (1103, "'FooType`1' does not live under a namespace; namespaces are a highly recommended .NET best practice");
|
||||
}
|
||||
|
||||
#if !NET
|
||||
[Ignore ("This only applies to .NET")]
|
||||
#endif
|
||||
[TestCase (Profile.iOS)]
|
||||
public void Bug18035 (Profile profile)
|
||||
{
|
||||
Configuration.IgnoreIfIgnoredPlatform (profile.AsPlatform ());
|
||||
var bgen = new BGenTool ();
|
||||
bgen.Profile = profile;
|
||||
bgen.AddTestApiDefinition ("bug18025.cs");
|
||||
bgen.CreateTemporaryBinding ();
|
||||
bgen.AssertExecute ("build");
|
||||
bgen.AssertWarning (1103, "'FooType' does not live under a namespace; namespaces are a highly recommended .NET best practice");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Bug40282 ()
|
||||
{
|
||||
|
|
|
@ -194,11 +194,11 @@ namespace GeneratorTests {
|
|||
var success = AttributeFactory.ConstructorArguments.TryGetCtorArguments (arguments, platformName,
|
||||
out var actualValues, out var actualTypes);
|
||||
Assert.True (success, "success");
|
||||
Assert.AreEqual (expectedValues.Length, actualValues.Length, "Values Length");
|
||||
Assert.AreEqual (expectedValues!.Length, actualValues!.Length, "Values Length");
|
||||
for (int index = 0; index < expectedValues.Length; index++) {
|
||||
Assert.AreEqual (expectedValues [index], actualValues [index], $"Values [{index}]");
|
||||
}
|
||||
Assert.AreEqual (expectedTypes.Length, actualTypes.Length, "Types Length");
|
||||
Assert.AreEqual (expectedTypes!.Length, actualTypes!.Length, "Types Length");
|
||||
for (int index = 0; index < expectedTypes.Length; index++) {
|
||||
Assert.AreEqual (expectedTypes [index], actualTypes [index], $"Types [{index}]");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
using Foundation;
|
||||
|
||||
[BaseType (typeof (NSObject))]
|
||||
public interface FooType {
|
||||
[Introduced (PlatformName.iOS, 8, 0)]
|
||||
[Export ("getBar:")]
|
||||
string GetBar (string bar);
|
||||
}
|
|
@ -38,12 +38,6 @@
|
|||
<PackageReference Include="MSBuild.StructuredLogger" Version="2.1.787" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\src\bgen\AttributeFactory.ConstructorArguments.cs">
|
||||
<Link>AttributeFactory.ConstructorArguments.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\bgen\AttributeFactory.cs">
|
||||
<Link>AttributeFactory.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\tools\common\SdkVersions.cs">
|
||||
<Link>SdkVersions.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
using AudioToolbox;
|
||||
using AVFoundation;
|
||||
using Foundation;
|
||||
|
||||
namespace MonoTouchFixtures.AVFoundation {
|
||||
[TestFixture]
|
||||
[Preserve (AllMembers = true)]
|
||||
public class AVAudioSinkNodeTest {
|
||||
[Test]
|
||||
public void SinkNodeCallback ()
|
||||
{
|
||||
var callbackEvent = new ManualResetEvent (false);
|
||||
SinkNodeCallbackTest (callbackEvent, () => {
|
||||
#if XAMCORE_5_0
|
||||
var handler = new AVAudioSinkNodeReceiverHandler ((ts, n, buffers) => SinkHandler (ts, n, buffers, callbackEvent));
|
||||
#else
|
||||
var handler = new AVAudioSinkNodeReceiverHandler ((AudioTimeStamp ts, uint n, ref AudioBuffers buffers) => SinkHandler (ts, n, ref buffers, callbackEvent));
|
||||
#endif
|
||||
return new AVAudioSinkNode (handler);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SinkNodeCallbackRaw ()
|
||||
{
|
||||
var callbackEvent = new ManualResetEvent (false);
|
||||
SinkNodeCallbackTest (callbackEvent, () => {
|
||||
var handler = new AVAudioSinkNodeReceiverHandlerRaw ((ts, n, buffers) => SinkHandlerRaw (ts, n, buffers, callbackEvent));
|
||||
return new AVAudioSinkNode (handler);
|
||||
});
|
||||
}
|
||||
|
||||
#if !XAMCORE_5_0
|
||||
[Test]
|
||||
public void SinkNodeCallback2 ()
|
||||
{
|
||||
var callbackEvent = new ManualResetEvent (false);
|
||||
SinkNodeCallbackTest (callbackEvent, () => {
|
||||
var handler = new AVAudioSinkNodeReceiverHandler2 ((ts, n, buffers) => SinkHandler2 (ts, n, buffers, callbackEvent));
|
||||
return new AVAudioSinkNode (handler);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
void SinkNodeCallbackTest (ManualResetEvent callbackEvent, Func<AVAudioSinkNode> createSinkNode)
|
||||
{
|
||||
TestRuntime.AssertNotVirtualMachine ();
|
||||
|
||||
#if __MACOS__
|
||||
var defaultCaptureDevice = AVCaptureDevice.GetDefaultDevice (AVMediaTypes.Audio);
|
||||
if (defaultCaptureDevice is null)
|
||||
Assert.Ignore ("The current system doesn't have a microphone.");
|
||||
#else
|
||||
using var session = AVAudioSession.SharedInstance ();
|
||||
if (!session.InputAvailable)
|
||||
Assert.Ignore ("The current system doesn't have a microphone.");
|
||||
|
||||
session.SetCategory (AVAudioSessionCategory.PlayAndRecord, AVAudioSessionCategoryOptions.DefaultToSpeaker, out var categoryError);
|
||||
Assert.IsNull (categoryError, "Category Error");
|
||||
#if !__WATCHOS__
|
||||
session.SetPreferredSampleRate (48000, out var sampleRateError);
|
||||
Assert.IsNull (sampleRateError, "Sample Rate Error");
|
||||
session.SetPreferredInputNumberOfChannels (1, out var inputChannelCountError);
|
||||
Assert.IsNull (inputChannelCountError, "Input Channel Count Error");
|
||||
#endif // !__WATCHOS__
|
||||
session.SetActive (true);
|
||||
#endif // __MACOS__
|
||||
|
||||
using var engine = new AVAudioEngine ();
|
||||
|
||||
try {
|
||||
var inputNode = engine.InputNode;
|
||||
var inputFormat = inputNode.GetBusOutputFormat (0);
|
||||
if (inputFormat.SampleRate == 0)
|
||||
Assert.Ignore ("The current system can't record audio.");
|
||||
var sinkNode = createSinkNode ();
|
||||
engine.AttachNode (sinkNode);
|
||||
engine.Connect (inputNode, sinkNode, inputFormat);
|
||||
engine.StartAndReturnError (out var error);
|
||||
|
||||
Assert.IsNull (error, "Start error");
|
||||
Assert.True (callbackEvent.WaitOne (TimeSpan.FromSeconds (5)), "Called back");
|
||||
} finally {
|
||||
engine.Stop ();
|
||||
}
|
||||
}
|
||||
|
||||
int SinkHandler (AudioTimeStamp ts, uint n, ref AudioBuffers buffers, ManualResetEvent evt)
|
||||
{
|
||||
return SinkHandler2 (ts, n, buffers, evt);
|
||||
}
|
||||
|
||||
int SinkHandler2 (AudioTimeStamp ts, uint n, AudioBuffers buffers, ManualResetEvent evt)
|
||||
{
|
||||
var data = new float [n];
|
||||
|
||||
int nCh = buffers.Count;
|
||||
for (int i = 0; i < nCh; i++) {
|
||||
var ptr = buffers [i].Data;
|
||||
Marshal.Copy (ptr, data, 0, (int) n);
|
||||
}
|
||||
|
||||
evt.Set ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsafe int SinkHandlerRaw (IntPtr ts_ptr, uint n, IntPtr buffers_ptr, ManualResetEvent evt)
|
||||
{
|
||||
var ts = *(AudioTimeStamp*) ts_ptr;
|
||||
var buffers = new AudioBuffers (buffers_ptr);
|
||||
return SinkHandler2 (ts, n, buffers, evt);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,7 +22,6 @@ namespace Xamarin.MacDev.Tasks {
|
|||
task.AppBundleName = "AppBundleName";
|
||||
task.CompiledAppManifest = new TaskItem (Path.Combine (tmpdir, "TemporaryAppManifest.plist"));
|
||||
task.DefaultSdkVersion = Sdks.GetAppleSdk (platform).GetInstalledSdkVersions (false).First ().ToString ();
|
||||
task.SdkPlatform = PlatformFrameworkHelper.GetSdkPlatform (platform, false);
|
||||
task.SdkVersion = task.DefaultSdkVersion;
|
||||
task.TargetFrameworkMoniker = TargetFramework.GetTargetFramework (platform, true).ToString ();
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ namespace Xamarin.MacDev.Tasks {
|
|||
Task.CompiledAppManifest = new TaskItem (Path.Combine (Cache.CreateTemporaryDirectory (), "AppBundlePath", "Info.plist"));
|
||||
Task.AssemblyName = assemblyName;
|
||||
Task.AppManifest = new TaskItem (CreateTempFile ("foo.plist"));
|
||||
Task.SdkPlatform = "iPhoneSimulator";
|
||||
Task.SdkVersion = "10.0";
|
||||
|
||||
Plist = new PDictionary ();
|
||||
|
|
|
@ -24,7 +24,6 @@ namespace Xamarin.MacDev.Tasks {
|
|||
|
||||
var task = CreateTask<ReadAppManifest> ();
|
||||
task.AppManifest = new TaskItem (plistPath);
|
||||
task.SdkVersion = Sdks.GetAppleSdk (platform).GetInstalledSdkVersions (false).First ().ToString ();
|
||||
task.TargetFrameworkMoniker = TargetFramework.GetTargetFramework (platform, true).ToString ();
|
||||
|
||||
return task;
|
||||
|
|
|
@ -76,6 +76,8 @@ namespace Xharness {
|
|||
Xtro = 1 << 27,
|
||||
[Label ("packaged-macos")]
|
||||
PackagedMacOS = 1 << 28,
|
||||
[Label ("windows")]
|
||||
Windows = 1 << 29,
|
||||
[Label ("all")]
|
||||
All = Int64.MaxValue,
|
||||
}
|
||||
|
|
|
@ -18,17 +18,35 @@ namespace Extrospection {
|
|||
}
|
||||
|
||||
public static partial class Helpers {
|
||||
static Dictionary<string, string> map = new Dictionary<string, string> ();
|
||||
static Dictionary<string, object> map = new Dictionary<string, object> ();
|
||||
|
||||
public static void MapNames (string nativeName, string managedName)
|
||||
{
|
||||
map.Add (nativeName, managedName);
|
||||
if (map.TryGetValue (nativeName, out var value)) {
|
||||
if (value is string str) {
|
||||
var list = new List<string> ();
|
||||
list.Add (str);
|
||||
list.Add (managedName);
|
||||
map [nativeName] = list;
|
||||
} else if (value is List<string> list) {
|
||||
list.Add (managedName);
|
||||
} else {
|
||||
throw new InvalidOperationException ($"Unexpected type in map: {value}");
|
||||
}
|
||||
} else {
|
||||
map.Add (nativeName, managedName);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetManagedName (string nativeName)
|
||||
{
|
||||
map.TryGetValue (nativeName, out var result);
|
||||
return result ?? nativeName;
|
||||
if (!map.TryGetValue (nativeName, out var value))
|
||||
return nativeName;
|
||||
if (value is string str)
|
||||
return str;
|
||||
if (value is List<string> list)
|
||||
throw new InvalidOperationException ($"The native name '{nativeName}' has multiple managed types: {string.Join (", ", list)}");
|
||||
throw new InvalidOperationException ($"Unexpected type in map: {value}");
|
||||
}
|
||||
|
||||
public static string ReplaceFirstInstance (this string source, string find, string replace)
|
||||
|
|
|
@ -0,0 +1,375 @@
|
|||
using System;
|
||||
using Mono.Cecil;
|
||||
using ClassRedirector;
|
||||
|
||||
namespace ClassRedirectorTests;
|
||||
|
||||
[TestFixture]
|
||||
public class CodeTests {
|
||||
const string commonCode = @"
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ObjCRuntime {
|
||||
public class Runtime
|
||||
{
|
||||
|
||||
public static class ClassHandles
|
||||
{
|
||||
public static unsafe void InitializeClassHandles (MTClassMap* map)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum MTTypeFlags : uint {
|
||||
None = 0,
|
||||
CustomType = 1,
|
||||
UserType = 2,
|
||||
}
|
||||
|
||||
[StructLayout (LayoutKind.Sequential, Pack = 1)]
|
||||
public struct MTClassMap {
|
||||
public MTClassMap (IntPtr handle, uint type_reference, MTTypeFlags flags)
|
||||
{
|
||||
this.handle = handle;
|
||||
this.type_reference = type_reference;
|
||||
this.flags = flags;
|
||||
}
|
||||
public IntPtr handle;
|
||||
public uint type_reference;
|
||||
public MTTypeFlags flags;
|
||||
}
|
||||
}
|
||||
|
||||
public struct NativeHandle : IEquatable<NativeHandle> {
|
||||
readonly IntPtr handle;
|
||||
|
||||
public IntPtr Handle {
|
||||
get { return handle; }
|
||||
}
|
||||
|
||||
public static NativeHandle Zero = default (NativeHandle);
|
||||
|
||||
public NativeHandle (IntPtr handle)
|
||||
{
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
public static bool operator == (NativeHandle left, IntPtr right)
|
||||
{
|
||||
return left.handle == right;
|
||||
}
|
||||
|
||||
public static bool operator == (NativeHandle left, NativeHandle right)
|
||||
{
|
||||
return left.handle == right.handle;
|
||||
}
|
||||
|
||||
public static bool operator == (IntPtr left, NativeHandle right)
|
||||
{
|
||||
return left == right.Handle;
|
||||
}
|
||||
|
||||
public static bool operator != (NativeHandle left, IntPtr right)
|
||||
{
|
||||
return left.handle != right;
|
||||
}
|
||||
|
||||
public static bool operator != (IntPtr left, NativeHandle right)
|
||||
{
|
||||
return left != right.Handle;
|
||||
}
|
||||
|
||||
public static bool operator != (NativeHandle left, NativeHandle right)
|
||||
{
|
||||
return left.handle != right.Handle;
|
||||
}
|
||||
|
||||
// Should this be made explicit? The JIT seems to optimize conversions away to
|
||||
// treat everything as a plain IntPtr, so I'm not sure there's any reason
|
||||
// to not keep it implicit.
|
||||
public static implicit operator IntPtr (NativeHandle value)
|
||||
{
|
||||
return value.Handle;
|
||||
}
|
||||
|
||||
// Should this be made explicit? The JIT seems to optimize conversions away to
|
||||
// treat everything as a plain IntPtr, so I'm not sure there's any reason
|
||||
// to not keep it implicit.
|
||||
public static implicit operator NativeHandle (IntPtr value)
|
||||
{
|
||||
return new NativeHandle (value);
|
||||
}
|
||||
|
||||
public unsafe static explicit operator void* (NativeHandle value)
|
||||
{
|
||||
return (void *) (IntPtr) value;
|
||||
}
|
||||
|
||||
public unsafe static explicit operator NativeHandle (void * value)
|
||||
{
|
||||
return new NativeHandle ((IntPtr) value);
|
||||
}
|
||||
|
||||
public override bool Equals (object o)
|
||||
{
|
||||
if (o is NativeHandle nh)
|
||||
return nh.handle == this.handle;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
return handle.GetHashCode ();
|
||||
}
|
||||
|
||||
public bool Equals (NativeHandle other)
|
||||
{
|
||||
return other.handle == handle;
|
||||
}
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
return ""0x"" + handle.ToString (""x"");
|
||||
}
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
const string initTestCode = @"
|
||||
namespace ObjCRuntime {
|
||||
public class Program {
|
||||
public static int Main (string[] args) {
|
||||
var map = new Runtime.MTClassMap [] {
|
||||
new Runtime.MTClassMap(new IntPtr (42), 0, Runtime.MTTypeFlags.None)
|
||||
};
|
||||
unsafe {
|
||||
fixed (Runtime.MTClassMap* mapPtr = &map [0]) {
|
||||
Runtime.ClassHandles.InitializeClassHandles (mapPtr);
|
||||
}
|
||||
}
|
||||
var foo = new Foo ();
|
||||
Console.WriteLine (foo.ClassHandle);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class Foo {
|
||||
static NativeHandle class_ptr = NativeHandle.Zero;
|
||||
public Foo () { }
|
||||
public NativeHandle ClassHandle => class_ptr;
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
[Test]
|
||||
public void CompilesOK ()
|
||||
{
|
||||
var testCode = commonCode + initTestCode;
|
||||
var result = Compiler.Compile (testCode);
|
||||
Assert.That (String.IsNullOrEmpty (result.Error), $"Compile failure: {result.Error}");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompliesRunWithDefaultOutput ()
|
||||
{
|
||||
var testCode = commonCode + initTestCode;
|
||||
var result = Compiler.Compile (testCode);
|
||||
Assert.That (String.IsNullOrEmpty (result.Error), $"Compile failure: {result.Error}");
|
||||
|
||||
var codeOutput = Compiler.Run ("mono", new List<string> () { result.OutputFileName });
|
||||
Assert.That (codeOutput, Is.EqualTo ("0x0\n"), "incorrect executable output");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BasicProcessing ()
|
||||
{
|
||||
var testCode = commonCode + initTestCode;
|
||||
var result = Compiler.Compile (testCode);
|
||||
Assert.That (String.IsNullOrEmpty (result.Error), $"Compile failure: {result.Error}");
|
||||
|
||||
var map = new CSToObjCMap () {
|
||||
["ObjCRuntime.Foo"] = new ObjCNameIndex ("xxx", 0),
|
||||
};
|
||||
|
||||
|
||||
var rewriter = new Rewriter (map, result.OutputFileName, new string [] { result.OutputFileName });
|
||||
rewriter.Process ();
|
||||
var codeOutput = Compiler.Run ("mono", new List<string> () { result.OutputFileName });
|
||||
Assert.That (codeOutput, Is.EqualTo ("0x2a\n"), "incorrect executable output");
|
||||
}
|
||||
|
||||
const string noChangeTestCode = @"
|
||||
namespace ObjCRuntime {
|
||||
public class Program {
|
||||
public static int Main (string[] args) {
|
||||
var map = new Runtime.MTClassMap [] {
|
||||
new Runtime.MTClassMap(new IntPtr (42), 0, Runtime.MTTypeFlags.None)
|
||||
};
|
||||
unsafe {
|
||||
fixed (Runtime.MTClassMap* mapPtr = &map [0]) {
|
||||
Runtime.ClassHandles.InitializeClassHandles (mapPtr);
|
||||
}
|
||||
}
|
||||
var bar = new Bar ();
|
||||
Console.WriteLine (bar.ClassHandle);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class Foo {
|
||||
static NativeHandle class_ptr = NativeHandle.Zero;
|
||||
public Foo () { }
|
||||
public NativeHandle ClassHandle => class_ptr;
|
||||
}
|
||||
|
||||
public class Bar {
|
||||
static NativeHandle class_ptr = NativeHandle.Zero;
|
||||
public Bar () { }
|
||||
public NativeHandle ClassHandle => class_ptr;
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
[Test]
|
||||
public void LeavesBarAlone ()
|
||||
{
|
||||
var testCode = commonCode + noChangeTestCode;
|
||||
var result = Compiler.Compile (testCode);
|
||||
Assert.That (String.IsNullOrEmpty (result.Error), $"Compile failure: {result.Error}");
|
||||
|
||||
var map = new CSToObjCMap () {
|
||||
["ObjCRuntime.Foo"] = new ObjCNameIndex ("xxx", 0),
|
||||
};
|
||||
|
||||
|
||||
var rewriter = new Rewriter (map, result.OutputFileName, new string [] { result.OutputFileName });
|
||||
rewriter.Process ();
|
||||
var codeOutput = Compiler.Run ("mono", new List<string> () { result.OutputFileName });
|
||||
Assert.That (codeOutput, Is.EqualTo ("0x0\n"), "incorrect executable output");
|
||||
}
|
||||
|
||||
const string noCCtorTestCode = @"
|
||||
namespace ObjCRuntime {
|
||||
public class Program {
|
||||
public static int Main (string[] args) {
|
||||
var map = new Runtime.MTClassMap [] {
|
||||
new Runtime.MTClassMap(new IntPtr (42), 0, Runtime.MTTypeFlags.None)
|
||||
};
|
||||
unsafe {
|
||||
fixed (Runtime.MTClassMap* mapPtr = &map [0]) {
|
||||
Runtime.ClassHandles.InitializeClassHandles (mapPtr);
|
||||
}
|
||||
}
|
||||
var foo = new Foo ();
|
||||
Console.WriteLine (foo.ClassHandle);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class Class {
|
||||
public static NativeHandle GetHandle (string s) {
|
||||
return NativeHandle.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public class Foo {
|
||||
static NativeHandle class_ptr = Class.GetHandle (""nothing"");
|
||||
public Foo () { }
|
||||
public NativeHandle ClassHandle => class_ptr;
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
[Test]
|
||||
public void RemovesCCtor ()
|
||||
{
|
||||
var testCode = commonCode + noCCtorTestCode;
|
||||
var result = Compiler.Compile (testCode);
|
||||
Assert.That (String.IsNullOrEmpty (result.Error), $"Compile failure: {result.Error}");
|
||||
|
||||
var map = new CSToObjCMap () {
|
||||
["ObjCRuntime.Foo"] = new ObjCNameIndex ("xxx", 0),
|
||||
};
|
||||
|
||||
|
||||
var rewriter = new Rewriter (map, result.OutputFileName, new string [] { result.OutputFileName });
|
||||
rewriter.Process ();
|
||||
var codeOutput = Compiler.Run ("mono", new List<string> () { result.OutputFileName });
|
||||
Assert.That (codeOutput, Is.EqualTo ("0x2a\n"), "incorrect executable output");
|
||||
var module = ModuleDefinition.ReadModule (result.OutputFileName);
|
||||
var type = module.Types.FirstOrDefault (t => t.Name == "Foo");
|
||||
Assert.NotNull (type, "didn't find Foo");
|
||||
var cctor = type.Methods.FirstOrDefault (m => m.Name == ".cctor");
|
||||
Assert.IsNull (cctor, "we had a cctor - oops");
|
||||
}
|
||||
|
||||
const string multiObjectCode = @"
|
||||
namespace ObjCRuntime {
|
||||
public class Program {
|
||||
public static int Main (string[] args) {
|
||||
var map = new Runtime.MTClassMap [] {
|
||||
new Runtime.MTClassMap(new IntPtr (42), 0, Runtime.MTTypeFlags.None),
|
||||
new Runtime.MTClassMap(new IntPtr (43), 1, Runtime.MTTypeFlags.None),
|
||||
new Runtime.MTClassMap(new IntPtr (44), 2, Runtime.MTTypeFlags.None),
|
||||
};
|
||||
unsafe {
|
||||
fixed (Runtime.MTClassMap* mapPtr = &map [0]) {
|
||||
Runtime.ClassHandles.InitializeClassHandles (mapPtr);
|
||||
}
|
||||
}
|
||||
var baz = new Baz ();
|
||||
Console.WriteLine (baz.ClassHandle);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class Class {
|
||||
public static NativeHandle GetHandle (string s) {
|
||||
return NativeHandle.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public class Foo {
|
||||
static NativeHandle class_ptr = Class.GetHandle (""nothing"");
|
||||
public Foo () { }
|
||||
public NativeHandle ClassHandle => class_ptr;
|
||||
}
|
||||
|
||||
public class Bar {
|
||||
static NativeHandle class_ptr = Class.GetHandle (""nothing"");
|
||||
public Bar () { }
|
||||
public NativeHandle ClassHandle => class_ptr;
|
||||
}
|
||||
|
||||
public class Baz {
|
||||
static NativeHandle class_ptr = Class.GetHandle (""nothing"");
|
||||
public Baz () { }
|
||||
public NativeHandle ClassHandle => class_ptr;
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
[Test]
|
||||
public void MultiObjects ()
|
||||
{
|
||||
var testCode = commonCode + multiObjectCode;
|
||||
var result = Compiler.Compile (testCode);
|
||||
Assert.That (String.IsNullOrEmpty (result.Error), $"Compile failure: {result.Error}");
|
||||
|
||||
var map = new CSToObjCMap () {
|
||||
["ObjCRuntime.Foo"] = new ObjCNameIndex ("xxx", 0),
|
||||
["ObjCRuntime.Bar"] = new ObjCNameIndex ("yyy", 1),
|
||||
["ObjCRuntime.Baz"] = new ObjCNameIndex ("zzz", 2),
|
||||
};
|
||||
|
||||
|
||||
var rewriter = new Rewriter (map, result.OutputFileName, new string [] { result.OutputFileName });
|
||||
rewriter.Process ();
|
||||
var codeOutput = Compiler.Run ("mono", new List<string> () { result.OutputFileName });
|
||||
Assert.That (codeOutput, Is.EqualTo ("0x2c\n"), "incorrect executable output");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ClassRedirectorTests {
|
||||
public class CompileResult {
|
||||
bool disposedValue;
|
||||
|
||||
public CompileResult (string directoryPath, string outputFileName, string error)
|
||||
{
|
||||
DirectoryPath = directoryPath;
|
||||
OutputFileName = outputFileName;
|
||||
Error = error;
|
||||
}
|
||||
|
||||
public string DirectoryPath { get; private set; }
|
||||
public string OutputFileName { get; private set; }
|
||||
public string Error { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using Xamarin;
|
||||
using Xamarin.Utils;
|
||||
|
||||
namespace ClassRedirectorTests;
|
||||
|
||||
public class Compiler {
|
||||
public Compiler ()
|
||||
{
|
||||
}
|
||||
|
||||
public static CompileResult Compile (string code)
|
||||
{
|
||||
var directory = Cache.CreateTemporaryDirectory ("class-redirector");
|
||||
var file = "Code.cs";
|
||||
var inputpath = Path.Combine (directory, file);
|
||||
var outputpath = Path.Combine (directory, "Code.exe");
|
||||
File.WriteAllText (inputpath, code);
|
||||
|
||||
//var args = "-unsafe -out:Code.exe " + inputpath;
|
||||
string result = "";
|
||||
try {
|
||||
var args = new List<string> () {
|
||||
"-unsafe",
|
||||
"-out:Code.exe",
|
||||
inputpath
|
||||
};
|
||||
var execTask = Execution.RunAsync ("mcs", args, environment: null, mergeOutput: false,
|
||||
workingDirectory: directory, log: null, timeout: null, cancellationToken: null);
|
||||
execTask.Wait ();
|
||||
var execResult = execTask.Result;
|
||||
if (execResult.ExitCode != 0) {
|
||||
result = execResult.StandardError?.ToString () ?? "no error?!";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
result = e.Message;
|
||||
}
|
||||
|
||||
return new CompileResult (directory, outputpath, result);
|
||||
}
|
||||
|
||||
public static string Run (string path, List<string> args, string? workingDirectory = null, bool verbose = false)
|
||||
{
|
||||
var execTask = Execution.RunAsync (path, args, environment: null, mergeOutput: false);
|
||||
execTask.Wait ();
|
||||
var execResult = execTask.Result;
|
||||
if (execResult.ExitCode != 0)
|
||||
throw new Exception ($"Failed to execute (exit code {execResult.ExitCode}): {path} {string.Join (" ", args)}\n{execResult.StandardError?.ToString () ?? "".ToString ()}");
|
||||
return execResult.StandardOutput?.ToString () ?? "";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3,6 +3,7 @@ using System.Xml.Linq;
|
|||
|
||||
namespace ClassRedirectorTests;
|
||||
|
||||
[TestFixture]
|
||||
public class XmlTests {
|
||||
[Test]
|
||||
public void WritesCorrectXml ()
|
||||
|
|
|
@ -18,14 +18,17 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\common\CSToObjCMap.cs">
|
||||
<Link>CSToObjCMap.cs</Link>
|
||||
<ProjectReference Include="..\class-redirector\class-redirector.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\tests\mtouch\Cache.cs">
|
||||
<Link>Cache.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\common\ObjCNameIndex.cs">
|
||||
<Link>ObjCNameIndex.cs</Link>
|
||||
<Compile Include="..\..\common\Execution.cs">
|
||||
<Link>Execution.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\common\StaticRegistrarFile.cs">
|
||||
<Link>StaticRegistrarFile.cs</Link>
|
||||
<Compile Include="..\..\common\StringUtils.cs">
|
||||
<Link>StringUtils.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -6,8 +6,9 @@ using Mono.Cecil.Rocks;
|
|||
|
||||
namespace ClassRedirector {
|
||||
public class Rewriter {
|
||||
const string classHandleName = "ObjRuntime.Runtime.ClassHandles";
|
||||
const string mtClassMapName = "ObjCRuntime.Runtime.MTClassMap";
|
||||
const string runtimeName = "ObjCRuntime.Runtime";
|
||||
const string classHandleName = "ObjCRuntime.Runtime/ClassHandles";
|
||||
const string mtClassMapName = "ObjCRuntime.Runtime/MTClassMap";
|
||||
const string nativeHandleName = "ObjCRuntime.NativeHandle";
|
||||
const string initClassHandlesName = "InitializeClassHandles";
|
||||
const string classPtrName = "class_ptr";
|
||||
|
@ -34,7 +35,8 @@ namespace ClassRedirector {
|
|||
Dictionary<string, FieldDefinition> CreateClassHandles ()
|
||||
{
|
||||
var classMap = new Dictionary<string, FieldDefinition> ();
|
||||
using var module = ModuleDefinition.ReadModule (pathToXamarinAssembly);
|
||||
using var assemblyStm = new FileStream (pathToXamarinAssembly, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
|
||||
using var module = ModuleDefinition.ReadModule (assemblyStm);
|
||||
|
||||
var classHandles = LocateClassHandles (module);
|
||||
if (classHandles is null)
|
||||
|
@ -50,7 +52,7 @@ namespace ClassRedirector {
|
|||
if (mtClassMapDef is null)
|
||||
throw new Exception ($"Unable to find {mtClassMapName} in {pathToXamarinAssembly}");
|
||||
|
||||
var nativeHandle = module.Types.FirstOrDefault (t => t.Name == nativeHandleName);
|
||||
var nativeHandle = module.Types.FirstOrDefault (t => t.FullName == nativeHandleName);
|
||||
if (nativeHandle is null)
|
||||
throw new Exception ($"Unable to find {nativeHandleName} in {pathToXamarinAssembly}");
|
||||
|
||||
|
@ -116,18 +118,19 @@ namespace ClassRedirector {
|
|||
|
||||
TypeDefinition? LocateClassHandles (ModuleDefinition module)
|
||||
{
|
||||
return module.GetType (classHandleName);
|
||||
return AllTypes (module).FirstOrDefault (t => t.FullName == classHandleName);
|
||||
}
|
||||
|
||||
TypeDefinition? LocateMTClassMap (ModuleDefinition module)
|
||||
{
|
||||
return module.GetType (mtClassMapName);
|
||||
return AllTypes (module).FirstOrDefault (t => t.FullName == mtClassMapName);
|
||||
}
|
||||
|
||||
void PatchClassPtrUsage (Dictionary<string, FieldDefinition> classMap)
|
||||
{
|
||||
foreach (var path in assembliesToPatch) {
|
||||
using var module = ModuleDefinition.ReadModule (path);
|
||||
using var stm = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
|
||||
using var module = ModuleDefinition.ReadModule (stm);
|
||||
PatchClassPtrUsage (classMap, module);
|
||||
module.Write ();
|
||||
}
|
||||
|
@ -135,7 +138,7 @@ namespace ClassRedirector {
|
|||
|
||||
void PatchClassPtrUsage (Dictionary<string, FieldDefinition> classMap, ModuleDefinition module)
|
||||
{
|
||||
foreach (var cl in module.Types) {
|
||||
foreach (var cl in AllTypes (module)) {
|
||||
if (classMap.TryGetValue (cl.FullName, out var classPtrField)) {
|
||||
PatchClassPtrUsage (cl, classPtrField);
|
||||
}
|
||||
|
@ -168,9 +171,11 @@ namespace ClassRedirector {
|
|||
|
||||
void PatchMethod (MethodDefinition method, FieldDefinition classPtr, FieldDefinition classPtrField)
|
||||
{
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
var il = method.Body.GetILProcessor ();
|
||||
for (int i = 0; i < method.Body.Instructions.Count; i++) {
|
||||
var instr = method.Body.Instructions [i];
|
||||
if (instr.OpCode == OpCodes.Ldsfld && instr.Operand == classPtr) {
|
||||
instr.Operand = classPtrField;
|
||||
il.Replace (instr, Instruction.Create (OpCodes.Ldsfld, method.Module.ImportReference (classPtrField)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,6 +258,26 @@ namespace ClassRedirector {
|
|||
var instr = il.Body.Instructions [index]!;
|
||||
return instr.OpCode == OpCodes.Ldstr;
|
||||
}
|
||||
|
||||
IEnumerable<TypeDefinition> AllTypes (ModuleDefinition module)
|
||||
{
|
||||
foreach (var type in module.Types) {
|
||||
yield return type;
|
||||
foreach (var t in AllTypes (type))
|
||||
yield return t;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<TypeDefinition> AllTypes (TypeDefinition type)
|
||||
{
|
||||
if (type.HasNestedTypes) {
|
||||
foreach (var t in type.NestedTypes) {
|
||||
yield return t;
|
||||
foreach (var nt in AllTypes (t))
|
||||
yield return nt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,8 @@ namespace Xamarin.Bundler {
|
|||
public bool EnableMarkerOnlyBitCode { get { return BitCodeMode == BitCodeMode.MarkerOnly; } }
|
||||
public bool EnableBitCode { get { return BitCodeMode != BitCodeMode.None; } }
|
||||
|
||||
public bool SkipMarkingNSObjectsInUserAssemblies { get; set; }
|
||||
|
||||
// assembly_build_targets describes what kind of native code each assembly should be compiled into for mobile targets (iOS, tvOS, watchOS).
|
||||
// An assembly can be compiled into: static object (.o), dynamic library (.dylib) or a framework (.framework).
|
||||
// In the case of a framework, each framework may contain the native code for multiple assemblies.
|
||||
|
|
|
@ -254,6 +254,9 @@ namespace Xamarin.Bundler {
|
|||
options.Add ("require-pinvoke-wrappers:", v => {
|
||||
app.RequiresPInvokeWrappers = ParseBool (v, "--require-pinvoke-wrappers");
|
||||
});
|
||||
options.Add ("skip-marking-nsobjects-in-user-assemblies:", "Don't mark NSObject (and any subclass of NSObject) in user assemblies in the linker. This may break your app, use at own risk.", v => {
|
||||
app.SkipMarkingNSObjectsInUserAssemblies = ParseBool (v, "--skip-marking-nsobjects-in-user-assemblies");
|
||||
});
|
||||
|
||||
|
||||
// Keep the ResponseFileSource option at the end.
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
param
|
||||
(
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$GithubToken,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$MaccorePath
|
||||
)
|
||||
|
||||
# maccore is special, we use fetch there in some bash scripts, but VSTS uses https.. and some pools don't like the above.. :/
|
||||
git -C "$MaccorePath" remote remove origin
|
||||
git -C "$MaccorePath" remote add origin "https://$GithubToken@github.com/xamarin/maccore.git"
|
||||
git -C "$MaccorePath" remote # don't add -v else we see the pat
|
|
@ -0,0 +1,36 @@
|
|||
param
|
||||
(
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$GithubToken,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$RepositoryUri,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$SourceBranch,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$CommentToHide
|
||||
)
|
||||
|
||||
Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY/xamarin-macios/tools/devops/automation/scripts/MaciosCI.psd1
|
||||
|
||||
$comments = New-GitHubCommentsObjectFromUrl -Url "$RepositoryUri" -Token $GithubToken
|
||||
|
||||
$prId = "$SourceBranch".Replace("refs/pull/", "").Replace("/merge", "")
|
||||
$prComments = $comments.GetCommentsForPR($prId)
|
||||
|
||||
$botComments = [System.Collections.ArrayList]@()
|
||||
foreach ($c in $prComments) {
|
||||
if ($c.Author -eq "vs-mobiletools-engineering-service2") {
|
||||
if ($c.Body.Contains($CommentToHide)) {
|
||||
$botComments.Add($c)
|
||||
}
|
||||
}
|
||||
}
|
||||
$comments.MinimizeComments($botComments)
|
|
@ -0,0 +1,41 @@
|
|||
param
|
||||
(
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$VstsToken,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$Style,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$Output,
|
||||
|
||||
[String]
|
||||
$Predicate
|
||||
)
|
||||
|
||||
# there is no var that gives us the start time, but we can use the rest api to get the time when
|
||||
# the build started
|
||||
|
||||
# User name can be anything. It is the personal access token (PAT) token that matters.
|
||||
$user= "AnyUser"
|
||||
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user, $VstsToken)))
|
||||
$headers = @{Authorization = "Basic {0}" -f $base64AuthInfo}
|
||||
|
||||
# get the url of the build
|
||||
$url= $Env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI + "$Env:SYSTEM_TEAMPROJECT/_apis/build/builds/" + $Env:BUILD_BUILDID + "?api-version=5.1"
|
||||
$buildPipeline= Invoke-RestMethod -Uri $url -Headers $headers -Method Get
|
||||
|
||||
$start=[DateTime]::Parse($buildPipeline.startTime).ToString("yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
$end=Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
Write-Host "end time: $end"
|
||||
|
||||
if (-not $Predicate) {
|
||||
log show --style $Style --start "$start" --end "$end" > $Output
|
||||
} else {
|
||||
log show --predicate $Predicate --style $Style --start "$start" --end "$end" > $Output
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
function RemoveUtf8Bom
|
||||
{
|
||||
param(
|
||||
[string]$FilePath
|
||||
)
|
||||
|
||||
$encoding = New-Object -TypeName System.Text.UTF8Encoding
|
||||
$content = Get-Content -Path $FilePath -Raw
|
||||
[System.IO.File]::WriteAllLines($FilePath, $content, $encoding)
|
||||
}
|
||||
|
||||
foreach ($locFile in (Get-Content -Path $env:XLocFileList))
|
||||
{
|
||||
RemoveUtf8Bom -FilePath $locFile
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
param
|
||||
(
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$WorkloadPath
|
||||
)
|
||||
|
||||
$versionData = Get-Content $WorkloadPath | ConvertFrom-Json
|
||||
$platforms = $("iOS", "tvOS", "macOS", "MacCatalyst")
|
||||
foreach ($platform in $platforms) {
|
||||
$platformLower = $platform.ToLowerInvariant()
|
||||
$platformUpper = $platform.ToUpperInvariant()
|
||||
$version = $versionData."microsoft.net.sdk.$platformLower"
|
||||
if (![string]::IsNullOrEmpty($version)) {
|
||||
$version = $version.Substring(0, $version.IndexOf('/'))
|
||||
Write-Host "Platform: $platform has version $version"
|
||||
Write-Host "##vso[task.setvariable variable=$($platformUpper)_WORKLOAD_VERSION;]$version"
|
||||
} else {
|
||||
Write-Host "Platform: $platform has no version (disabled?)"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
Write-Host "IsMacOS: ${IsMacOS}"
|
||||
Write-Host "IsWindows: ${IsWindows}"
|
||||
Write-Host "IsLinux: ${IsLinux}"
|
||||
|
||||
if ($IsMacOS -or $IsLinux) {
|
||||
Write-Host "HOSTNAME: $(hostname)"
|
||||
} else {
|
||||
Write-Host "COMPUTERNAME: ${env:COMPUTERNAME}"
|
||||
}
|
||||
|
||||
gci env: | format-table -autosize -wrap
|
||||
|
||||
if ($IsMacOS) {
|
||||
system_profiler SPSoftwareDataType SPHardwareDataType SPDeveloperToolsDataType
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
param
|
||||
(
|
||||
[Parameter(Mandatory)]
|
||||
[String]
|
||||
$SourceBranch,
|
||||
|
||||
[String]
|
||||
$IsPr
|
||||
)
|
||||
|
||||
if($IsPr.ToLower() -eq "true") {
|
||||
Write-Host "Working on a PR, Undoing the github merge with main."
|
||||
|
||||
git config remote.origin.fetch '+refs/pull/*:refs/remotes/origin/pull/*'
|
||||
git fetch origin
|
||||
|
||||
$branch="$SourceBranch".Replace("merge", "head")
|
||||
$branch=$branch.Replace("refs", "origin")
|
||||
|
||||
Write-Host "Checking out branch $branch"
|
||||
|
||||
git checkout $branch
|
||||
git submodule update --recursive --init
|
||||
git clean -xffd
|
||||
git submodule foreach --recursive git clean -xffd
|
||||
$hash = git rev-parse HEAD
|
||||
|
||||
Write-Host "##vso[task.setvariable variable=GIT_HASH;isOutput=true]$hash"
|
||||
} else {
|
||||
Write-Host "Working on a branch, using current commit"
|
||||
$hash = git rev-parse HEAD
|
||||
Write-Host "##vso[task.setvariable variable=GIT_HASH;isOutput=true]$hash"
|
||||
}
|
|
@ -27,18 +27,7 @@ steps:
|
|||
repositoryAlias: ${{ parameters.repositoryAlias }}
|
||||
commit: ${{ parameters.commit }}
|
||||
|
||||
- powershell: |
|
||||
Write-Host "IsMacOS: ${IsMacOS}"
|
||||
Write-Host "IsWindows: ${IsWindows}"
|
||||
Write-Host "IsLinux: ${IsLinux}"
|
||||
|
||||
if ($IsMacOS -or $IsLinux) {
|
||||
Write-Host "HOSTNAME: $(hostname)"
|
||||
} else {
|
||||
Write-Host "COMPUTERNAME: ${env:COMPUTERNAME}"
|
||||
}
|
||||
|
||||
gci env: | format-table -autosize -wrap
|
||||
- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1
|
||||
displayName: 'Show Environment'
|
||||
|
||||
- pwsh: |
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
# template that contains all the different steps to create a pkgs, publish the results and provide feedback to the
|
||||
# developers in github.
|
||||
parameters:
|
||||
- name: vsdropsPrefix
|
||||
type: string
|
||||
|
||||
- name: keyringPass
|
||||
type: string
|
||||
|
||||
- name: gitHubToken
|
||||
type: string
|
||||
|
||||
- name: xqaCertPass
|
||||
type: string
|
||||
|
||||
- name: enableDotnet
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
- name: pool
|
||||
type: string
|
||||
default: automatic
|
||||
|
||||
- name: isPR
|
||||
type: boolean
|
||||
|
||||
- name: repositoryAlias
|
||||
type: string
|
||||
default: self
|
||||
|
||||
- name: commit
|
||||
type: string
|
||||
default: HEAD
|
||||
|
||||
- name: xcodeChannel
|
||||
type: string
|
||||
|
||||
- name: macOSName
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
- job: configure
|
||||
displayName: 'Configure build'
|
||||
pool:
|
||||
vmImage: windows-latest
|
||||
|
||||
variables:
|
||||
isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]
|
||||
isScheduled: $[eq(variables['Build.Reason'], 'Schedule')]
|
||||
|
||||
steps:
|
||||
- template: ../common/configure.yml
|
||||
parameters:
|
||||
repositoryAlias: ${{ parameters.repositoryAlias }}
|
||||
commit: ${{ parameters.commit }}
|
||||
uploadArtifacts: true
|
||||
enableDotnet: ${{ parameters.enableDotnet }}
|
||||
|
||||
- ${{ if eq(parameters.pool, 'automatic') }}:
|
||||
- job: AgentPoolSelector # https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml
|
||||
pool: # Consider using an agentless (server) job here, but would need to host selection logic as an Azure function: https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#server
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- checkout: none # https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#checkout
|
||||
|
||||
# Selects appropriate agent pool based on trigger type (PR or CI); manually triggered builds target the PR pool
|
||||
- template: azure-devops-pools/agent-pool-selector.yml@yaml-templates
|
||||
parameters:
|
||||
agentPoolPR: $(PRBuildPool)
|
||||
agentPoolPRUrl: $(PRBuildPoolUrl)
|
||||
agentPoolCI: $(CIBuildPool)
|
||||
agentPoolCIUrl: $(CIBuildPoolUrl)
|
||||
|
||||
# This job builds the macOS tests.
|
||||
#
|
||||
# - configure: Get the labels from gihub and populate the output.
|
||||
# - AgentPoolSelector: If the build was not manually triggered to use a specific pool, this job is used to decide if the build is using a
|
||||
# private pool or a public one.
|
||||
- job: build_macos_tests_job
|
||||
dependsOn:
|
||||
- ${{ if eq(parameters.pool, 'automatic') }}:
|
||||
- AgentPoolSelector
|
||||
- configure
|
||||
displayName: 'Build macOS tests'
|
||||
timeoutInMinutes: 120
|
||||
variables:
|
||||
DOTNET_PLATFORMS: $[ dependencies.configure.outputs['configure_platforms.DOTNET_PLATFORMS'] ]
|
||||
ENABLE_DOTNET: $[ dependencies.configure.outputs['configure_platforms.ENABLE_DOTNET'] ]
|
||||
INCLUDE_XAMARIN_LEGACY: $[ dependencies.configure.outputs['configure_platforms.INCLUDE_XAMARIN_LEGACY'] ]
|
||||
${{ if eq(parameters.pool, 'automatic') }}:
|
||||
AgentPoolComputed: $[ dependencies.AgentPoolSelector.outputs['setAgentPool.AgentPoolComputed'] ]
|
||||
${{ if eq(parameters.pool, 'ci') }}:
|
||||
AgentPoolComputed: $(CIBuildPool)
|
||||
${{ if eq(parameters.pool, 'pr') }}:
|
||||
AgentPoolComputed: $(PRBuildPool)
|
||||
# add all the variables that have been parsed by the configuration step. Could we have a less verbose way??
|
||||
# old and ugly env var use by jenkins, we do have parts of the code that use it, contains the PR number
|
||||
PR_ID: $[ dependencies.configure.outputs['labels.pr_number'] ]
|
||||
# set the branch variable name, this is required by jenkins and we have a lot of scripts that depend on it
|
||||
BRANCH_NAME: $[ replace(variables['Build.SourceBranch'], 'refs/heads/', '') ]
|
||||
RUN_MAC_TESTS: $[ dependencies.configure.outputs['decisions.RUN_MAC_TESTS'] ]
|
||||
condition: ne(dependencies.configure.outputs['decisions.RUN_MAC_TESTS'],'')
|
||||
pool:
|
||||
name: $(AgentPoolComputed)
|
||||
demands:
|
||||
- Agent.OS -equals Darwin
|
||||
- macOS.Name -equals ${{ parameters.macOSName }}
|
||||
- XcodeChannel -equals ${{ parameters.xcodeChannel }}
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- template: build-mac-tests.yml
|
||||
parameters:
|
||||
isPR: ${{ parameters.isPR }}
|
||||
repositoryAlias: ${{ parameters.repositoryAlias }}
|
||||
commit: ${{ parameters.commit }}
|
||||
vsdropsPrefix: ${{ parameters.vsdropsPrefix }}
|
||||
keyringPass: ${{ parameters.keyringPass }}
|
||||
gitHubToken: ${{ parameters.gitHubToken }}
|
||||
xqaCertPass: ${{ parameters.xqaCertPass }}
|
||||
enableDotnet: ${{ parameters.enableDotnet }}
|
|
@ -0,0 +1,97 @@
|
|||
parameters:
|
||||
- name: vsdropsPrefix
|
||||
type: string
|
||||
|
||||
- name: keyringPass
|
||||
type: string
|
||||
|
||||
- name: gitHubToken
|
||||
type: string
|
||||
|
||||
- name: xqaCertPass
|
||||
type: string
|
||||
|
||||
- name: enableDotnet
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
- name: uploadBinlogs
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
- name: isPR
|
||||
type: boolean
|
||||
|
||||
- name: repositoryAlias
|
||||
type: string
|
||||
default: self
|
||||
|
||||
- name: commit
|
||||
type: string
|
||||
default: HEAD
|
||||
|
||||
- name: uploadPrefix
|
||||
type: string
|
||||
default: '$(MaciosUploadPrefix)'
|
||||
|
||||
steps:
|
||||
- template: build.yml
|
||||
parameters:
|
||||
isPR: ${{ parameters.isPR }}
|
||||
repositoryAlias: ${{ parameters.repositoryAlias }}
|
||||
commit: ${{ parameters.commit }}
|
||||
vsdropsPrefix: ${{ parameters.vsdropsPrefix }}
|
||||
keyringPass: ${{ parameters.keyringPass }}
|
||||
gitHubToken: ${{ parameters.gitHubToken }}
|
||||
xqaCertPass: ${{ parameters.xqaCertPass }}
|
||||
enableDotnet: ${{ parameters.enableDotnet }}
|
||||
buildSteps:
|
||||
|
||||
# funny enough we need these profiles to build the mac tests
|
||||
- bash: '"$BUILD_SOURCESDIRECTORY"/maccore/tools/install-qa-provisioning-profiles.sh -v'
|
||||
displayName: 'Add tests provisioning profiles'
|
||||
timeoutInMinutes: 30
|
||||
continueOnError: true # should not stop the build will result in test failures but we do want the pkg
|
||||
env:
|
||||
AUTH_TOKEN_GITHUB_COM: ${{ parameters.gitHubToken }}
|
||||
AUTH_TOKEN_LA_DEV_APPLE_P12: ${{ parameters.xqaCertPass }}
|
||||
AUTH_TOKEN_LA_DISTR_APPLE_P12: ${{ parameters.xqaCertPass }}
|
||||
AUTH_TOKEN_LA_MAC_INSTALLER_DISTR_P12: ${{ parameters.xqaCertPass }}
|
||||
AUTH_TOKEN_VSENG_XAMARIN_MAC_DEVICES_P12: ${{ parameters.xqaCertPass }}
|
||||
AUTH_TOKEN_VSENG_XAMARIN_MAC_DEVICES_2_P12: ${{ parameters.xqaCertPass }}
|
||||
|
||||
- bash: |
|
||||
set -x
|
||||
set -e
|
||||
|
||||
make -C $(Build.SourcesDirectory)/xamarin-macios/tests package-tests
|
||||
|
||||
if test -f "$(Build.SourcesDirectory)/xamarin-macios/tests/mac-test-package.7z"; then
|
||||
set +x
|
||||
echo "##vso[artifact.upload containerfolder=CrashReports;artifactname=${{ parameters.uploadPrefix }}mac-test-package]$(Build.SourcesDirectory)/xamarin-macios/tests/mac-test-package.7z"
|
||||
set -x
|
||||
fi
|
||||
|
||||
name: macTestPkg
|
||||
displayName: 'Package macOS tests'
|
||||
condition: and(succeeded(), contains(variables['RUN_MAC_TESTS'], 'true'))
|
||||
timeoutInMinutes: 60
|
||||
|
||||
- ${{ if eq(parameters.uploadBinlogs, true) }}:
|
||||
# Copy all the binlogs to a separate directory, keeping directory structure.
|
||||
- script: |
|
||||
set -x
|
||||
mkdir -p $(Build.ArtifactStagingDirectory)/mactests-binlogs
|
||||
rsync -av --prune-empty-dirs --include '*/' --include '*.binlog' --exclude '*' $(Build.SourcesDirectory)/xamarin-macios $(Build.ArtifactStagingDirectory)/mactests-binlogs
|
||||
displayName: Copy all binlogs
|
||||
continueOnError: true
|
||||
condition: succeededOrFailed()
|
||||
|
||||
# Publish all the binlogs we collected in the previous step
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Publish Artifact: All binlogs'
|
||||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)/mactests-binlogs
|
||||
artifactName: '${{ parameters.uploadPrefix }}mactests-binlogs-$(Build.BuildId)-$(System.JobAttempt)'
|
||||
continueOnError: true
|
||||
condition: succeededOrFailed()
|
|
@ -126,37 +126,6 @@ steps:
|
|||
artifactName: '${{ parameters.uploadPrefix }}not-signed-package'
|
||||
continueOnError: true
|
||||
|
||||
# funny enough we need these profiles to build the mac tests
|
||||
- bash: '"$BUILD_SOURCESDIRECTORY"/maccore/tools/install-qa-provisioning-profiles.sh -v'
|
||||
displayName: 'Add tests provisioning profiles'
|
||||
timeoutInMinutes: 30
|
||||
continueOnError: true # should not stop the build will result in test failures but we do want the pkg
|
||||
env:
|
||||
AUTH_TOKEN_GITHUB_COM: ${{ parameters.gitHubToken }}
|
||||
AUTH_TOKEN_LA_DEV_APPLE_P12: ${{ parameters.xqaCertPass }}
|
||||
AUTH_TOKEN_LA_DISTR_APPLE_P12: ${{ parameters.xqaCertPass }}
|
||||
AUTH_TOKEN_LA_MAC_INSTALLER_DISTR_P12: ${{ parameters.xqaCertPass }}
|
||||
AUTH_TOKEN_VSENG_XAMARIN_MAC_DEVICES_P12: ${{ parameters.xqaCertPass }}
|
||||
AUTH_TOKEN_VSENG_XAMARIN_MAC_DEVICES_2_P12: ${{ parameters.xqaCertPass }}
|
||||
|
||||
- bash: |
|
||||
set -x
|
||||
set -e
|
||||
|
||||
make -C $(Build.SourcesDirectory)/xamarin-macios/tests package-tests
|
||||
|
||||
if test -f "$(Build.SourcesDirectory)/xamarin-macios/tests/mac-test-package.7z"; then
|
||||
set +x
|
||||
echo "##vso[artifact.upload containerfolder=CrashReports;artifactname=${{ parameters.uploadPrefix }}mac-test-package]$(Build.SourcesDirectory)/xamarin-macios/tests/mac-test-package.7z"
|
||||
set -x
|
||||
fi
|
||||
|
||||
name: macTestPkg
|
||||
displayName: 'Package macOS tests'
|
||||
condition: and(succeeded(), contains(variables['RUN_MAC_TESTS'], 'true'))
|
||||
continueOnError: true # not a terrible blocking issue
|
||||
timeoutInMinutes: 60
|
||||
|
||||
- bash: |
|
||||
set -x
|
||||
set -e
|
||||
|
|
|
@ -217,7 +217,6 @@ steps:
|
|||
|
||||
# We'll need these profiles to build the hot restart prebuilt app during the build
|
||||
# (it's built for device, and thus needs a certificate available so that the app can be signed).
|
||||
# We do this again before running the tests further below.
|
||||
- bash: |
|
||||
set -x
|
||||
set -e
|
||||
|
|
|
@ -22,29 +22,10 @@ steps:
|
|||
submodules: recursive
|
||||
path: s/xamarin-macios
|
||||
|
||||
- ${{ if parameters.isPR }}:
|
||||
- pwsh: |
|
||||
git config remote.origin.fetch '+refs/pull/*:refs/remotes/origin/pull/*'
|
||||
git fetch origin
|
||||
$branch="$(Build.SourceBranch)".Replace("merge", "head")
|
||||
$branch=$branch.Replace("refs", "origin")
|
||||
Write-Host "Checking out branch $branch"
|
||||
git checkout $branch
|
||||
git submodule update --recursive --init
|
||||
git clean -xffd
|
||||
git submodule foreach --recursive git clean -xffd
|
||||
$hash = git rev-parse HEAD
|
||||
Write-Host "##vso[task.setvariable variable=GIT_HASH;isOutput=true]$hash"
|
||||
name: fix_commit
|
||||
displayName: "Undo Github merge"
|
||||
workingDirectory: $(System.DefaultWorkingDirectory)/xamarin-macios
|
||||
- ${{ else }}:
|
||||
- pwsh: |
|
||||
$hash = git rev-parse HEAD
|
||||
Write-Host "##vso[task.setvariable variable=GIT_HASH;isOutput=true]$hash"
|
||||
name: fix_commit
|
||||
displayName: "Undo Github merge"
|
||||
workingDirectory: $(System.DefaultWorkingDirectory)/xamarin-macios
|
||||
- pwsh: ./undo_github_merge.ps1 -SourceBranch "$(Build.SourceBranch)" -IsPr "${{ parameters.isPR }}"
|
||||
name: fix_commit
|
||||
displayName: "Undo Github merge"
|
||||
workingDirectory: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts
|
||||
|
||||
- checkout: maccore
|
||||
clean: true
|
||||
|
@ -57,10 +38,6 @@ steps:
|
|||
- checkout: release-scripts
|
||||
clean: true
|
||||
|
||||
- pwsh: |
|
||||
# maccore is special, we use fetch there in some bash scripts, but VSTS uses https.. and some pools don't like the above.. :/
|
||||
git remote remove origin
|
||||
git remote add origin https://$(GitHub.Token)@github.com/xamarin/maccore.git
|
||||
git remote # don't add -v else we see the pat
|
||||
- pwsh: ./clean_git_vsts.ps1 -GithubToken "$(GitHub.Token)" -MaccorePath "$(System.DefaultWorkingDirectory)/maccore"
|
||||
displayName: 'Clean git mess from VSTS'
|
||||
workingDirectory: $(System.DefaultWorkingDirectory)/maccore
|
||||
workingDirectory: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts
|
||||
|
|
|
@ -26,22 +26,11 @@ steps:
|
|||
repositoryAlias: ${{ parameters.repositoryAlias }}
|
||||
commit: ${{ parameters.commit }}
|
||||
|
||||
- pwsh: |
|
||||
Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY/xamarin-macios/tools/devops/automation/scripts/MaciosCI.psd1
|
||||
|
||||
$comments = New-GitHubCommentsObjectFromUrl -Url "$(Build.Repository.Uri)" -Token $(GitHub.Token)
|
||||
$ciComment = "${{ parameters.commentToHide }}"
|
||||
|
||||
$prId = "$(Build.SourceBranch)".Replace("refs/pull/", "").Replace("/merge", "")
|
||||
$prComments = $comments.GetCommentsForPR($prId)
|
||||
|
||||
$botComments = [System.Collections.ArrayList]@()
|
||||
foreach ($c in $prComments) {
|
||||
if ($c.Author -eq "vs-mobiletools-engineering-service2") {
|
||||
if ($c.Body.Contains($ciComment)) {
|
||||
$botComments.Add($c)
|
||||
}
|
||||
}
|
||||
}
|
||||
$comments.MinimizeComments($botComments)
|
||||
- pwsh: >-
|
||||
./clean_past_comments.ps1
|
||||
-GithubToken "$(GitHub.Token)"
|
||||
-RepositoryUri "$(Build.Repository.Uri)"
|
||||
-SourceBranch "$(Build.SourceBranch)"
|
||||
-CommentToHide "${{ parameters.commentToHide }}"
|
||||
displayName: Clear past comments
|
||||
workingDirectory: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts
|
||||
|
|
|
@ -35,44 +35,15 @@ parameters:
|
|||
|
||||
steps:
|
||||
|
||||
- pwsh: |
|
||||
$style=$Env:STYLE
|
||||
$output=$Env:OUTPUT
|
||||
|
||||
Write-Host "output path: $output"
|
||||
|
||||
# there is no var that gives us the start time, but we can use the rest api to get the time when
|
||||
# the build started
|
||||
|
||||
# User name can be anything. It is the personal access token (PAT) token that matters.
|
||||
$user= "AnyUser"
|
||||
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user, $Env:ACCESSTOKEN)))
|
||||
$headers = @{Authorization = "Basic {0}" -f $base64AuthInfo}
|
||||
|
||||
# get the url of the build
|
||||
$url= $Env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI + "$Env:SYSTEM_TEAMPROJECT/_apis/build/builds/" + $Env:BUILD_BUILDID + "?api-version=5.1"
|
||||
$buildPipeline= Invoke-RestMethod -Uri $url -Headers $headers -Method Get
|
||||
|
||||
$start=[DateTime]::Parse($buildPipeline.startTime).ToString("yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
$end=Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
Write-Host "end time: $end"
|
||||
|
||||
$predicate=$Env:PREDICATE
|
||||
if (-not $predicate) {
|
||||
log show --style $style --start "$start" --end "$end" > $output
|
||||
} else {
|
||||
log show --predicate $predicate --style $style --start "$start" --end "$end" > $output
|
||||
}
|
||||
|
||||
- pwsh: >-
|
||||
$(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/generate_agent_logs.ps1
|
||||
-VstsToken "$(System.AccessToken)"
|
||||
-Style "${{ parameters.style }}"
|
||||
-Output "${{ parameters.outputPath }}"
|
||||
-Predicate "${{ parameters.predicate }}"
|
||||
displayName: 'Gathering agent logs'
|
||||
condition: always()
|
||||
continueOnError: true
|
||||
env:
|
||||
ACCESSTOKEN: $(System.AccessToken)
|
||||
OUTPUT: ${{ parameters.outputPath }}
|
||||
PREDICATE: ${{ parameters.predicate }}
|
||||
STYLE: ${{ parameters.style }}
|
||||
${{ if ne(parameters.workingDirectory, '') }}:
|
||||
workingDirectory: ${{ parameters.workingDirectory }}
|
||||
|
||||
|
|
|
@ -27,20 +27,7 @@ steps:
|
|||
continueOnError: true
|
||||
timeoutInMinutes: 60
|
||||
|
||||
- powershell: |
|
||||
Write-Host "IsMacOS: ${IsMacOS}"
|
||||
Write-Host "IsWindows: ${IsWindows}"
|
||||
Write-Host "IsLinux: ${IsLinux}"
|
||||
|
||||
if ($IsMacOS -or $IsLinux) {
|
||||
Write-Host "HOSTNAME: $(hostname)"
|
||||
} else {
|
||||
Write-Host "COMPUTERNAME: ${env:COMPUTERNAME}"
|
||||
}
|
||||
|
||||
gci env: | format-table -autosize -wrap
|
||||
|
||||
system_profiler SPSoftwareDataType SPHardwareDataType SPDeveloperToolsDataType
|
||||
- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1
|
||||
displayName: 'Show Environment'
|
||||
|
||||
- powershell: |
|
||||
|
|
|
@ -34,18 +34,7 @@ steps:
|
|||
Dir $(System.DefaultWorkingDirectory)
|
||||
displayName: Show directories
|
||||
|
||||
- powershell: |
|
||||
Write-Host "IsMacOS: ${IsMacOS}"
|
||||
Write-Host "IsWindows: ${IsWindows}"
|
||||
Write-Host "IsLinux: ${IsLinux}"
|
||||
|
||||
if ($IsMacOS -or $IsLinux) {
|
||||
Write-Host "HOSTNAME: $(hostname)"
|
||||
} else {
|
||||
Write-Host "COMPUTERNAME: ${env:COMPUTERNAME}"
|
||||
}
|
||||
|
||||
gci env: | format-table -autosize -wrap
|
||||
- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1
|
||||
displayName: 'Show Environment'
|
||||
|
||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||
|
|
|
@ -95,6 +95,7 @@ steps:
|
|||
repoType: gitHub
|
||||
gitHubPatVariable: '$(GitHub.Token)'
|
||||
isDeletePrSourceBranchSelected: false
|
||||
xLocCustomPowerShellScript: '$(Build.SourcesDirectory)\\tools\\devops\\automation\\scripts\\localizationBomRemoval.ps1'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
continueOnError: true
|
||||
|
|
|
@ -73,9 +73,8 @@ steps:
|
|||
# download the packages that have been created, install them, later download the zip files that contain the already built
|
||||
# tests and execute them.
|
||||
|
||||
- pwsh: |
|
||||
gci env: | format-table -autosize -wrap
|
||||
displayName: 'Dump Environment'
|
||||
- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1
|
||||
displayName: 'Show Environment'
|
||||
|
||||
- bash: |
|
||||
ioreg -l | grep -e Manufacturer -e 'Vendor Name'
|
||||
|
@ -138,39 +137,6 @@ steps:
|
|||
displayName: "Remove artifacts"
|
||||
condition: always()
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download not notarized build
|
||||
inputs:
|
||||
artifact: '${{ parameters.uploadPrefix }}not-signed-package'
|
||||
allowFailedBuilds: true
|
||||
path: $(Build.SourcesDirectory)/package
|
||||
|
||||
- pwsh: |
|
||||
$dir = "$(Build.SourcesDirectory)/package"
|
||||
Dir $dir
|
||||
$items = Get-ChildItem $dir -Recurse
|
||||
foreach ($i in $items) {
|
||||
if ($i.Name -like "xamarin.mac-*.pkg") {
|
||||
$path = $i.FullName
|
||||
Write-Host "##vso[task.setvariable variable=XM_PACKAGE;]$path"
|
||||
}
|
||||
}
|
||||
displayName: 'Set Mac pkgs url'
|
||||
timeoutInMinutes: 5
|
||||
|
||||
- bash: |
|
||||
echo "Pkg uri is $XM_PACKAGE"
|
||||
make -C $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/ mac-tests-provisioning.csx
|
||||
displayName: 'Generate Provisionator csx file'
|
||||
|
||||
- task: xamops.azdevex.provisionator-task.provisionator@2
|
||||
displayName: 'Provision Products & Frameworks'
|
||||
inputs:
|
||||
provisioning_script: $(Build.SourcesDirectory)/xamarin-macios/tools/devops/mac-tests-provisioning.csx
|
||||
provisioning_extra_args: '-vvvv'
|
||||
github_token: $(Github.Token)
|
||||
timeoutInMinutes: 250
|
||||
|
||||
# Executed ONLY if we want to clear the provisionator cache.
|
||||
- bash: rm -rf "$TOOLS_DIR/provisionator"
|
||||
env:
|
||||
|
@ -186,20 +152,13 @@ steps:
|
|||
allowFailedBuilds: true
|
||||
path: $(Build.SourcesDirectory)/artifacts/tmp
|
||||
|
||||
# sometimes the make that creates the pkgs fails.
|
||||
- bash: |
|
||||
set -ex
|
||||
if ! test -f $(Build.SourcesDirectory)/artifacts/tmp/${{ parameters.uploadPrefix }}mac-test-package/mac-test-package.7z; then
|
||||
echo "No test package could be found for tests on macOS $CONTEXT" > "$GITHUB_FAILURE_COMMENT_FILE"
|
||||
exit 1
|
||||
fi
|
||||
ls -Rla $(Build.SourcesDirectory)/artifacts/tmp
|
||||
7z x $(Build.SourcesDirectory)/artifacts/tmp/${{ parameters.uploadPrefix }}mac-test-package/mac-test-package.7z -o$(Build.SourcesDirectory)/artifacts/ -bb1
|
||||
# no prefix! we did expand to the exact name we are using
|
||||
ls -Rla $(Build.SourcesDirectory)/artifacts/mac-test-package
|
||||
displayName: Expand tests.
|
||||
env:
|
||||
CONTEXT: ${{ parameters.statusContext }}
|
||||
|
||||
- bash: |
|
||||
ls -Rla $(Build.SourcesDirectory)/artifacts
|
||||
|
|
|
@ -43,8 +43,8 @@ stages:
|
|||
- stage: ${{ parameters.stageName }}
|
||||
displayName: ${{ parameters.displayName }}
|
||||
dependsOn:
|
||||
- build_packages
|
||||
condition: and(succeeded(), eq(dependencies.build_packages.outputs['configure.decisions.RUN_MAC_TESTS'], 'true'))
|
||||
- build_macos_tests
|
||||
condition: and(succeeded(), eq(dependencies.build_macos_tests.outputs['configure.decisions.RUN_MAC_TESTS'], 'true'))
|
||||
variables:
|
||||
GITHUB_FAILURE_COMMENT_FILE: $(System.DefaultWorkingDirectory)/github-comment-file.md
|
||||
|
||||
|
@ -83,7 +83,7 @@ stages:
|
|||
|
||||
variables:
|
||||
PR_ID: $[ dependencies.configure.outputs['labels.pr_number'] ]
|
||||
GIT_HASH: $[ stageDependencies.build_packages.build.outputs['fix_commit.GIT_HASH'] ]
|
||||
GIT_HASH: $[ stageDependencies.build_macos_tests.build.outputs['fix_commit.GIT_HASH'] ]
|
||||
|
||||
steps:
|
||||
- template: build.yml
|
||||
|
|
|
@ -235,6 +235,26 @@ stages:
|
|||
skipESRP: ${{ parameters.skipESRP }}
|
||||
pool: ${{ parameters.pool }}
|
||||
|
||||
- stage: build_macos_tests
|
||||
displayName: '${{ parameters.stageDisplayNamePrefix }}Build macOS tests'
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
${{ if and(ne(parameters.dependsOn, ''), ne(parameters.dependsOnResult, '')) }}:
|
||||
condition: eq(dependencies.${{ parameters.dependsOn }}.result, '${{ parameters.dependsOnResult }}')
|
||||
jobs:
|
||||
- template: ./build/build-mac-tests-stage.yml
|
||||
parameters:
|
||||
xcodeChannel: ${{ parameters.xcodeChannel }}
|
||||
macOSName: ${{ parameters.macOSName }}
|
||||
isPR: ${{ parameters.isPR }}
|
||||
repositoryAlias: ${{ parameters.repositoryAlias }}
|
||||
commit: ${{ parameters.commit }}
|
||||
vsdropsPrefix: ${{ variables.vsdropsPrefix }}
|
||||
keyringPass: $(pass--lab--mac--builder--keychain)
|
||||
gitHubToken: $(Github.Token)
|
||||
xqaCertPass: $(xqa--certificates--password)
|
||||
enableDotnet: ${{ parameters.enableDotnet }}
|
||||
pool: ${{ parameters.pool }}
|
||||
|
||||
- ${{ each pkg_obj in parameters.packages }}:
|
||||
- stage: ${{ pkg_obj.job }}
|
||||
displayName: '${{ parameters.stageDisplayNamePrefix }}${{ pkg_obj.displayName }}'
|
||||
|
|
|
@ -79,20 +79,7 @@ jobs:
|
|||
- checkout: release-scripts
|
||||
clean: true
|
||||
|
||||
- pwsh: |
|
||||
Write-Host "IsMacOS: ${IsMacOS}"
|
||||
Write-Host "IsWindows: ${IsWindows}"
|
||||
Write-Host "IsLinux: ${IsLinux}"
|
||||
|
||||
if ($IsMacOS -or $IsLinux) {
|
||||
Write-Host "HOSTNAME: $(hostname)"
|
||||
} else {
|
||||
Write-Host "COMPUTERNAME: ${env:COMPUTERNAME}"
|
||||
}
|
||||
|
||||
gci env: | format-table -autosize -wrap
|
||||
|
||||
system_profiler SPSoftwareDataType SPHardwareDataType SPDeveloperToolsDataType
|
||||
- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1
|
||||
displayName: 'Show Environment'
|
||||
|
||||
- bash: |
|
||||
|
|
|
@ -76,22 +76,10 @@ steps:
|
|||
allowFailedBuilds: true
|
||||
path: $(Build.SourcesDirectory)/artifacts
|
||||
|
||||
- pwsh: |
|
||||
$workloadPath = "$(Build.SourcesDirectory)/artifacts/${{ parameters.uploadPrefix }}WorkloadRollback/WorkloadRollback.json"
|
||||
$versionData = Get-Content $workloadPath | ConvertFrom-Json
|
||||
$platforms = $("iOS", "tvOS", "macOS", "MacCatalyst")
|
||||
foreach ($platform in $platforms) {
|
||||
$platformLower = $platform.ToLowerInvariant()
|
||||
$platformUpper = $platform.ToUpperInvariant()
|
||||
$version = $versionData."microsoft.net.sdk.$platformLower"
|
||||
if (![string]::IsNullOrEmpty($version)) {
|
||||
$version = $version.Substring(0, $version.IndexOf('/'))
|
||||
Write-Host "Platform: $platform has version $version"
|
||||
Write-Host "##vso[task.setvariable variable=$($platformUpper)_WORKLOAD_VERSION;]$version"
|
||||
} else {
|
||||
Write-Host "Platform: $platform has no version (disabled?)"
|
||||
}
|
||||
}
|
||||
- pwsh: >-
|
||||
./set_xtro_workloads.ps1
|
||||
-WorkloadPath "$(Build.SourcesDirectory)/artifacts/${{ parameters.uploadPrefix }}WorkloadRollback/WorkloadRollback.json"
|
||||
workingDirectory: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts
|
||||
displayName: 'Set workload versions for xtro'
|
||||
|
||||
- bash: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/bash/install-workloads.sh
|
||||
|
|
|
@ -27,8 +27,7 @@ steps:
|
|||
repositoryAlias: ${{ parameters.repositoryAlias }}
|
||||
commit: ${{ parameters.commit }}
|
||||
|
||||
- pwsh: |
|
||||
gci env: | format-table -autosize -wrap
|
||||
- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1
|
||||
displayName: 'Dump Environment'
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
|
|
|
@ -261,6 +261,11 @@ namespace Xamarin.Linker {
|
|||
throw new InvalidOperationException ($"Unable to parse the {key} value: {value} in {linker_file}");
|
||||
SdkVersion = sdk_version;
|
||||
break;
|
||||
case "SkipMarkingNSObjectsInUserAssemblies":
|
||||
if (!TryParseOptionalBoolean (value, out var skip_marking_nsobjects_in_user_assemblies))
|
||||
throw new InvalidOperationException ($"Unable to parse the {key} value: {value} in {linker_file}");
|
||||
Application.SkipMarkingNSObjectsInUserAssemblies = skip_marking_nsobjects_in_user_assemblies.Value;
|
||||
break;
|
||||
case "TargetArchitectures":
|
||||
if (!Enum.TryParse<Abi> (value, out var arch))
|
||||
throw new InvalidOperationException ($"Unknown target architectures: {value} in {linker_file}");
|
||||
|
|
|
@ -143,8 +143,11 @@ namespace Xamarin.Linker.Steps {
|
|||
return (method.DeclaringType.Module.Assembly.Name.Name == ProductAssembly);
|
||||
}
|
||||
|
||||
static bool IsProductType (TypeDefinition type)
|
||||
bool IsProductType (TypeDefinition type)
|
||||
{
|
||||
if (LinkContext.App.SkipMarkingNSObjectsInUserAssemblies)
|
||||
return true;
|
||||
|
||||
var name = type.Module.Assembly.Name.Name;
|
||||
switch (name) {
|
||||
case "Xamarin.Forms.Platform.iOS":
|
||||
|
|
Загрузка…
Ссылка в новой задаче