Merge main into xcode14. (#15914)
This commit is contained in:
Коммит
d9a07ee7ef
|
@ -1,6 +1,6 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AssemblyName>Build</AssemblyName>
|
||||
<NoWarn>$(NoWarn);NU1603</NoWarn> <!-- Xamarin.Messaging.Build.Common 1.6.24 depends on Merq (>= 1.1.0) but Merq 1.1.0 was not found. An approximate best match of Merq 1.1.4 was resolved. -->
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>../../product.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>../../product.snk</AssemblyOriginatorKeyFile>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
|
|
@ -2685,6 +2685,9 @@ Copyright (C) 2018 Microsoft. All rights reserved.
|
|||
<_AppContainerDir Condition="'$(IsAppDistribution)' == 'true'">$(ArchivePath)\Products\Applications\</_AppContainerDir>
|
||||
<AppBundleDir>$(_AppContainerDir)$(_AppBundleName)$(AppBundleExtension)</AppBundleDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(_AppContainerDir)' == ''">
|
||||
<_AppContainerDir>$([System.IO.Path]::GetDirectoryName($(AppBundleDir)))/</_AppContainerDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<!-- Ensure _AppBundlePath is a relative path (relative to the project directory) and contains a trailing slash -->
|
||||
<_AppBundlePath>$(AppBundleDir)</_AppBundlePath>
|
||||
|
|
|
@ -312,8 +312,8 @@ Copyright (C) 2011-2013 Xamarin. All rights reserved.
|
|||
Outputs="$(_LinkSemaphore)">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- We need to use net5.0 because when building from VS it sets MSBuildRuntimeType to Core and will pick net472 (which doesn't contain the illink assembly) -->
|
||||
<_RemoteILLinkPath>$(ILLinkTasksAssembly.Replace('$(NetCoreRoot)', '$(_DotNetRootRemoteDirectory)').Replace('net472', 'net6.0').Replace('$([System.IO.Path]::GetFileName('$(ILLinkTasksAssembly)'))', 'illink.dll'))</_RemoteILLinkPath>
|
||||
<!-- We need to use netX.Y because when building from VS it sets MSBuildRuntimeType to Core and will pick net472 (which doesn't contain the illink assembly) -->
|
||||
<_RemoteILLinkPath>$(ILLinkTasksAssembly.Replace('$(NetCoreRoot)', '$(_DotNetRootRemoteDirectory)').Replace('net472', 'net$(BundledNETCoreAppTargetFrameworkVersion)').Replace('$([System.IO.Path]::GetFileName('$(ILLinkTasksAssembly)'))', 'illink.dll'))</_RemoteILLinkPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Include Debug symbols as input so those are copied to the server -->
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<MergeSystemAssemblies>false</MergeSystemAssemblies>
|
||||
<IncludeMSBuildAssets Condition="'$(IncludeMSBuildAssets)' == ''">compile</IncludeMSBuildAssets>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<IncludeMSBuildAssets Condition="'$(IncludeMSBuildAssets)' == ''">compile</IncludeMSBuildAssets>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
|
|
|
@ -56,8 +56,8 @@ typedef struct {
|
|||
} MTProperty;
|
||||
|
||||
// This structure completely describes everything required to resolve a metadata token
|
||||
typedef struct MTFullTokenReference {
|
||||
const char *assembly_name; /* the name of the assembly */
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t assembly_index; /* index into the 'assemblies' array in the registration map */
|
||||
uint32_t module_token;
|
||||
uint32_t token;
|
||||
} MTFullTokenReference;
|
||||
|
@ -99,10 +99,15 @@ typedef struct __attribute__((packed)) {
|
|||
const __unsafe_unretained Protocol * const * protocols; // the corresponding native protocols
|
||||
} MTProtocolMap;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
const char *name;
|
||||
const char *mvid;
|
||||
} MTAssembly;
|
||||
|
||||
struct MTRegistrationMap;
|
||||
|
||||
struct MTRegistrationMap {
|
||||
const char **assembly;
|
||||
const MTAssembly *assemblies;
|
||||
MTClassMap *map;
|
||||
const MTFullTokenReference *full_token_references;
|
||||
// There are some managed types that are not registered because their ObjC
|
||||
|
|
|
@ -59,7 +59,11 @@ namespace CoreFoundation {
|
|||
|
||||
// CFRunLoop.h
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
#if NET
|
||||
internal unsafe struct CFRunLoopSourceContext {
|
||||
#else
|
||||
internal struct CFRunLoopSourceContext {
|
||||
#endif
|
||||
public CFIndex Version;
|
||||
public IntPtr Info;
|
||||
public IntPtr Retain;
|
||||
|
@ -67,9 +71,15 @@ namespace CoreFoundation {
|
|||
public IntPtr CopyDescription;
|
||||
public IntPtr Equal;
|
||||
public IntPtr Hash;
|
||||
#if NET
|
||||
public delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> Schedule;
|
||||
public delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> Cancel;
|
||||
public delegate* unmanaged<IntPtr, void> Perform;
|
||||
#else
|
||||
public IntPtr Schedule;
|
||||
public IntPtr Cancel;
|
||||
public IntPtr Perform;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NET
|
||||
|
@ -145,9 +155,11 @@ namespace CoreFoundation {
|
|||
[DllImport (Constants.CoreFoundationLibrary)]
|
||||
extern static /* CFRunLoopSourceRef */ IntPtr CFRunLoopSourceCreate (/* CFAllocatorRef */ IntPtr allocator, /* CFIndex */ nint order, /* CFRunLoopSourceContext* */ ref CFRunLoopSourceContext context);
|
||||
|
||||
#if !NET
|
||||
static ScheduleCallback ScheduleDelegate = (ScheduleCallback) Schedule;
|
||||
static CancelCallback CancelDelegate = (CancelCallback) Cancel;
|
||||
static PerformCallback PerformDelegate = (PerformCallback) Perform;
|
||||
#endif
|
||||
|
||||
protected CFRunLoopSourceCustom ()
|
||||
: base (IntPtr.Zero, true)
|
||||
|
@ -155,9 +167,17 @@ namespace CoreFoundation {
|
|||
gch = GCHandle.Alloc (this);
|
||||
var ctx = new CFRunLoopSourceContext ();
|
||||
ctx.Info = GCHandle.ToIntPtr (gch);
|
||||
#if NET
|
||||
unsafe {
|
||||
ctx.Schedule = &Schedule;
|
||||
ctx.Cancel = &Cancel;
|
||||
ctx.Perform = &Perform;
|
||||
}
|
||||
#else
|
||||
ctx.Schedule = Marshal.GetFunctionPointerForDelegate (ScheduleDelegate);
|
||||
ctx.Cancel = Marshal.GetFunctionPointerForDelegate (CancelDelegate);
|
||||
ctx.Perform = Marshal.GetFunctionPointerForDelegate (PerformDelegate);
|
||||
#endif
|
||||
|
||||
var handle = CFRunLoopSourceCreate (IntPtr.Zero, 0, ref ctx);
|
||||
InitializeHandle (handle);
|
||||
|
@ -165,7 +185,11 @@ namespace CoreFoundation {
|
|||
|
||||
delegate void ScheduleCallback (IntPtr info, IntPtr runLoop, IntPtr mode);
|
||||
|
||||
#if NET
|
||||
[UnmanagedCallersOnly]
|
||||
#else
|
||||
[MonoPInvokeCallback (typeof(ScheduleCallback))]
|
||||
#endif
|
||||
static void Schedule (IntPtr info, IntPtr runLoop, IntPtr mode)
|
||||
{
|
||||
var source = GCHandle.FromIntPtr (info).Target as CFRunLoopSourceCustom;
|
||||
|
@ -182,7 +206,11 @@ namespace CoreFoundation {
|
|||
|
||||
delegate void CancelCallback (IntPtr info, IntPtr runLoop, IntPtr mode);
|
||||
|
||||
#if NET
|
||||
[UnmanagedCallersOnly]
|
||||
#else
|
||||
[MonoPInvokeCallback (typeof(CancelCallback))]
|
||||
#endif
|
||||
static void Cancel (IntPtr info, IntPtr runLoop, IntPtr mode)
|
||||
{
|
||||
var source = GCHandle.FromIntPtr (info).Target as CFRunLoopSourceCustom;
|
||||
|
@ -199,7 +227,11 @@ namespace CoreFoundation {
|
|||
|
||||
delegate void PerformCallback (IntPtr info);
|
||||
|
||||
#if NET
|
||||
[UnmanagedCallersOnly]
|
||||
#else
|
||||
[MonoPInvokeCallback (typeof(PerformCallback))]
|
||||
#endif
|
||||
static void Perform (IntPtr info)
|
||||
{
|
||||
var source = GCHandle.FromIntPtr (info).Target as CFRunLoopSourceCustom;
|
||||
|
|
|
@ -330,27 +330,50 @@ namespace CoreVideo {
|
|||
public delegate CVReturn DisplayLinkOutputCallback (CVDisplayLink displayLink, ref CVTimeStamp inNow, ref CVTimeStamp inOutputTime, CVOptionFlags flagsIn, ref CVOptionFlags flagsOut);
|
||||
delegate CVReturn CVDisplayLinkOutputCallback (IntPtr displayLink, ref CVTimeStamp inNow, ref CVTimeStamp inOutputTime, CVOptionFlags flagsIn, ref CVOptionFlags flagsOut, IntPtr displayLinkContext);
|
||||
|
||||
#if NET
|
||||
[UnmanagedCallersOnly]
|
||||
static unsafe CVReturn OutputCallback (IntPtr displayLink, CVTimeStamp* inNow, CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, IntPtr displayLinkContext)
|
||||
#else
|
||||
static CVDisplayLinkOutputCallback static_OutputCallback = new CVDisplayLinkOutputCallback (OutputCallback);
|
||||
|
||||
#if !MONOMAC
|
||||
[MonoPInvokeCallback (typeof (CVDisplayLinkOutputCallback))]
|
||||
#endif
|
||||
static CVReturn OutputCallback (IntPtr displayLink, ref CVTimeStamp inNow, ref CVTimeStamp inOutputTime, CVOptionFlags flagsIn, ref CVOptionFlags flagsOut, IntPtr displayLinkContext)
|
||||
#endif
|
||||
{
|
||||
GCHandle callbackHandle = GCHandle.FromIntPtr (displayLinkContext);
|
||||
DisplayLinkOutputCallback func = (DisplayLinkOutputCallback) callbackHandle.Target!;
|
||||
CVDisplayLink delegateDisplayLink = new CVDisplayLink(displayLink, false);
|
||||
#if NET
|
||||
return func (delegateDisplayLink,
|
||||
ref System.Runtime.CompilerServices.Unsafe.AsRef<CVTimeStamp> (inNow),
|
||||
ref System.Runtime.CompilerServices.Unsafe.AsRef<CVTimeStamp> (inOutputTime),
|
||||
flagsIn, ref System.Runtime.CompilerServices.Unsafe.AsRef<CVOptionFlags> (flagsOut));
|
||||
#else
|
||||
return func (delegateDisplayLink, ref inNow, ref inOutputTime, flagsIn, ref flagsOut);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if NET
|
||||
[DllImport (Constants.CoreVideoLibrary)]
|
||||
extern static unsafe CVReturn CVDisplayLinkSetOutputCallback (IntPtr displayLink, delegate* unmanaged<IntPtr, CVTimeStamp*, CVTimeStamp*, CVOptionFlags, CVOptionFlags *, IntPtr, CVReturn> function, IntPtr userInfo);
|
||||
#else
|
||||
[DllImport (Constants.CoreVideoLibrary)]
|
||||
extern static CVReturn CVDisplayLinkSetOutputCallback (IntPtr displayLink, CVDisplayLinkOutputCallback function, IntPtr userInfo);
|
||||
#endif
|
||||
public CVReturn SetOutputCallback (DisplayLinkOutputCallback callback)
|
||||
{
|
||||
callbackHandle = GCHandle.Alloc (callback);
|
||||
#if NET
|
||||
unsafe {
|
||||
CVReturn ret = CVDisplayLinkSetOutputCallback (this.Handle, &OutputCallback, GCHandle.ToIntPtr (callbackHandle));
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
CVReturn ret = CVDisplayLinkSetOutputCallback (this.Handle, static_OutputCallback, GCHandle.ToIntPtr (callbackHandle));
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if NET
|
||||
|
|
|
@ -146,15 +146,35 @@ namespace CoreVideo {
|
|||
/* void * CV_NULLABLE */ IntPtr releaseRefCon,
|
||||
/* const void * CV_NULLABLE */ IntPtr baseAddress);
|
||||
|
||||
#if !NET
|
||||
static CVPixelBufferReleaseBytesCallback releaseBytesCallback = new CVPixelBufferReleaseBytesCallback (ReleaseBytesCallback);
|
||||
#endif
|
||||
|
||||
#if NET
|
||||
[UnmanagedCallersOnly]
|
||||
#else
|
||||
[MonoPInvokeCallbackAttribute (typeof (CVPixelBufferReleaseBytesCallback))]
|
||||
#endif
|
||||
static void ReleaseBytesCallback (IntPtr releaseRefCon, IntPtr baseAddress)
|
||||
{
|
||||
GCHandle handle = GCHandle.FromIntPtr (releaseRefCon);
|
||||
handle.Free ();
|
||||
}
|
||||
|
||||
#if NET
|
||||
[DllImport (Constants.CoreVideoLibrary)]
|
||||
static unsafe extern CVReturn CVPixelBufferCreateWithBytes (
|
||||
/* CFAllocatorRef CV_NULLABLE */ IntPtr allocator,
|
||||
/* size_t */ nint width,
|
||||
/* size_t */ nint height,
|
||||
/* OSType */ CVPixelFormatType pixelFormatType,
|
||||
/* void * CV_NONNULL */ IntPtr baseAddress,
|
||||
/* size_t */ nint bytesPerRow,
|
||||
delegate* unmanaged<IntPtr, IntPtr, void> releaseCallback,
|
||||
/* void * CV_NULLABLE */ IntPtr releaseRefCon,
|
||||
/* CFDictionaryRef CV_NULLABLE */ IntPtr pixelBufferAttributes,
|
||||
/* CV_RETURNS_RETAINED_PARAMETER CVPixelBufferRef CV_NULLABLE * CV_NONNULL */ out IntPtr pixelBufferOut);// __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_4_0);
|
||||
#else
|
||||
[DllImport (Constants.CoreVideoLibrary)]
|
||||
static extern CVReturn CVPixelBufferCreateWithBytes (
|
||||
/* CFAllocatorRef CV_NULLABLE */ IntPtr allocator,
|
||||
|
@ -167,7 +187,7 @@ namespace CoreVideo {
|
|||
/* void * CV_NULLABLE */ IntPtr releaseRefCon,
|
||||
/* CFDictionaryRef CV_NULLABLE */ IntPtr pixelBufferAttributes,
|
||||
/* CV_RETURNS_RETAINED_PARAMETER CVPixelBufferRef CV_NULLABLE * CV_NONNULL */ out IntPtr pixelBufferOut);// __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_4_0);
|
||||
|
||||
#endif
|
||||
public static CVPixelBuffer? Create (nint width, nint height, CVPixelFormatType pixelFormatType, byte[] data, nint bytesPerRow, CVPixelBufferAttributes pixelBufferAttributes)
|
||||
{
|
||||
CVReturn status;
|
||||
|
@ -187,7 +207,13 @@ namespace CoreVideo {
|
|||
|
||||
gchandle = GCHandle.Alloc (data, GCHandleType.Pinned); // This requires a pinned GCHandle, because unsafe code is scoped to the current block, and the address of the byte array will be used after this function returns.
|
||||
|
||||
#if NET
|
||||
unsafe {
|
||||
status = CVPixelBufferCreateWithBytes (IntPtr.Zero, width, height, pixelFormatType, gchandle.AddrOfPinnedObject (), bytesPerRow, &ReleaseBytesCallback, GCHandle.ToIntPtr (gchandle), DictionaryContainerHelper.GetHandle (pixelBufferAttributes), out handle);
|
||||
}
|
||||
#else
|
||||
status = CVPixelBufferCreateWithBytes (IntPtr.Zero, width, height, pixelFormatType, gchandle.AddrOfPinnedObject (), bytesPerRow, releaseBytesCallback, GCHandle.ToIntPtr (gchandle), DictionaryContainerHelper.GetHandle (pixelBufferAttributes), out handle);
|
||||
#endif
|
||||
|
||||
if (status != CVReturn.Success) {
|
||||
gchandle.Free ();
|
||||
|
@ -210,11 +236,11 @@ namespace CoreVideo {
|
|||
/* size_t */ nint dataSize,
|
||||
/* size_t */ nint numberOfPlanes,
|
||||
/* const void* */IntPtr planeAddresses);
|
||||
|
||||
#if !NET
|
||||
static CVPixelBufferReleasePlanarBytesCallback releasePlanarBytesCallback = new CVPixelBufferReleasePlanarBytesCallback (ReleasePlanarBytesCallback);
|
||||
#endif
|
||||
|
||||
[MonoPInvokeCallbackAttribute (typeof (CVPixelBufferReleasePlanarBytesCallback))]
|
||||
static void ReleasePlanarBytesCallback (IntPtr releaseRefCon, IntPtr dataPtr, nint dataSize, nint numberOfPlanes, IntPtr planeAddresses)
|
||||
static void ReleasePlanarBytesCallbackImpl (IntPtr releaseRefCon, IntPtr dataPtr, nint dataSize, nint numberOfPlanes, IntPtr planeAddresses)
|
||||
{
|
||||
GCHandle handle = GCHandle.FromIntPtr (releaseRefCon);
|
||||
PlaneData data = (PlaneData) handle.Target!;
|
||||
|
@ -222,7 +248,36 @@ namespace CoreVideo {
|
|||
data.dataHandles[i].Free ();
|
||||
handle.Free ();
|
||||
}
|
||||
#if NET
|
||||
[UnmanagedCallersOnly]
|
||||
#else
|
||||
[MonoPInvokeCallbackAttribute (typeof (CVPixelBufferReleasePlanarBytesCallback))]
|
||||
#endif
|
||||
static void ReleasePlanarBytesCallback (IntPtr releaseRefCon, IntPtr dataPtr, nint dataSize, nint numberOfPlanes, IntPtr planeAddresses)
|
||||
{
|
||||
ReleasePlanarBytesCallbackImpl (releaseRefCon, dataPtr, dataSize, numberOfPlanes, planeAddresses);
|
||||
}
|
||||
|
||||
#if NET
|
||||
[DllImport (Constants.CoreVideoLibrary)]
|
||||
static unsafe extern CVReturn CVPixelBufferCreateWithPlanarBytes (
|
||||
/* CFAllocatorRef CV_NULLABLE */ IntPtr allocator,
|
||||
/* size_t */ nint width,
|
||||
/* size_t */ nint height,
|
||||
/* OSType */ CVPixelFormatType pixelFormatType,
|
||||
/* void * CV_NULLABLE */ IntPtr dataPtr, /* pass a pointer to a plane descriptor block, or NULL /*
|
||||
/* size_t */ nint dataSize, /* pass size if planes are contiguous, NULL if not */
|
||||
/* size_t */ nint numberOfPlanes,
|
||||
/* void *[] CV_NULLABLE */ IntPtr[] planeBaseAddress,
|
||||
/* size_t[] */ nint [] planeWidth,
|
||||
/* size_t[] */ nint [] planeHeight,
|
||||
/* size_t[] */ nint [] planeBytesPerRow,
|
||||
delegate* unmanaged<IntPtr, IntPtr, nint, nint, IntPtr, void>/* CV_NULLABLE */ releaseCallback,
|
||||
/* void * CV_NULLABLE */ IntPtr releaseRefCon,
|
||||
/* CFDictionaryRef CV_NULLABLE */ IntPtr pixelBufferAttributes,
|
||||
/* CV_RETURNS_RETAINED_PARAMETER CVPixelBufferRef CV_NULLABLE * CV_NONNULL */ out IntPtr pixelBufferOut); // __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_4_0);
|
||||
|
||||
#else
|
||||
[DllImport (Constants.CoreVideoLibrary)]
|
||||
static extern CVReturn CVPixelBufferCreateWithPlanarBytes (
|
||||
/* CFAllocatorRef CV_NULLABLE */ IntPtr allocator,
|
||||
|
@ -240,6 +295,7 @@ namespace CoreVideo {
|
|||
/* void * CV_NULLABLE */ IntPtr releaseRefCon,
|
||||
/* CFDictionaryRef CV_NULLABLE */ IntPtr pixelBufferAttributes,
|
||||
/* CV_RETURNS_RETAINED_PARAMETER CVPixelBufferRef CV_NULLABLE * CV_NONNULL */ out IntPtr pixelBufferOut); // __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_4_0);
|
||||
#endif
|
||||
|
||||
public static CVPixelBuffer? Create (nint width, nint height, CVPixelFormatType pixelFormatType, byte[][] planes, nint[] planeWidths, nint[] planeHeights, nint[] planeBytesPerRow, CVPixelBufferAttributes pixelBufferAttributes)
|
||||
{
|
||||
|
@ -287,14 +343,24 @@ namespace CoreVideo {
|
|||
data_handle = GCHandle.Alloc (data);
|
||||
|
||||
IntPtr data_handle_ptr = GCHandle.ToIntPtr (data_handle);
|
||||
#if NET
|
||||
unsafe {
|
||||
status = CVPixelBufferCreateWithPlanarBytes (IntPtr.Zero,
|
||||
width, height, pixelFormatType, IntPtr.Zero, 0,
|
||||
planeCount, addresses, planeWidths, planeHeights, planeBytesPerRow,
|
||||
&ReleasePlanarBytesCallback, data_handle_ptr,
|
||||
DictionaryContainerHelper.GetHandle (pixelBufferAttributes), out handle);
|
||||
}
|
||||
#else
|
||||
status = CVPixelBufferCreateWithPlanarBytes (IntPtr.Zero,
|
||||
width, height, pixelFormatType, IntPtr.Zero, 0,
|
||||
planeCount, addresses, planeWidths, planeHeights, planeBytesPerRow,
|
||||
releasePlanarBytesCallback, data_handle_ptr,
|
||||
DictionaryContainerHelper.GetHandle (pixelBufferAttributes), out handle);
|
||||
#endif
|
||||
|
||||
if (status != CVReturn.Success) {
|
||||
ReleasePlanarBytesCallback (data_handle_ptr, IntPtr.Zero, 0, 0, IntPtr.Zero);
|
||||
ReleasePlanarBytesCallbackImpl (data_handle_ptr, IntPtr.Zero, 0, 0, IntPtr.Zero);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
@ -19,6 +20,10 @@ using Foundation;
|
|||
using Registrar;
|
||||
#endif
|
||||
|
||||
#if !COREBUILD
|
||||
using Xamarin.Bundler;
|
||||
#endif
|
||||
|
||||
#if !NET
|
||||
using NativeHandle = System.IntPtr;
|
||||
#endif
|
||||
|
@ -56,8 +61,8 @@ namespace ObjCRuntime {
|
|||
|
||||
|
||||
for (int i = 0; i < map->assembly_count; i++) {
|
||||
var ptr = Marshal.ReadIntPtr (map->assembly, i * IntPtr.Size);
|
||||
Runtime.Registrar.SetAssemblyRegistered (Marshal.PtrToStringAuto (ptr));
|
||||
var assembly = map->assemblies [i];
|
||||
Runtime.Registrar.SetAssemblyRegistered (Marshal.PtrToStringAuto (assembly.name));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,27 +297,27 @@ namespace ObjCRuntime {
|
|||
if ((token_reference & 0x1) == 0x1) {
|
||||
// full token reference
|
||||
var idx = (int) (token_reference >> 1);
|
||||
var entry = map->full_token_references + (IntPtr.Size + 8) * idx;
|
||||
var entry = map->full_token_references [idx];
|
||||
// first compare what's most likely to fail (the type's metadata token)
|
||||
var token = (uint) Marshal.ReadInt32 (entry + IntPtr.Size + 4);
|
||||
var token = entry.token;
|
||||
type_token |= 0x02000000 /* TypeDef - the token type is explicit in the full token reference, but not present in the type_token argument, so we have to add it before comparing */;
|
||||
if (type_token != token)
|
||||
return false;
|
||||
|
||||
// then the module token
|
||||
var module_token = (uint) Marshal.ReadInt32 (entry + IntPtr.Size);
|
||||
var module_token = entry.module_token;
|
||||
if (mod_token != module_token)
|
||||
return false;
|
||||
|
||||
// leave the assembly name for the end, since it's the most expensive comparison (string comparison)
|
||||
assembly_name = Marshal.ReadIntPtr (entry);
|
||||
assembly_name = map->assemblies [entry.assembly_index].name;
|
||||
} else {
|
||||
// packed token reference
|
||||
if (token_reference >> 8 != type_token)
|
||||
return false;
|
||||
|
||||
var assembly_index = (token_reference >> 1) & 0x7F;
|
||||
assembly_name = Marshal.ReadIntPtr (map->assembly, (int) assembly_index * IntPtr.Size);
|
||||
assembly_name = map->assemblies [(int) assembly_index].name;
|
||||
}
|
||||
|
||||
return Runtime.StringEquals (assembly_name, asm_name);
|
||||
|
@ -380,10 +385,11 @@ namespace ObjCRuntime {
|
|||
internal unsafe static MemberInfo? ResolveFullTokenReference (uint token_reference)
|
||||
{
|
||||
// sizeof (MTFullTokenReference) = IntPtr.Size + 4 + 4
|
||||
var entry = Runtime.options->RegistrationMap->full_token_references + (IntPtr.Size + 8) * (int) (token_reference >> 1);
|
||||
var assembly_name = Marshal.ReadIntPtr (entry);
|
||||
var module_token = (uint) Marshal.ReadInt32 (entry + IntPtr.Size);
|
||||
var token = (uint) Marshal.ReadInt32 (entry + IntPtr.Size + 4);
|
||||
var idx = (int) (token_reference >> 1);
|
||||
var entry = Runtime.options->RegistrationMap->full_token_references [idx];
|
||||
var assembly_name = Runtime.options->RegistrationMap->assemblies [entry.assembly_index].name;
|
||||
var module_token = entry.module_token;
|
||||
var token = entry.token;
|
||||
|
||||
#if LOG_TYPELOAD
|
||||
Console.WriteLine ($"ResolveFullTokenReference (0x{token_reference:X}) assembly name: {assembly_name} module token: 0x{module_token:X} token: 0x{token:X}.");
|
||||
|
@ -430,7 +436,7 @@ namespace ObjCRuntime {
|
|||
Console.WriteLine ($"ResolveTokenReference (0x{token_reference:X}) assembly index: {assembly_index} token: 0x{token:X}.");
|
||||
#endif
|
||||
|
||||
var assembly_name = Marshal.ReadIntPtr (map->assembly, (int) assembly_index * IntPtr.Size);
|
||||
var assembly_name = map->assemblies [(int) assembly_index].name;
|
||||
var assembly = ResolveAssembly (assembly_name);
|
||||
var module = ResolveModule (assembly, 0x1);
|
||||
|
||||
|
@ -474,7 +480,65 @@ namespace ObjCRuntime {
|
|||
throw ErrorHelper.CreateError (8020, $"Could not find the module with MetadataToken 0x{token:X} in the assembly {assembly}.");
|
||||
}
|
||||
|
||||
// Restrict this code to desktop for now, which is where most of the problems with outdated generated static registrar code occur.
|
||||
#if __MACOS__ || __MACCATALYST__
|
||||
static bool? verify_static_registrar_code;
|
||||
static object? verification_lock;
|
||||
static Dictionary<IntPtr, object?>? verified_assemblies; // Use Dictionary instead of HashSet to avoid pulling in System.Core.dll.
|
||||
unsafe static void VerifyStaticRegistrarCode (IntPtr assembly_name, Assembly assembly)
|
||||
{
|
||||
if (verify_static_registrar_code is null) {
|
||||
verify_static_registrar_code = !string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("XAMARIN_VALIDATE_STATIC_REGISTRAR_CODE"));
|
||||
verification_lock = new object ();
|
||||
}
|
||||
if (verify_static_registrar_code != true)
|
||||
return;
|
||||
|
||||
lock (verification_lock!) {
|
||||
if (verified_assemblies is null) {
|
||||
verified_assemblies = new Dictionary<IntPtr, object?> (Runtime.IntPtrEqualityComparer);
|
||||
} else if (verified_assemblies.ContainsKey (assembly_name)) {
|
||||
return;
|
||||
}
|
||||
verified_assemblies [assembly_name] = null;
|
||||
}
|
||||
|
||||
var map = Runtime.options->RegistrationMap;
|
||||
if (map is null)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < map->assembly_count; i++) {
|
||||
var entry = map->assemblies [i];
|
||||
var name = Marshal.PtrToStringAuto (entry.name)!;
|
||||
if (!Runtime.StringEquals (assembly_name, name))
|
||||
continue;
|
||||
try {
|
||||
var mvid = Marshal.PtrToStringAuto (entry.mvid)!;
|
||||
var runtime_mvid = assembly.ManifestModule.ModuleVersionId;
|
||||
var registered_mvid = Guid.Parse (mvid);
|
||||
if (registered_mvid == runtime_mvid)
|
||||
continue;
|
||||
throw ErrorHelper.CreateError (8044, Errors.MX8044 /* The assembly {0} has been modified since the app was built, invalidating the generated static registrar code. The MVID for the loaded assembly is {1}, while the MVID for the assembly the generated static registrar code corresponds to is {2}. */, name, runtime_mvid, registered_mvid);
|
||||
} catch (Exception e) {
|
||||
throw ErrorHelper.CreateError (8043, e, Errors.MX8043 /* An exception occurred while validating the static registrar code for {0}: {1} */, name, e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // __MACOS__ || __MACCATALYST__
|
||||
|
||||
static Assembly ResolveAssembly (IntPtr assembly_name)
|
||||
{
|
||||
if (TryResolveAssembly (assembly_name, out var asm)) {
|
||||
#if __MACOS__ || __MACCATALYST__
|
||||
VerifyStaticRegistrarCode (assembly_name, asm);
|
||||
#endif
|
||||
return asm;
|
||||
}
|
||||
|
||||
throw ErrorHelper.CreateError (8019, $"Could not find the assembly {Marshal.PtrToStringAuto (assembly_name)} in the loaded assemblies.");
|
||||
}
|
||||
|
||||
static bool TryResolveAssembly (IntPtr assembly_name, [NotNullWhen (true)] out Assembly? assembly)
|
||||
{
|
||||
// Find the assembly. We've already loaded all the assemblies that contain registered types, so just look at those assemblies.
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies ()) {
|
||||
|
@ -482,12 +546,14 @@ namespace ObjCRuntime {
|
|||
continue;
|
||||
|
||||
#if LOG_TYPELOAD
|
||||
Console.WriteLine ($"ResolveAssembly (0x{assembly_name:X}): {asm.FullName}.");
|
||||
Console.WriteLine ($"TryResolveAssembly (0x{assembly_name:X}): {asm.FullName}.");
|
||||
#endif
|
||||
return asm;
|
||||
assembly = asm;
|
||||
return true;
|
||||
}
|
||||
|
||||
throw ErrorHelper.CreateError (8019, $"Could not find the assembly {Marshal.PtrToStringAuto (assembly_name)} in the loaded assemblies.");
|
||||
assembly = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
internal unsafe static uint GetTokenReference (Type type, bool throw_exception = true)
|
||||
|
@ -514,7 +580,7 @@ namespace ObjCRuntime {
|
|||
// Find the assembly index in our list of registered assemblies.
|
||||
int assembly_index = -1;
|
||||
for (int i = 0; i < map->assembly_count; i++) {
|
||||
var name_ptr = Marshal.ReadIntPtr (map->assembly, (int) i * IntPtr.Size);
|
||||
var name_ptr = map->assemblies [(int) i].name;
|
||||
if (Runtime.StringEquals (name_ptr, asm_name)) {
|
||||
assembly_index = i;
|
||||
break;
|
||||
|
@ -542,15 +608,16 @@ namespace ObjCRuntime {
|
|||
{
|
||||
var map = Runtime.options->RegistrationMap;
|
||||
for (int i = 0; i < map->full_token_reference_count; i++) {
|
||||
var ptr = map->full_token_references + (i * (IntPtr.Size + 8));
|
||||
var asm_ptr = Marshal.ReadIntPtr (ptr);
|
||||
var token = Marshal.ReadInt32 (ptr + IntPtr.Size + 4);
|
||||
var ftr = map->full_token_references [i];
|
||||
var token = ftr.token;
|
||||
if (token != metadata_token)
|
||||
continue;
|
||||
var mod_token = Marshal.ReadInt32 (ptr + IntPtr.Size);
|
||||
var mod_token = ftr.module_token;
|
||||
if (mod_token != module_token)
|
||||
continue;
|
||||
if (!Runtime.StringEquals (asm_ptr, assembly_name))
|
||||
var assembly_index = ftr.assembly_index;
|
||||
var assembly = map->assemblies [assembly_index];
|
||||
if (!Runtime.StringEquals (assembly.name, assembly_name))
|
||||
continue;
|
||||
|
||||
return ((uint) i << 1) + 1;
|
||||
|
|
|
@ -419,6 +419,13 @@ namespace ObjCRuntime {
|
|||
if (obj == null)
|
||||
return;
|
||||
|
||||
var structType = obj.GetType ();
|
||||
// Unwrap enums, Marshal.StructureToPtr complains they're not blittable (https://github.com/xamarin/xamarin-macios/issues/15744)
|
||||
if (structType.IsEnum) {
|
||||
structType = Enum.GetUnderlyingType (structType);
|
||||
obj = Convert.ChangeType (obj, structType);
|
||||
}
|
||||
|
||||
if (obj is bool b) {
|
||||
// Only write a single byte for bools
|
||||
Marshal.WriteByte (ptr, b ? (byte) 1 : (byte) 0);
|
||||
|
|
|
@ -55,9 +55,9 @@ namespace ObjCRuntime {
|
|||
|
||||
#pragma warning disable 649 // Field 'X' is never assigned to, and will always have its default value
|
||||
internal unsafe struct MTRegistrationMap {
|
||||
public IntPtr assembly;
|
||||
public MTAssembly *assemblies;
|
||||
public MTClassMap *map;
|
||||
public IntPtr full_token_references; /* array of MTFullTokenReference */
|
||||
public MTFullTokenReference *full_token_references;
|
||||
public MTManagedClassMap* skipped_map;
|
||||
public MTProtocolWrapperMap* protocol_wrapper_map;
|
||||
public MTProtocolMap protocol_map;
|
||||
|
@ -78,6 +78,13 @@ namespace ObjCRuntime {
|
|||
UserType = 2,
|
||||
}
|
||||
|
||||
[StructLayout (LayoutKind.Sequential, Pack = 1)]
|
||||
internal unsafe struct MTFullTokenReference {
|
||||
public uint assembly_index;
|
||||
public uint module_token;
|
||||
public uint token;
|
||||
}
|
||||
|
||||
[StructLayout (LayoutKind.Sequential, Pack = 1)]
|
||||
internal struct MTClassMap {
|
||||
public IntPtr handle;
|
||||
|
@ -104,6 +111,12 @@ namespace ObjCRuntime {
|
|||
public IntPtr* protocols;
|
||||
}
|
||||
|
||||
[StructLayout (LayoutKind.Sequential, Pack = 1)]
|
||||
internal unsafe struct MTAssembly {
|
||||
public IntPtr name;
|
||||
public IntPtr mvid;
|
||||
}
|
||||
|
||||
/* Keep Delegates, Trampolines and InitializationOptions in sync with monotouch-glue.m */
|
||||
#pragma warning disable 649 // Field 'X' is never assigned to, and will always have its default value
|
||||
internal struct Trampolines {
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
#if !WATCH
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Foundation;
|
||||
using ObjCRuntime;
|
||||
using CoreGraphics;
|
||||
#nullable enable
|
||||
|
||||
namespace UIKit {
|
||||
|
||||
|
@ -41,9 +40,9 @@ namespace UIKit {
|
|||
{
|
||||
var copyOfRecognizers = recognizers;
|
||||
var savedHandle = Handle;
|
||||
recognizers = null;
|
||||
recognizers = new Dictionary<Token, IntPtr> ();
|
||||
|
||||
if (copyOfRecognizers == null)
|
||||
if (copyOfRecognizers.Count == 0)
|
||||
return;
|
||||
|
||||
DangerousRetain (savedHandle);
|
||||
|
@ -80,12 +79,12 @@ namespace UIKit {
|
|||
[Register ("__UIGestureRecognizerGenericCB")]
|
||||
internal class Callback<T> : Token where T: UIGestureRecognizer {
|
||||
Action<T> action;
|
||||
|
||||
|
||||
internal Callback (Action<T> action)
|
||||
{
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
|
||||
[Export ("target:")]
|
||||
[Preserve (Conditional = true)]
|
||||
public void Activated (T sender) => action (sender);
|
||||
|
@ -168,7 +167,10 @@ namespace UIKit {
|
|||
//
|
||||
public IEnumerable<Token> GetTargets ()
|
||||
{
|
||||
return (IEnumerable<Token>) recognizers?.Keys ?? Array.Empty<Token> ();
|
||||
var keys = recognizers?.Keys;
|
||||
if (keys is null)
|
||||
return Array.Empty<Token> ();
|
||||
return (IEnumerable<Token>) keys;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Foundation;
|
||||
using ObjCRuntime;
|
||||
|
||||
namespace MySimpleApp
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
static int Main (string[] args)
|
||||
{
|
||||
Console.WriteLine (Environment.GetEnvironmentVariable ("MAGIC_WORD"));
|
||||
|
||||
#if INCLUDED_ADDITIONAL_CODE
|
||||
GC.KeepAlive (typeof (AdditionalClass));
|
||||
#endif
|
||||
|
||||
return StaticRegistrarValidationTest ();
|
||||
}
|
||||
|
||||
static int StaticRegistrarValidationTest ()
|
||||
{
|
||||
try {
|
||||
using var obj = new SomeObj ();
|
||||
obj.Whatever ();
|
||||
xamarin_IntPtr_objc_msgSend_IntPtr_ref_IntPtr_exception (obj.Handle, Selector.GetHandle ("whatever"), IntPtr.Zero, IntPtr.Zero, out var gchandle);
|
||||
Console.WriteLine ($"GCH: {gchandle}");
|
||||
if (gchandle != IntPtr.Zero) {
|
||||
var gch = GCHandle.FromIntPtr (gchandle);
|
||||
var exc = (Exception) gch.Target;
|
||||
gch.Free ();
|
||||
throw exc;
|
||||
}
|
||||
return 1; // We're not supposed to get here
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine ($"E: {e}");
|
||||
if (e.Message.Contains ("The assembly MyRegistrarApp has been modified since the app was built, invalidating the generated static registrar code."))
|
||||
return 0;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport ("__Internal")]
|
||||
static extern IntPtr xamarin_IntPtr_objc_msgSend_IntPtr_ref_IntPtr_exception (IntPtr handle, IntPtr selector, IntPtr p0, IntPtr p1, out IntPtr gchandle);
|
||||
}
|
||||
|
||||
public class SomeObj : NSObject
|
||||
{
|
||||
[Export ("whatever")]
|
||||
public IntPtr Whatever ()
|
||||
{
|
||||
return new IntPtr (0xdeadf00d);
|
||||
}
|
||||
}
|
||||
|
||||
public class DeadClass {} // Some code for the linker to remove
|
||||
|
||||
#if INCLUDED_ADDITIONAL_CODE
|
||||
public class AdditionalClass {
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
include ../shared.mk
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-maccatalyst</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\shared.csproj" />
|
||||
</Project>
|
|
@ -0,0 +1,2 @@
|
|||
TOP=../../..
|
||||
include $(TOP)/tests/common/shared-dotnet-test.mk
|
|
@ -0,0 +1 @@
|
|||
include ../shared.mk
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-ios</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\shared.csproj" />
|
||||
</Project>
|
|
@ -0,0 +1 @@
|
|||
include ../shared.mk
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-macos</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\shared.csproj" />
|
||||
</Project>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
|
||||
<ApplicationTitle>MyRegistrarApp</ApplicationTitle>
|
||||
<ApplicationId>com.xamarin.myregistrarapp</ApplicationId>
|
||||
|
||||
<ExcludeNUnitLiteReference>true</ExcludeNUnitLiteReference>
|
||||
<ExcludeTouchUnitReference>true</ExcludeTouchUnitReference>
|
||||
|
||||
<DefineConstants>$(DefineConstants);$(AdditionalDefineConstants)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="../../common/shared-dotnet.csproj" />
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="../*.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,3 @@
|
|||
TOP=../../../..
|
||||
TESTNAME=MyRegistrarApp
|
||||
include $(TOP)/tests/common/shared-dotnet.mk
|
|
@ -0,0 +1 @@
|
|||
include ../shared.mk
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-tvos</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\shared.csproj" />
|
||||
</Project>
|
|
@ -34,7 +34,7 @@ class MainClass {
|
|||
|
||||
// Capture the current time
|
||||
var timestamp = DateTime.UtcNow;
|
||||
File.WriteAllText (mainFile, mainContents + "\n");
|
||||
File.WriteAllText (mainFile, mainContents);
|
||||
|
||||
// Build again
|
||||
rv = DotNet.AssertBuild (project_path, properties);
|
||||
|
|
|
@ -982,5 +982,19 @@ namespace Xamarin.Tests {
|
|||
Assert.That (errors [0].Message, Does.Contain ("Error loading Entitlements.plist template 'Entitlements.plist'"), "Message");
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase (ApplePlatform.MacOSX, "osx-arm64")]
|
||||
public void CustomAppBundleDir (ApplePlatform platform, string runtimeIdentifiers)
|
||||
{
|
||||
var project = "MySimpleApp";
|
||||
Configuration.IgnoreIfIgnoredPlatform (platform);
|
||||
|
||||
var project_path = GetProjectPath (project, runtimeIdentifiers: runtimeIdentifiers, platform: platform, out var appPath);
|
||||
Clean (project_path);
|
||||
var properties = GetDefaultProperties (runtimeIdentifiers);
|
||||
var customAppBundleDir = Path.Combine (Cache.CreateTemporaryDirectory (), project + ".app");
|
||||
properties ["AppBundleDir"] = customAppBundleDir;
|
||||
var result = DotNet.AssertBuild (project_path, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
namespace Xamarin.Tests {
|
||||
[TestFixture]
|
||||
public class RegistrarTest : TestBaseClass
|
||||
{
|
||||
[TestCase (ApplePlatform.MacCatalyst, true)]
|
||||
[TestCase (ApplePlatform.MacOSX, true)]
|
||||
[TestCase (ApplePlatform.iOS, false)]
|
||||
[TestCase (ApplePlatform.TVOS, false)]
|
||||
public void InvalidStaticRegistrarValidation (ApplePlatform platform, bool validated)
|
||||
{
|
||||
var project = "MyRegistrarApp";
|
||||
var configuration = "Debug";
|
||||
var runtimeIdentifiers = GetDefaultRuntimeIdentifier (platform);
|
||||
Configuration.IgnoreIfIgnoredPlatform (platform);
|
||||
|
||||
var projectPath = GetProjectPath (project, platform: platform);
|
||||
Clean (projectPath);
|
||||
var properties = GetDefaultProperties ();
|
||||
properties ["Registrar"] = "static";
|
||||
// enable the linker (so that the main assembly is modified)
|
||||
properties ["LinkMode"] = "full";
|
||||
properties ["MtouchLink"] = "full";
|
||||
|
||||
DotNet.AssertBuild (projectPath, properties);
|
||||
|
||||
var appDir = GetAppPath (projectPath, platform, runtimeIdentifiers, configuration);
|
||||
var asmDir = Path.Combine (appDir, GetRelativeAssemblyDirectory (platform));
|
||||
|
||||
var appExecutable = Path.Combine (asmDir, project + ".dll");
|
||||
|
||||
// Save the first version of the main assembly in memory
|
||||
var firstAssembly = File.ReadAllBytes (appExecutable);
|
||||
|
||||
// Build again, including additional code
|
||||
properties ["AdditionalDefineConstants"] = "INCLUDED_ADDITIONAL_CODE";
|
||||
DotNet.AssertBuild (projectPath, properties);
|
||||
|
||||
// Revert to the original version of the main assembly
|
||||
File.WriteAllBytes (appExecutable, firstAssembly);
|
||||
|
||||
Environment.SetEnvironmentVariable ("XAMARIN_VALIDATE_STATIC_REGISTRAR_CODE", "1");
|
||||
try {
|
||||
if (validated) {
|
||||
ExecuteProjectWithMagicWordAndAssert (projectPath, platform, runtimeIdentifiers);
|
||||
} else if (CanExecute (platform, runtimeIdentifiers)) {
|
||||
var rv = base.Execute (GetNativeExecutable (platform, appDir), out var output, out _);
|
||||
Assert.AreEqual (1, rv.ExitCode, "Expected no validation");
|
||||
}
|
||||
} finally {
|
||||
Environment.SetEnvironmentVariable ("XAMARIN_VALIDATE_STATIC_REGISTRAR_CODE", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -40,9 +40,24 @@ namespace Xamarin.Tests {
|
|||
}
|
||||
|
||||
protected string GetAppPath (string projectPath, ApplePlatform platform, string runtimeIdentifiers, string configuration = "Debug")
|
||||
{
|
||||
return Path.Combine (GetBinDir (projectPath, platform, runtimeIdentifiers, configuration), Path.GetFileNameWithoutExtension (projectPath) + ".app");
|
||||
}
|
||||
|
||||
protected string GetBinDir (string projectPath, ApplePlatform platform, string runtimeIdentifiers, string configuration = "Debug")
|
||||
{
|
||||
return GetBinOrObjDir ("bin", projectPath, platform, runtimeIdentifiers, configuration);
|
||||
}
|
||||
|
||||
protected string GetObjDir (string projectPath, ApplePlatform platform, string runtimeIdentifiers, string configuration = "Debug")
|
||||
{
|
||||
return GetBinOrObjDir ("obj", projectPath, platform, runtimeIdentifiers, configuration);
|
||||
}
|
||||
|
||||
protected string GetBinOrObjDir (string binOrObj, string projectPath, ApplePlatform platform, string runtimeIdentifiers, string configuration = "Debug")
|
||||
{
|
||||
var appPathRuntimeIdentifier = runtimeIdentifiers.IndexOf (';') >= 0 ? "" : runtimeIdentifiers;
|
||||
return Path.Combine (Path.GetDirectoryName (projectPath)!, "bin", configuration, platform.ToFramework (), appPathRuntimeIdentifier, Path.GetFileNameWithoutExtension (projectPath) + ".app");
|
||||
return Path.Combine (Path.GetDirectoryName (projectPath)!, binOrObj, configuration, platform.ToFramework (), appPathRuntimeIdentifier);
|
||||
}
|
||||
|
||||
protected string GetOutputPath (string project, string? subdir, string runtimeIdentifiers, ApplePlatform platform, string configuration = "Debug")
|
||||
|
@ -275,20 +290,25 @@ namespace Xamarin.Tests {
|
|||
}
|
||||
|
||||
protected void ExecuteWithMagicWordAndAssert (string executable)
|
||||
{
|
||||
var rv = Execute (executable, out var output, out string magicWord);
|
||||
Assert.That (output.ToString (), Does.Contain (magicWord), "Contains magic word");
|
||||
Assert.AreEqual (0, rv.ExitCode, "ExitCode");
|
||||
}
|
||||
|
||||
protected Execution Execute (string executable, out StringBuilder output, out string magicWord)
|
||||
{
|
||||
if (!File.Exists (executable))
|
||||
throw new FileNotFoundException ($"The executable '{executable}' does not exists.");
|
||||
|
||||
var magicWord = Guid.NewGuid ().ToString ();
|
||||
magicWord = Guid.NewGuid ().ToString ();
|
||||
var env = new Dictionary<string, string?> {
|
||||
{ "MAGIC_WORD", magicWord },
|
||||
{ "DYLD_FALLBACK_LIBRARY_PATH", null }, // VSMac might set this, which may cause tests to crash.
|
||||
};
|
||||
|
||||
var output = new StringBuilder ();
|
||||
var rv = Execution.RunWithStringBuildersAsync (executable, Array.Empty<string> (), environment: env, standardOutput: output, standardError: output, timeout: TimeSpan.FromSeconds (15)).Result;
|
||||
Assert.That (output.ToString (), Does.Contain (magicWord), "Contains magic word");
|
||||
Assert.AreEqual (0, rv.ExitCode, "ExitCode");
|
||||
output = new StringBuilder ();
|
||||
return Execution.RunWithStringBuildersAsync (executable, Array.Empty<string> (), environment: env, standardOutput: output, standardError: output, timeout: TimeSpan.FromSeconds (15)).Result;
|
||||
}
|
||||
|
||||
public static StringBuilder AssertExecute (string executable, params string[] arguments)
|
||||
|
|
|
@ -263,8 +263,23 @@ namespace ObjCRuntime
|
|||
|
||||
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
|
||||
public extern static void void_objc_msgSend_NSRange_out_NSRange_ref_NSRange (IntPtr receiver, IntPtr selector, _LongNSRange p1, out _LongNSRange p2, ref _LongNSRange p3);
|
||||
|
||||
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
|
||||
public extern static void void_objc_msgSend_ref_byte_ref_sbyte_ref_short_ref_ushort_ref_int_ref_uint_ref_long_ref_ulong (IntPtr receiver, IntPtr selector, ref EnumB b, ref EnumSB sb, ref EnumS s, ref EnumUS us, ref EnumI i, ref EnumUI ui, ref EnumL l, ref EnumUL ul);
|
||||
|
||||
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
|
||||
public extern static void void_objc_msgSend_out_byte_out_sbyte_out_short_out_ushort_out_int_out_uint_out_long_out_ulong (IntPtr receiver, IntPtr selector, out EnumB b, out EnumSB sb, out EnumS s, out EnumUS us, out EnumI i, out EnumUI ui, out EnumL l, out EnumUL ul);
|
||||
}
|
||||
|
||||
public enum EnumB : byte { a, b = 10 };
|
||||
public enum EnumSB : sbyte { a, b = 11 };
|
||||
public enum EnumS : short { a, b = 12 };
|
||||
public enum EnumUS : ushort { a, b = 13 };
|
||||
public enum EnumI : int { a, b = 14 };
|
||||
public enum EnumUI : uint { a, b = 15 };
|
||||
public enum EnumL : long { a, b = 16 };
|
||||
public enum EnumUL : ulong { a, b = 17 };
|
||||
|
||||
public struct _LongNSRange {
|
||||
public long Location;
|
||||
public long Length;
|
||||
|
|
|
@ -1694,21 +1694,38 @@ namespace MonoTouchFixtures.ObjCRuntime {
|
|||
}
|
||||
|
||||
[Register ("UnderlyingEnumValues")]
|
||||
class UnderlyingEnumValues : NSObject
|
||||
internal class UnderlyingEnumValues : NSObject
|
||||
{
|
||||
enum B : byte { a };
|
||||
enum SB : sbyte { a };
|
||||
enum S : short { a };
|
||||
enum US : ushort { a };
|
||||
enum I : int { a };
|
||||
enum UI : uint { a };
|
||||
enum L : long { a };
|
||||
enum UL : ulong { a };
|
||||
|
||||
[Export ("Foo:a:b:c:d:e:f:g:h")]
|
||||
void Foo (B b, SB sb, S s, US us, I i, UI ui, L l, UL ul)
|
||||
void Foo (EnumB b, EnumSB sb, EnumS s, EnumUS us, EnumI i, EnumUI ui, EnumL l, EnumUL ul)
|
||||
{
|
||||
}
|
||||
|
||||
[Export ("ByRef:a:b:c:d:e:f:g:")]
|
||||
void ByRef (ref EnumB b, ref EnumSB sb, ref EnumS s, ref EnumUS us, ref EnumI i, ref EnumUI ui, ref EnumL l, ref EnumUL ul)
|
||||
{
|
||||
b = EnumB.b;
|
||||
sb = EnumSB.b;
|
||||
s = EnumS.b;
|
||||
us = EnumUS.b;
|
||||
i = EnumI.b;
|
||||
ui = EnumUI.b;
|
||||
l = EnumL.b;
|
||||
ul = EnumUL.b;
|
||||
}
|
||||
|
||||
[Export ("Out:a:b:c:d:e:f:g:")]
|
||||
void Out (out EnumB b, out EnumSB sb, out EnumS s, out EnumUS us, out EnumI i, out EnumUI ui, out EnumL l, out EnumUL ul)
|
||||
{
|
||||
b = EnumB.b;
|
||||
sb = EnumSB.b;
|
||||
s = EnumS.b;
|
||||
us = EnumUS.b;
|
||||
i = EnumI.b;
|
||||
ui = EnumUI.b;
|
||||
l = EnumL.b;
|
||||
ul = EnumUL.b;
|
||||
}
|
||||
}
|
||||
|
||||
// It should be possible to export two identically named nested types.
|
||||
|
@ -5456,6 +5473,43 @@ namespace MonoTouchFixtures.ObjCRuntime {
|
|||
}
|
||||
}
|
||||
#endif // !__WATCHOS__ && !__TVOS__
|
||||
|
||||
[Test]
|
||||
public void RefEnumValues ()
|
||||
{
|
||||
EnumB b = 0;
|
||||
EnumSB sb = 0;
|
||||
EnumS s = 0;
|
||||
EnumUS us = 0;
|
||||
EnumI i = 0;
|
||||
EnumUI ui = 0;
|
||||
EnumL l = 0;
|
||||
EnumUL ul = 0;
|
||||
|
||||
using (var obj = new UnderlyingEnumValues ()) {
|
||||
b = 0; sb = 0; s = 0; us = 0; i = 0; ui = 0; l = 0; ul = 0;
|
||||
Messaging.void_objc_msgSend_ref_byte_ref_sbyte_ref_short_ref_ushort_ref_int_ref_uint_ref_long_ref_ulong (obj.Handle, Selector.GetHandle ("ByRef:a:b:c:d:e:f:g:"), ref b, ref sb, ref s, ref us, ref i, ref ui, ref l, ref ul);
|
||||
Assert.AreEqual (EnumB.b, b, "ref: B");
|
||||
Assert.AreEqual (EnumSB.b, sb, "ref: SB");
|
||||
Assert.AreEqual (EnumS.b, s, "ref: S");
|
||||
Assert.AreEqual (EnumUS.b, us, "ref: US");
|
||||
Assert.AreEqual (EnumI.b, i, "ref: I");
|
||||
Assert.AreEqual (EnumUI.b, ui, "ref: UI");
|
||||
Assert.AreEqual (EnumL.b, l, "ref: L");
|
||||
Assert.AreEqual (EnumUL.b, ul, "ref: UL");
|
||||
|
||||
b = 0; sb = 0; s = 0; us = 0; i = 0; ui = 0; l = 0; ul = 0;
|
||||
Messaging.void_objc_msgSend_out_byte_out_sbyte_out_short_out_ushort_out_int_out_uint_out_long_out_ulong (obj.Handle, Selector.GetHandle ("Out:a:b:c:d:e:f:g:"), out b, out sb, out s, out us, out i, out ui, out l, out ul);
|
||||
Assert.AreEqual (EnumB.b, b, "out: B");
|
||||
Assert.AreEqual (EnumSB.b, sb, "out: SB");
|
||||
Assert.AreEqual (EnumS.b, s, "out: S");
|
||||
Assert.AreEqual (EnumUS.b, us, "out: US");
|
||||
Assert.AreEqual (EnumI.b, i, "out: I");
|
||||
Assert.AreEqual (EnumUI.b, ui, "out: UI");
|
||||
Assert.AreEqual (EnumL.b, l, "out: L");
|
||||
Assert.AreEqual (EnumUL.b, ul, "out: UL");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !__WATCHOS__
|
||||
|
|
|
@ -2118,7 +2118,7 @@ namespace Registrar {
|
|||
|
||||
AutoIndentStringBuilder full_token_references = new AutoIndentStringBuilder ();
|
||||
uint full_token_reference_count;
|
||||
List<string> registered_assemblies = new List<string> ();
|
||||
List<(AssemblyDefinition Assembly, string Name)> registered_assemblies = new List<(AssemblyDefinition Assembly, string Name)> ();
|
||||
|
||||
bool IsPlatformType (TypeReference type)
|
||||
{
|
||||
|
@ -2853,9 +2853,9 @@ namespace Registrar {
|
|||
|
||||
if (string.IsNullOrEmpty (single_assembly)) {
|
||||
foreach (var assembly in GetAssemblies ())
|
||||
registered_assemblies.Add (GetAssemblyName (assembly));
|
||||
registered_assemblies.Add (new (assembly, GetAssemblyName (assembly)));
|
||||
} else {
|
||||
registered_assemblies.Add (single_assembly);
|
||||
registered_assemblies.Add (new (GetAssemblies ().Single (v => GetAssemblyName (v) == single_assembly), single_assembly));
|
||||
}
|
||||
|
||||
foreach (var @class in allTypes) {
|
||||
|
@ -3154,22 +3154,24 @@ namespace Registrar {
|
|||
map.AppendLine ();
|
||||
}
|
||||
|
||||
map.AppendLine ("static const char *__xamarin_registration_assemblies []= {");
|
||||
map.AppendLine ("static const MTAssembly __xamarin_registration_assemblies [] = {");
|
||||
int count = 0;
|
||||
foreach (var assembly in registered_assemblies) {
|
||||
count++;
|
||||
if (count > 1)
|
||||
map.AppendLine (", ");
|
||||
map.Append ("\"");
|
||||
map.Append (assembly);
|
||||
map.Append ("\"");
|
||||
map.Append ("{ \"");
|
||||
map.Append (assembly.Name);
|
||||
map.Append ("\", \"");
|
||||
map.Append (assembly.Assembly.MainModule.Mvid.ToString ());
|
||||
map.Append ("\" }");
|
||||
}
|
||||
map.AppendLine ();
|
||||
map.AppendLine ("};");
|
||||
map.AppendLine ();
|
||||
|
||||
if (full_token_reference_count > 0) {
|
||||
map.AppendLine ("static const struct MTFullTokenReference __xamarin_token_references [] = {");
|
||||
map.AppendLine ("static const MTFullTokenReference __xamarin_token_references [] = {");
|
||||
map.AppendLine (full_token_references);
|
||||
map.AppendLine ("};");
|
||||
map.AppendLine ();
|
||||
|
@ -4876,7 +4878,13 @@ namespace Registrar {
|
|||
default:
|
||||
throw ErrorHelper.CreateError (99, Errors.MX0099, $"unsupported tokentype ({member.MetadataToken.TokenType}) for {member.FullName}");
|
||||
}
|
||||
full_token_references.AppendFormat ("\t\t{{ /* #{3} = 0x{4:X} */ \"{0}\", 0x{1:X}, 0x{2:X} }},\n", GetAssemblyName (member.Module.Assembly), member.Module.MetadataToken.ToUInt32 (), member.MetadataToken.ToUInt32 (), full_token_reference_count, rv);
|
||||
var assemblyIndex = registered_assemblies.FindIndex (v => v.Assembly == member.Module.Assembly);
|
||||
var assemblyName = registered_assemblies [assemblyIndex].Name;
|
||||
var moduleToken = member.Module.MetadataToken.ToUInt32 ();
|
||||
var moduleName = member.Module.Name;
|
||||
var memberToken = member.MetadataToken.ToUInt32 ();
|
||||
var memberName = member.FullName;
|
||||
full_token_references.Append ($"\t\t{{ /* #{full_token_reference_count} = 0x{rv:X} */ {assemblyIndex} /* {assemblyName} */, 0x{moduleToken:X} /* {moduleName} */, 0x{memberToken:X} /* {memberName} */ }},\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -4908,7 +4916,7 @@ namespace Registrar {
|
|||
|
||||
/* The assembly must be a registered one, and only within the first 128 assemblies */
|
||||
var assembly_name = GetAssemblyName (member.Module.Assembly);
|
||||
var index = registered_assemblies.IndexOf (assembly_name);
|
||||
var index = registered_assemblies.FindIndex (v => v.Name == assembly_name);
|
||||
if (index < 0 || index > 127)
|
||||
return CreateFullTokenReference (member);
|
||||
|
||||
|
|
|
@ -140,22 +140,27 @@ Describe "TestResults tests" {
|
|||
New-Item -Path "$testDirectory/TestSummary-prefixintrospection-2" -Name "TestSummary.md" -Value "SummaryE" -Force
|
||||
New-Item -Path "$testDirectory/TestSummary-prefixmtouch-3" -Name "TestSummary.md" -Value "SummaryF" -Force
|
||||
|
||||
$labels = "linker;introspection".Split(";")
|
||||
$labels = @("linker", "introspection", "monotouch-test")
|
||||
$testResults = New-TestSummaryResults -Path "$testDirectory" -Labels $labels -TestPrefix "prefix"
|
||||
|
||||
Remove-Item -Path $testDirectory -Recurse
|
||||
|
||||
$testResults.count | Should -Be 2
|
||||
$testResults.count | Should -Be $labels.count
|
||||
|
||||
$testResults[0].Label | Should -Be "linker"
|
||||
$testResults[0].Context | Should -Be " - linker"
|
||||
$testResults[0].ResultsPath | Should -Be "$Env:PWD/subdir/TestSummary-prefixlinker-200/TestSummary.md"
|
||||
$testResults[0].ResultsPath | Should -Be "$(get-location)/subdir/TestSummary-prefixlinker-200/TestSummary.md"
|
||||
$testResults[0].TestsJobStatus | Should -Be "yay"
|
||||
|
||||
$testResults[1].Label | Should -Be "introspection"
|
||||
$testResults[1].Context | Should -Be " - introspection"
|
||||
$testResults[1].ResultsPath | Should -Be "$Env:PWD/subdir/TestSummary-prefixintrospection-2/TestSummary.md"
|
||||
$testResults[1].ResultsPath | Should -Be "$(get-location)/subdir/TestSummary-prefixintrospection-2/TestSummary.md"
|
||||
$testResults[1].TestsJobStatus | Should -Be "nay"
|
||||
|
||||
$testResults[2].Label | Should -Be "monotouch_test"
|
||||
$testResults[2].Context | Should -Be " - monotouch_test"
|
||||
$testResults[2].ResultsPath | Should -Be "./subdir/TestSummary-prefixmonotouch_test-1/TestSummary.md"
|
||||
$testResults[2].TestsJobStatus | Should -Be ""
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,14 +28,14 @@ class TestResults {
|
|||
}
|
||||
|
||||
[bool] IsSuccess() {
|
||||
Write-Debug "\t$($this.Label) - IsSuccess()"
|
||||
Write-Debug "`t$($this.Label) - IsSuccess()"
|
||||
if ($this.NotTestSummaryLabels.Contains($this.Label)) {
|
||||
Write-Debug "\t\t$($this.Label) - Found special label $($this.Label), checking only status."
|
||||
Write-Debug "`t`t$($this.Label) - Found special label $($this.Label), checking only status."
|
||||
return $this.TestsJobStatus -eq "Succeeded"
|
||||
} else {
|
||||
$hasResultsPath = Test-Path $this.ResultsPath -PathType Leaf
|
||||
Write-Debug "\t\t$($this.Label) - Path $($this.ResultsPath) exits? $hasResultsPath"
|
||||
Write-Debug "\t\t$($this.Label) - Test status: $($this.TestsJobStatus)"
|
||||
Write-Debug "`t`t$($this.Label) - Path $($this.ResultsPath) exists? $hasResultsPath"
|
||||
Write-Debug "`t`t$($this.Label) - Test status: $($this.TestsJobStatus)"
|
||||
return $hasResultsPath -and ($this.TestsJobStatus -eq "Succeeded")
|
||||
}
|
||||
}
|
||||
|
@ -91,13 +91,13 @@ class TestResults {
|
|||
[object] GetPassedTests() {
|
||||
Write-Debug "$($this.Label) - GetPassedTests()"
|
||||
if ($this.Passed -eq -1 -or $this.Failed -eq -1) {
|
||||
Write-Debug "\t$($this.Label) - Calculate results."
|
||||
Write-Debug "`t$($this.Label) - Calculate results."
|
||||
# the result file is diff if the result was a success or not
|
||||
if ($this.IsSuccess()) {
|
||||
Write-Debug "$($this.Label) - IsSuccess() => TRUE"
|
||||
Write-Debug "`t$($this.Label) - IsSuccess() => TRUE"
|
||||
$this.Failed = 0
|
||||
if ($this.NotTestSummaryLabels.Contains($this.Label)) {
|
||||
Write-Debug "\t\t$($this.Label) - Found special label $($this.Label), adding a single pass."
|
||||
Write-Debug "`t`t$($this.Label) - Found special label $($this.Label), adding a single pass."
|
||||
$this.Passed = 1
|
||||
} else {
|
||||
# in this case, the file contains a single line with the number and the following
|
||||
|
@ -106,27 +106,26 @@ class TestResults {
|
|||
$regexp = "(# :tada: All )(?<passed>[0-9]+)( tests passed :tada:)"
|
||||
$content = Get-Content $this.ResultsPath | Select -First 1
|
||||
if ($content -eq "# No tests selected.") {
|
||||
Write-Debug "\t\tNo tests selected"
|
||||
Write-Debug "`t`tNo tests selected"
|
||||
$this.Passed = 0
|
||||
} elseif ($content -match $regexp) {
|
||||
Write-Debug "Did match regexp"
|
||||
$this.Passed = $matches.passed -as [int]
|
||||
Write-Debug "Passed tests count: $($this.Passed)"
|
||||
Write-Debug "`tPassed tests count: $($this.Passed)"
|
||||
} else {
|
||||
throw "Unknown result pattern '$content'"
|
||||
throw "Unable to understand the test result '$content' for test '$($this.Label)'"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Debug "IsSuccess() => FALSE"
|
||||
Write-Debug "`t$($this.Label) - IsSuccess() => FALSE"
|
||||
$fileIsPresent = Test-Path $this.ResultsPath -PathType Leaf
|
||||
if ($this.TestsJobStatus -eq "" -or -not (Test-Path $this.ResultsPath -PathType Leaf)) {
|
||||
Write-Debug "\t\tTests job status: $($this.TestsJobStatus)"
|
||||
Write-Debug "\t\tNot Found results path: $fileIsPresent"
|
||||
Write-Debug "`t`tTests job status: $($this.TestsJobStatus)"
|
||||
Write-Debug "`t`tNot Found results path: $fileIsPresent"
|
||||
$this.Passed = -2
|
||||
$this.Failed = -2
|
||||
} else {
|
||||
if ($this.NotTestSummaryLabels.Contains($this.Label)) {
|
||||
Write-Debug "\t\tFound special label $($this.Label), adding a single fail."
|
||||
Write-Debug "`t`tFound special label $($this.Label), adding a single fail."
|
||||
$this.Passed = 0
|
||||
$this.Failed = 1
|
||||
} else {
|
||||
|
@ -160,20 +159,24 @@ class TestResults {
|
|||
# <summary>4 tests failed, 144 tests passed.</summary>
|
||||
$regexp = "(\<summary\>)(?<failed>[0-9]+)( tests failed, )(?<passed>[0-9]+)( tests passed\.\</summary\>)"
|
||||
if ($content -match $regexp) {
|
||||
Write-Debug "\t\tMatched regexpt."
|
||||
Write-Debug "`t`tMatched regexpt."
|
||||
$this.Passed = $matches.passed -as [int]
|
||||
$this.Failed = $matches.failed -as [int]
|
||||
Write-Debug "\t\tPassed: $($this.Passed) Failed: $($this.Failed)"
|
||||
} else {
|
||||
throw "Unknown result pattern '$content'"
|
||||
Write-Debug "`t`tAdding a single fail because unexpected <summary> contents found: $($content)"
|
||||
$this.Passed = 0
|
||||
$this.Failed = 1
|
||||
}
|
||||
} else {
|
||||
throw "Unknown result pattern of a failed test"
|
||||
Write-Debug "`t`tNo <summary> found, adding a single fail"
|
||||
$this.Passed = 0
|
||||
$this.Failed = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Debug "`t$($this.Label) - Passed: $($this.Passed) Failed: $($this.Failed)"
|
||||
return [PSCustomObject]@{
|
||||
Passed = $this.Passed
|
||||
Failed = $this.Failed
|
||||
|
@ -241,7 +244,7 @@ class ParallelTestsResults {
|
|||
}
|
||||
|
||||
# we return the patterns we already know
|
||||
if ($failedTests -eq 0) {
|
||||
if ($failedTests -eq 0 -and $crashedTests -eq 0) {
|
||||
return ":tada: All $passedTests tests passed :tada:"
|
||||
} else {
|
||||
return "$crashedTests tests crashed, $failedTests tests failed, $passedTests tests passed."
|
||||
|
@ -307,8 +310,8 @@ class ParallelTestsResults {
|
|||
} else {
|
||||
# create a detail per test result with the name of the test and will contain the exact summary
|
||||
$stringBuilder.AppendLine("<summary>$($result.Failed) tests failed, $($result.Passed) tests passed.</summary>")
|
||||
$stringBuilder.AppendLine("<details>")
|
||||
if (Test-Path -Path $r.ResultsPath -PathType Leaf) {
|
||||
$stringBuilder.AppendLine("<details>")
|
||||
$stringBuilder.AppendLine("")
|
||||
$foundTests = $false
|
||||
foreach ($line in Get-Content -Path $r.ResultsPath)
|
||||
|
@ -321,12 +324,8 @@ class ParallelTestsResults {
|
|||
}
|
||||
}
|
||||
}
|
||||
$stringBuilder.AppendLine("</details>")
|
||||
$stringBuilder.AppendLine("")
|
||||
} else {
|
||||
$stringBuilder.AppendLine("<details>")
|
||||
$stringBuilder.AppendLine(" Test has no summary file.")
|
||||
$stringBuilder.AppendLine("</details>")
|
||||
}
|
||||
$stringBuilder.AppendLine("</details>")
|
||||
$stringBuilder.AppendLine("")
|
||||
|
@ -402,7 +401,7 @@ function New-TestSummaryResults {
|
|||
$environmentVariable = "TESTS_JOBSTATUS_$($label.ToUpper())"
|
||||
$status = [Environment]::GetEnvironmentVariable($environmentVariable)
|
||||
|
||||
Write-Host "Test results for $label is '$status'"
|
||||
Write-Debug "Test results for $label is '$status'"
|
||||
|
||||
$testSummaryDirectoryExpression = "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY\Reports\TestSummary-$TestPrefix$label-*"
|
||||
|
||||
|
@ -411,7 +410,10 @@ function New-TestSummaryResults {
|
|||
$testSummaryDirectories = Get-ChildItem -Path $Path -Directory -Filter $directoryFilter
|
||||
|
||||
if ($testSummaryDirectories.length -eq 0) {
|
||||
Write-Host "WARNING: Found no directories matching $directoryFilter for label $label"
|
||||
Write-Debug "WARNING: Found no directories matching $directoryFilter for label $label and prefix $TestPrefix"
|
||||
$testSummaryPath = Join-Path $Path "TestSummary-$TestPrefix$label-1" "TestSummary.md"
|
||||
$result = New-TestResults -Path $testSummaryPath -Status $status -Label $label -Context "$Env:CONTEXT - $label" -Attempt 1
|
||||
$testResults += $result
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -436,10 +438,10 @@ function New-TestSummaryResults {
|
|||
$testAttemptPath = $testSummaryDirectory.Name
|
||||
$testSummaryPath = Join-Path $testAttemptPath "TestSummary.md"
|
||||
|
||||
Write-Host "Found "$attemptDirectories.count" directories, selected $testSummaryDirectory and final path is $testSummaryPath"
|
||||
Write-Debug "Found $($attemptDirectories.count) directories, selected $testSummaryDirectory and final path is $testSummaryPath"
|
||||
|
||||
if (-not (Test-Path -Path $testSummaryPath -PathType Leaf)) {
|
||||
Write-Host "WARNING: Path $testSummaryPath does not exist"
|
||||
Write-Debug "WARNING: Path $testSummaryPath does not exist"
|
||||
}
|
||||
|
||||
$result = New-TestResults -Path $testSummaryPath -Status $status -Label $label -Context "$Env:CONTEXT - $label" -Attempt $testAttempt
|
||||
|
|
|
@ -49,7 +49,7 @@ steps:
|
|||
inputs:
|
||||
dropServiceURI: 'https://devdiv.artifacts.visualstudio.com/DefaultCollection'
|
||||
dropMetadataContainerName: 'DropMetadata-ChangeDetection'
|
||||
buildNumber: 'xamarin-macios/detected-changes/$(Build.BuildNumber)/$(Build.BuildId)'
|
||||
buildNumber: 'xamarin-macios/detected-changes/$(Build.BuildNumber)/$(Build.BuildId)-$(System.JobAttempt)'
|
||||
sourcePath: '$(System.DefaultWorkingDirectory)/change-detection/results/'
|
||||
detailedLog: true
|
||||
usePat: true
|
||||
|
@ -57,7 +57,7 @@ steps:
|
|||
# Process the github comment and publish it
|
||||
- pwsh: |
|
||||
Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\MaciosCI.psd1
|
||||
$vsdropsChangeDetectionPrefix = "https://vsdrop.corp.microsoft.com/file/v1/xamarin-macios/detected-changes/$Env:BUILD_BUILDNUMBER/$Env:BUILD_BUILDID/;/"
|
||||
$vsdropsChangeDetectionPrefix = "https://vsdrop.corp.microsoft.com/file/v1/xamarin-macios/detected-changes/$Env:BUILD_BUILDNUMBER/$Env:BUILD_BUILDID-$Env:SYSTEM_JOBATTEMPT/;/"
|
||||
|
||||
$rootDirectory = Join-Path "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY" "change-detection" "results"
|
||||
|
||||
|
|
|
@ -19,6 +19,6 @@ steps:
|
|||
displayName: 'Publish Artifact: build-binlogs'
|
||||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)/build-binlogs
|
||||
artifactName: build-binlogs-$(Build.BuildId)
|
||||
artifactName: build-binlogs-$(Build.BuildId)-$(System.JobAttempt)
|
||||
continueOnError: true
|
||||
condition: and(succeededOrFailed(), contains(variables['configuration.BuildNugets'], 'True'))
|
||||
|
|
|
@ -49,24 +49,28 @@ steps:
|
|||
# build a message with all the content of all tests, to do so, we get the labels and to pass them to pwsh we do a join with ;
|
||||
# as the separator
|
||||
- pwsh: |
|
||||
$vsdropsIndex="$Env:VSDROPSPREFIX/$Env:BUILD_BUILDNUMBER/$Env:BUILD_BUILDID/"
|
||||
Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\MaciosCI.psd1
|
||||
$DebugPreference = "Continue" # enable debug messages
|
||||
try {
|
||||
$vsdropsIndex="$Env:VSDROPSPREFIX/$Env:BUILD_BUILDNUMBER/$Env:BUILD_BUILDID-$Env:SYSTEM_JOBATTEMPT/"
|
||||
Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\MaciosCI.psd1
|
||||
$DebugPreference = "Continue" # enable debug messages
|
||||
|
||||
$labels = "$Env:LABELS".Split(";")
|
||||
$labels = "$Env:LABELS".Split(";")
|
||||
|
||||
$testResults = New-TestSummaryResults -Path "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY\Reports" -Labels $labels -TestPrefix "${{ parameters.testPrefix }}"
|
||||
$testResults = New-TestSummaryResults -Path "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY\Reports" -Labels $labels -TestPrefix "${{ parameters.testPrefix }}"
|
||||
|
||||
$parallelResults = New-ParallelTestsResults -Results $testResults -Context "$Env:CONTEXT" -TestPrefix "${{ parameters.testPrefix }}" -VSDropsIndex $vsdropsIndex
|
||||
$success = $parallelResults.IsSuccess()
|
||||
$emoji = ":rocket:"
|
||||
if (-not $success) {
|
||||
Set-PipelineResult -Status partiallySucceeded
|
||||
$emoji = ":fire:"
|
||||
}
|
||||
$parallelResults = New-ParallelTestsResults -Results $testResults -Context "$Env:CONTEXT" -TestPrefix "${{ parameters.testPrefix }}" -VSDropsIndex $vsdropsIndex
|
||||
$success = $parallelResults.IsSuccess()
|
||||
$emoji = ":rocket:"
|
||||
if (-not $success) {
|
||||
Set-PipelineResult -Status partiallySucceeded
|
||||
$emoji = ":fire:"
|
||||
}
|
||||
|
||||
$gihubComments = New-GitHubCommentsObject -Org "xamarin" -Repo "xamarin-macios" -Token $Env:GITHUB_TOKEN -Hash $Env:GIT_HASH -Debug
|
||||
$result = $gihubComments.NewCommentFromObject("Test results", $emoji, $parallelResults)
|
||||
$gihubComments = New-GitHubCommentsObject -Org "xamarin" -Repo "xamarin-macios" -Token $Env:GITHUB_TOKEN -Hash $Env:GIT_HASH -Debug
|
||||
$result = $gihubComments.NewCommentFromObject("Test results", $emoji, $parallelResults)
|
||||
} catch {
|
||||
New-GitHubComment -Header "Failed to compute test summaries on $Env:CONTEXT" -Emoji ":fire:" -Description "Failed to compute test summaries: $_."
|
||||
}
|
||||
env:
|
||||
LABELS: ${{ join(';', parameters.simTestsConfigurations) }}
|
||||
BUILD_REVISION: $(Build.SourceVersion)
|
||||
|
|
|
@ -175,7 +175,7 @@ steps:
|
|||
echo "##vso[task.setvariable variable=TESTS_BOT;isOutput=true]$AGENT_NAME"
|
||||
|
||||
# uri used to create the vsdrops index using full uri
|
||||
export VSDROPS_URI="$VSDROPSPREFIX/$BUILD_BUILDNUMBER/$BUILD_BUILDID/$PARAMETERS_TESTPREFIX;/tests/"
|
||||
export VSDROPS_URI="$VSDROPSPREFIX/$BUILD_BUILDNUMBER/$BUILD_BUILDID-$SYSTEM_JOBATTEMPT/$PARAMETERS_TESTPREFIX;/tests/"
|
||||
|
||||
# assume something is going to fail
|
||||
echo "##vso[task.setvariable variable=TESTS_JOBSTATUS;isOutput=true]Failed"
|
||||
|
@ -218,7 +218,7 @@ steps:
|
|||
displayName: 'Publish Artifact: Simulator diagnostic info'
|
||||
inputs:
|
||||
targetPath: $(System.DefaultWorkingDirectory)/diagnostic-sim-output
|
||||
artifactName: diagnostic-simulator-info-$(Build.BuildId)-${{ parameters.label }}
|
||||
artifactName: diagnostic-simulator-info-$(Build.BuildId)-$(System.JobAttempt)-${{ parameters.label }}
|
||||
condition: and(eq(variables['system.debug'], true), succeededOrFailed())
|
||||
continueOnError: true
|
||||
|
||||
|
|
|
@ -4113,5 +4113,23 @@ namespace Xamarin.Bundler {
|
|||
return ResourceManager.GetString("MX8042", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An exception occurred while validating the static registrar code for {0}: {1}.
|
||||
/// </summary>
|
||||
public static string MX8043 {
|
||||
get {
|
||||
return ResourceManager.GetString("MX8043", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The assembly {0} has been modified since the app was built, invalidating the generated static registrar code. The MVID for the loaded assembly is {1}, while the MVID for the assembly the generated static registrar code corresponds to is {2}..
|
||||
/// </summary>
|
||||
public static string MX8044 {
|
||||
get {
|
||||
return ResourceManager.GetString("MX8044", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2171,4 +2171,16 @@
|
|||
1: exception info
|
||||
</comment>
|
||||
</data>
|
||||
|
||||
<data name="MX8043" xml:space="preserve">
|
||||
<value>An exception occurred while validating the static registrar code for {0}: {1}</value>
|
||||
<comment>
|
||||
0: name of an assembly
|
||||
1: exception info
|
||||
</comment>
|
||||
</data>
|
||||
|
||||
<data name="MX8044" xml:space="preserve">
|
||||
<value>The assembly {0} has been modified since the app was built, invalidating the generated static registrar code. The MVID for the loaded assembly is {1}, while the MVID for the assembly the generated static registrar code corresponds to is {2}.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
Загрузка…
Ссылка в новой задаче