* [net6] Fix ILStrip'ed apps to actually work again
- In a late minute change to the ILStrip PR (https://github.com/xamarin/xamarin-macios/pull/12563) a change to support XVS support broke execution of Apps that were stripped
- Applications were broken because none of the stripped assemblies were actually copied into the bundle
- However, the tests still passed, because all assemblies that were there had no IL (zero assemblies total)
Now why did this happen?
- The stripped assemblies were changed to return via an msbuild Output Element
- Output Element can return an Property or ItemGroup, depending if you use the PropertyName or ItemName attributes
- Unfortunately I used PropertyName, when I expected an ItemGroup. So I silently had a property created instead.
- Thus zero items were added to the list of files to copy into the bundle
- Which was undetected as the test did not confirm files were copied in, and manual tests were not run so late into the PR (3 weeks after PR was opened)
How was it fixed?
- Correctly using ItemName on Output created a valid item group to reference
- However, that still failed with an absurdly confusing error:
PATH/Microsoft.NET.Publish.targets(277,5): error MSB3024: Could not copy the file FILE to the destination file PATH, because the destination is a folder instead of a file. To copy the source file into a folder, consider using the DestinationFolder parameter instead of DestinationFiles.
- After a splunking through netcore targets, I found the metadata on these assemblies references really matters. Without it, they are not processed correctly at all.
- Thus, I updated ILStripBase to clone the existing metadata when changing the original assembly reference to the stripped path
- Finally, I corrected the test to assert that required files are copied in. I also manually ran our device test.
Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com>
* Subclass NativeObject to reuse object lifetime code. This isn't for CFType
itself, but all its subclasses.
* Add a public default constructor to maintain compat, but remove it for XAMCORE_4_0.
* Add an internal (IntPtr, bool) constructor to follow the NativeObject pattern.
* Enable nullability and fix code accordingly.
* Use CFString.CreateNative/ReleaseNative instead of other means to create
native strings (the fastest and least memory hungry option).
* Use 'nameof (parameter)' instead of string constants.
The deadlock goes like this:
1. Thread A holds the framework_peer_release_lock lock, and tries to lock the
refcount_mutex lock.
2. Thread B holds the refcount_mutex, and is waiting for the GC to complete
3. Thread C is trying to lock the framework_peer_release_lock while running
the GC.
The fix is in thread A, by not doing anything at all with the
framework_peer_release_lock lock locked.
The code contains extensive comments explaining the situation and the solution.
Fixes https://github.com/xamarin/xamarin-macios/issues/13066.
Co-authored-by: Chris Hamons <chris.hamons@xamarin.com>
* Subclass NativeObject to reuse object lifetime code.
* Enable nullability and fix code accordingly.
* Use 'is' and 'is not' instead of '==' and '!=' for object identity.
* Use CFString.CreateNative/ReleaseNative instead of other means to create native
strings (the fastest and least memory hungry option).
* Use 'nameof (parameter)' instead of string constants.
* Call 'GetCheckedHandle ()' (which will throw an ObjectDisposedException if
Handle == IntPtr.Zero) instead of manually checking for IntPtr.Zero and throwing
ObjectDisposedException.
* Use CFArray helper methods to create arrays (and implement some helper methods
that didn't exist).
* Add a few tests for the new CFArray helper methods.
* Don't execute .NET tests in the 'legacy' targets (it's wasteful because
we're already executing those .NET tests elsewhere).
* Fix reporting failures in the legacy tests.
This makes it easier to iterate over the platforms we're building for, because
we can use "macOS" to compute the variable names we're interested in (like we
already can for iOS, tvOS, watchOS and MacCatalyst).
* Create all INativeObject subclasses using 'Runtime.GetINativeObject<T>' instead
of 'new T ()'. Although it's somewhat slower, it automatically handles any IntPtr.Zero
handles, and it also makes the generator code simpler. If something turns out to
be a performance problem, we can always add custom static creation methods (like
some of the existing types already have).
* This makes it so that the zero pointer check logic in the generator isn't necessary
anymore.
* The most important part is where we use IntPtr as the marshalling type for returned
INativeObjects in blocks (instead of the INativeObject class - which doesn't make
sense really, because I have no idea how that's marshalled).
Example:
```diff
diff --git a/build/dotnet/ios/generated-sources/ObjCRuntime/Trampolines.g.cs b/build-new/dotnet/ios/generated-sources/ObjCRuntime/Trampolines.g.cs
index 97e58f3a91b..8a40748de8b 100644
--- a/build/dotnet/ios/generated-sources/ObjCRuntime/Trampolines.g.cs
+++ b/build-new/dotnet/ios/generated-sources/ObjCRuntime/Trampolines.g.cs
@@ -214,7 +214,7 @@ namespace ObjCRuntime {
} /* class NIDAVAudioEngineManualRenderingBlock */
[UnmanagedFunctionPointerAttribute (CallingConvention.Cdecl)]
[UserDelegateType (typeof (global::AVFoundation.AVAudioIONodeInputBlock))]
- internal delegate global::AudioToolbox.AudioBuffers DAVAudioIONodeInputBlock (IntPtr block, uint frameCount);
+ internal delegate IntPtr DAVAudioIONodeInputBlock (IntPtr block, uint frameCount);
//
// This class bridges native block invocations that call into C#
//
@@ -223,11 +223,11 @@ namespace ObjCRuntime {
[Preserve (Conditional = true)]
[global::System.Diagnostics.CodeAnalysis.DynamicDependency ("Handler")]
[MonoPInvokeCallback (typeof (DAVAudioIONodeInputBlock))]
- static unsafe global::AudioToolbox.AudioBuffers Invoke (IntPtr block, uint frameCount) {
+ static unsafe IntPtr Invoke (IntPtr block, uint frameCount) {
var descriptor = (BlockLiteral *) block;
var del = (global::AVFoundation.AVAudioIONodeInputBlock) (descriptor->Target);
AudioToolbox.AudioBuffers retval = del (frameCount);
- return retval;
+ return retval.GetHandle ();
}
} /* class SDAVAudioIONodeInputBlock */
internal sealed class NIDAVAudioIONodeInputBlock : TrampolineBlockBase {
@@ -249,7 +249,7 @@ namespace ObjCRuntime {
[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
unsafe global::AudioToolbox.AudioBuffers Invoke (uint frameCount)
{
- var ret = invoker (BlockPointer, frameCount);
+ var ret = Runtime.GetINativeObject<global::AudioToolbox.AudioBuffers> (invoker (BlockPointer, frameCount), false);
return ret!;
}
} /* class NIDAVAudioIONodeInputBlock */
```
* Add an (IntPtr, bool) constructor so that AudioUnit works with Runtime.GetINativeObject.
* Keep track of ownership, so that AudioUnit doesn't free the native resources
when it doesn't own them.
* Update a test to verify that calling 'AVAudioIONode.AudioUnit' multiple
times and disposing the result between them works (this fails if AudioUnit
doesn't keep track of ownership).
Now that macOS runs on ARM64 (and also the simulators soon), we need to have to same logic for all platforms.
Fixes:
Introspection.iOSApiPInvokeTest
[FAIL] Could not find the field 'objc_msgSend_stret' in /usr/lib/libobjc.dylib
[FAIL] Could not find the field 'objc_msgSendSuper_stret' in /usr/lib/libobjc.dylib
[FAIL] SymbolExists : 2 errors found in 5300 functions validated: objc_msgSend_stret, objc_msgSendSuper_stret
Expected: 0
But was: 2
at Introspection.ApiPInvokeTest.SymbolExists() in /Users/builder/azdo/_work/1/s/xamarin-macios/tests/introspection/ApiPInvokeTest.cs:line 182
Fixes this when running our test suites on macOS 10.14:
dyld: Library not loaded: /System/Library/Frameworks/AuthenticationServices.framework/Versions/A/AuthenticationServices
Referenced from: /Users/runner/work/1/s/artifacts/mac-test-package/tests/./introspection/dotnet/macOS/bin/Debug/net6.0-macos/osx-x64/introspection.app/Contents/MacOS/introspection
Reason: image not found
make[2]: *** [exec-mac-dotnet-x64-introspection] Abort trap: 6
I recently deleted the generated makefile support for building and running our
test suites. It turned out that it was used for building the packaged
Xamarin.Mac tests, so it wasn't as unused as I thought.
So fix the building and packaging of Xamarin.Mac tests to not use the
(non-existent) makefile targets, but instead replicate it with manual make
code.
Also take the opportunity to add packaging and execution of the .NET versions
of these test suites we execute on other macOS versions (both for macOS and
the Mac Catalyst).
* [devops] Use stricter matching when finding the Xamarin.Mac pkg link.
Otherwise the branch name in any package could end up matching the pattern we
were looking for:
XM_PACKAGE=https://bosstoragemirror.blob.core.windows.net/wrench/tests-package-xamarin-mac-tests/15759261d425ae08494b0a26862a0b1356c5f8ec/5268864/package/Microsoft.iOS.Bundle.15.0.101-ci.tests-package-xamarin-mac-tests.68.pkg
is just clearly wrong.
This fixes a problem where the build from the different projects could stomp
on eachother in the obj/bin folders. It's technically possible to make this
work by setting up custom [Base][Intermediate][OutputPath] properties in the
project files, but the simplest solution is to just make sure there's no more
than a single project per directory.
Add support for 'dotnet pack', by:
1. Add a workaround for the fact that as soon as a project has a
'NativeReference' item, .NET's MSBuild logic wants to include a
'Native.$(AssemblyName).manifest' file in the NuGet. This obviously breaks,
because we don't create such a file, so we work around it by removing the
file in question from the corresponding item groups.
2. Add any binding resource packages to the NuGet.
3. Add tests.
Fixes https://github.com/xamarin/xamarin-macios/issues/12631.