This makes the linker able to trim away a few methods that aren't trim-safe
when using the managed static registrar (and thus not warn about these methods
doing un-trimmable stuff).
Contributes towards #10405.
Fixes https://github.com/xamarin/xamarin-macios/issues/18968
We provide a mapping to the checked in source files via SourceLink.json
and the rest of the generated/untracked sources are embedded into the
PDB to provide a more comprehensive debugging experience. Since we
invoke CSC directly, there were a few workarounds that had to be
implemented (ex: implementing a helper script to account for untracked
sources instead of simply using the EmbedUntrackedSources MSBuild
property).
As for testing, the newly added support was validated via the dotnet
sourcelink tool which confirmed all the sources in the PDB either had
valid urls or were embedded.
`sourcelink test Microsoft.MacCatalyst.pdb` —> `sourcelink test passed:
Microsoft.MacCatalyst.pdb`
The PDB size does increase in size after embedding;
Microsoft.MacCatalyst.pdb went from 5 MB to 15.7 MB.
But considering it would significantly help improve the debugging
experience, be consistent with Android’s offerings, and it’s a
highlighted attribute on the NuGet package explorer I think it’s a
worthy size increase.
Refs:
https://github.com/xamarin/xamarin-android/pull/7298https://github.com/dotnet/roslyn/issues/12625https://github.com/dotnet/sourcelink/tree/main/docs
---------
Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com>
Co-authored-by: Alex Soto <alex@alexsoto.me>
Co-authored-by: Michael Cummings (MSFT) <mcumming@microsoft.com>
Co-authored-by: GitHub Actions Autoformatter <github-actions-autoformatter@xamarin.com>
It'll never be called from the generated code from the managed static
registrar, so there's no need to register it as a potential callback from
native code.
This makes the linker able to remove the Runtime.CreateDelegateProxy method
(and a few other methods as well) when using the managed static registrar (and
thus not warn about these methods doing un-trimmable stuff).
Contributes towards #10405.
If a project tried to use a .NET 6 project (say TargetFramework=net6.0-ios), then
we used to show these rather unhelpful errors:
error NETSDK1147: To build this project, the following workloads must be installed: wasm-tools-net6
error NETSDK1147: To install these workloads, run the following command: dotnet workload restore
The underlying problem is that we don't support .NET 6 anymore, so with this fix we now show:
error NETSDK1202: The workload 'net6.0-ios' is out of support and will not receive security updates in the future. Please refer to https://aka.ms/maui-support-policy for more information about the support policy.
which is much more helpful.
References:
* https://github.com/dotnet/sdk/pull/32426
* https://github.com/xamarin/xamarin-android/pull/8047
Fixes https://github.com/xamarin/xamarin-macios/issues/18790.
It'll never be called from the generated code from the managed static
registrar, so there's no need to register it as a potential callback from
native code.
This makes the linker able to remove the Runtime.GetGenericMethodFromToken
method (and a few other methods as well).
Contributes towards #10405.
Two changes:
1. Fix the tests by not using the Configuration.SourceRoot property. There is a bug in that code that returns diff paths in some bots.
2. Use Assert.Multiple for better error formatting.
---------
Co-authored-by: GitHub Actions Autoformatter <github-actions-autoformatter@xamarin.com>
By default, the build will just continue if a remote connection couldn't be
established. For tests that require a remote connection, this often results in
weird errors later on in the build, so improve this by immediately verifying
that we were able to establish a remote connection and telling the developer
where to look for more information.
---------
Co-authored-by: Alex Soto <alex@alexsoto.me>
We've used to ignore the target platform version (the "17.0" part in "net8.0-ios17.0")
since our initial .NET relaese - customers could specify any valid OS version between
the minimum and maximum versions, and we'd completely ignore the value [1].
The purpose of the target platform version is to specify which bindings to choose:
"net8.0-ios17.0" would mean that the developer wants packages that have bindings
for iOS 17.0 (and earlier iOS versions, but not later iOS versions).
So saying "net8.0-ios11.0" would technically mean that the developer would want our
bindings for iOS 11.0 (and earlier iOS versions, but not later iOS versions). The
problem is that we don't ship any such thing... we shipped iOS 17.0 bindings in .NET
8, and that's it, you can't choose to build with something that does *not* have bindings
for iOS 17.0.
This will change with multi-targeting: we'll support *some* matrix of bindings. For
instance, we might want to support the OS version we shipped initial support in any
given .NET release + the latest OS version.
For example, we might want to support both of these:
* net8.0-ios17.0
* net8.0-ios17.2
This means that the target platform version (17.0/17.2) can't keep staying ignored.
There was an somewhat related issue with the `SdkSupportedTargetPlatformVersion`,
where we're now able to distinguish between old versions we no longer support and
new versions that limits the valid values for TargetPlatformVersion (see 74d83ca7e3).
We've already taken advantage of this to properly annotate every version, even in
.NET 8 (in a future service update), because the dotnet/sdk change required to understand
the new annotations (and ignore old versions in the `SdkSupportedTargetPlatformVersion`
item group) won't be shipped until .NET 9, so this won't be a breaking change in
.NET 8.
However, we'd still like to give customers a heads up that their project files need
to change, so this PR adds a warning (that tells developers what to do), and then
in .NET 9 we'll make the warning an error instead. Side note: Android is also making
an invalid target platform version an error in .NET 9: https://github.com/xamarin/xamarin-android/pull/8569.
[1]: We'd ignore the value for executable projects. It did have an effect for library
projects that were packed into NuGets: the target platform version would be stored
in the NuGet.
This is because it doesn't work on arm64 - it's trying to verify that we
handle a specific error condition gracefully, but we're rather evil in trying
to trigger the error condition (being kind doesn't trigger the error), and the
AOT compiler detects the same thing we do and errors out before we get a
chance to show our nice error.
In short: make this an x64-only test.
This is a manual and squashed backport of
https://github.com/xamarin/xamarin-macios/pull/19717 and it was updated
to use Xcode 15.2 since Xcode 15.2 contains the same SDKs as Xcode 15.1
but Xcode 15.2 has visionOS SDK and it is the new stable release from
Apple.
---------
Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com>
In theory we should define the default platform version if it's not specified
in the TFM, and this default should not change for a given .NET version:
* We release support for iOS 17.0 with .NET 8
* Apple releases iOS 18.0, we're still using .NET 8. This default continues to be iOS 17.0
* .NET 9 is shipped, and at this point we bump the default to iOS 18.0
Basically: this should be the last OS version of the platform in question when
the current major .NET version is first released to stable.
Ref: 8e6394406d/accepted/2020/net5/net5.md (os-versions)
However, this doesn't work well for Apple platforms: whenever Apple releases
new Xcode versions, our existing workloads might not be compatible with the
new Xcode. We'll of course ship updateds workload with support for the new
Xcode, but defaulting to an older target platform version would mean that
developers wouldn't get the new workload, they'd get the old one. This is
exacerbated by the fact that Apple aggressively auto-updates Xcode on
developers' machines: they might wake up one day to a broken build - the
obvious fix ("dotnet workload update") doesn't fix anything - even if we've
shipped updated workloads - because the default is to use the old one. They'd
have to manually specify the target platform version in the target platform to
get the updated workload ("net8.0-ios17.2" to use the iOS 17.2 workload
instead of "net8.0-ios", which would use the default (old/initial/17.0) .NET 8
workload) - and then update _again_ when the next Xcode comes around. At this
point the point of having a sane default value is totally out the window,
because everybody would have to specify (and continuously update) a platform
version in their project files to keep their projects building.
So we've made the decision that the default target platform version is always
the latest target platform version.
It seems targets are ran in a different order in .NET 9, which means that we
ran into a different one that the one we expected. So fix that error, which
means we're now getting the error the test is checking for again.
Fixes:
Xamarin.Tests.DotNetProjectTest.InvalidArchProperty(TVOS,"MtouchArch","arm64"): Error count
Expected: 1
But was: 2
Xamarin.Tests.DotNetProjectTest.InvalidArchProperty(MacCatalyst,"MtouchArch","x64"): Error count
Expected: 1
But was: 2
Xamarin.Tests.DotNetProjectTest.InvalidArchProperty(MacOSX,"XamMacArch","x64"): Error message
Expected string length 172 but was 50. Strings differ at index 0.
Expected: "The property 'XamMacArch' is deprecated, please remove it fro..."
But was: "Could not parse TargetArchitectures 'x64'\n "
-----------^
Xamarin.Tests.DotNetProjectTest.InvalidArchProperty(iOS,"MtouchArch","armv7s"): Error count
Expected: 1
But was: 2
Also improve error reporting a bit.
Closes#19505
We transform `[Preserve(AllMembers = true)]` into
`[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(T))]`.
There is difference between which members are preserved in these two
cases. The `DynamicallyAccessedMemberTypes.All` preserves many more,
especially nested types and their members. This manifested with the
`IL3050` AOT analysis warning we got from ILC when building any app:
1. `NSObject_Disposer` has `[Preserve(AllMembers = true)]`
2. `NSObject_Disposer` is a subclass of NSObject
3. `NSObject` has nested enums `Flags` and `XamarinGCHandleFlags`
4. the base class `Enum` has a public static method `GetValues(Type)`
5. the `GetValues` method is annotated with `RequiresDynamicCode` and
ILC produces a warning because even though it isn't used anywhere in the
codebase, it could be used via reflection
I changed two things when transforming Preserve:
- For enums, we only need to preserve public fields. We especially want
to avoid `PublicMethods` since that would preserve public methods in the
base class which includes the `GetValues(Type)` method.
- For other types, I list explicitly the member types that should be
preserved instead of using `All`.
- The code is verbose, but in the end, I chose the explicit list instead
of `All ^ PublicNestedTypes ^ NonPublicNestedTypes` since that would
automatically include any new flag added to the enum in the future.
The ResolveNativeReferences task would incorrectly set Kind=Framework for static
libraries and dylibs if these files came from an XCFramework in the runtimes/native
directory in a NuGet (as opposed to a binding project, or the NuGet built from a
binding project).
Fix this by properly assigning the Kind and PublishFolderType metadata for such static
libraries and dylibs.
Also add a test.
When migrating Xamarin projects to .NET projects, somewhat frequently people
will leave the MtouchArch/XamMacArch properties in their project files with
old values. This won't work, since we use RuntimeIdentifier(s) now to control
the target architecture, so remove support for MtouchArch/XamMacArch, and show
an error if we detect that they're set.
This will hopefully prevent some really confusing problems, especially in the IDEs.
Example: https://github.com/xamarin/xamarin-macios/issues/19258
Fixed an issue where the C# class name was coming in with `,
AssemblyName` tacked on the end.
Fixed an issue where a class that had an entry in the map didn't have a
`class_ptr` which was causing an NRE.
Fixed a predicate for deciding when to mark the assembly for save.
Note - for an as yet undetermined reason, the linker is not picking up
that I'm marking the assembly for save, which is why the `true` test
cases are commented out.
This fixes issue 16671 https://github.com/xamarin/xamarin-macios/issues/16671
ILLink doesn't handle library projects the way we need: the library is
automatically treated as a root assembly, with the entry point as the root.
This doesn't work, because library projects don't have an entry point.
In earlier versions of .NET (and Xamarin), we'd solved this by a custom linker
step that would manually root everything that needed to be rooted, but that
doesn't work anymore because we hit this sanity check in ILLink:
> ILLink : error IL1034: Root assembly 'MyExtension, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have entry point.
Technically this happens because the library project is configured as a root
assembly, where the entry point is the root point (and in that regards the
sanity check is rather sane).
The best solution would be if we could just treat the library assembly as any
other assembly, and manually root it in our custom linker steps - but the
custom linker step we have for this kind of rooting will only iterate over
types in assemblies that are already marked somehow, and that's not
necessarily the case for app extension projects - the end result is that the
entire app extension assembly is linked away.
A close runner-up as the second best solution is to provide the API that needs
to be rooted as an xml file to the linker. This works, but we currently don't
have the infrastructure in the code to generate this xml file before running
the linker (it would be a rather major undertaking). This work is tentatively
scheduled for .NET 9 (https://github.com/xamarin/xamarin-macios/issues/17693).
So I went for the third option: set RootMode="Library" for the library
assembly. I'm not sure exactly what that means ILLink will mark, but as long
as _anything_ is marked, our custom linker step will run. This seems like an
acceptable workaround until we can implement the previous solution.
Fixes https://github.com/xamarin/xamarin-macios/issues/19037.
This pull request updates the following dependencies
## From https://github.com/dotnet/installer
- **Subscription**: f9b68d84-9c90-4bd0-5499-08db4112d57e
- **Build**: 20230918.1
- **Date Produced**: September 18, 2023 11:00:22 AM UTC
- **Commit**: e1fd7d964980ed478fa30457cf750e81105caee1
- **Branch**: refs/heads/release/8.0.1xx
- **Updates**:
- **Microsoft.Dotnet.Sdk.Internal**: [from 8.0.100-rc.2.23463.8 to 8.0.100-rc.2.23468.1][12]
- **Microsoft.NET.ILLink.Tasks**: [from 8.0.0-rc.2.23431.9 to 8.0.0-rc.2.23466.4][13]
- **Microsoft.AspNetCore.App.Ref**: [from 8.0.0-rc.2.23455.8 to 8.0.0-rc.2.23465.17][14]
- **Microsoft.NETCore.App.Ref**: [from 8.0.0-rc.2.23431.9 to 8.0.0-rc.2.23466.4][13]
- **Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport**: [from 8.0.0-rc.1.23415.5 to 8.0.0-rc.2.23463.1][15]
- **Microsoft.NETCore.App.Ref**: [from 8.0.0-rc.2.23431.9 to 8.0.0-rc.2.23466.4][13]
- **Microsoft.DotNet.Cecil**: [from 0.11.4-alpha.23428.2 to 0.11.4-alpha.23461.1][16]
[12]: ec56994f9c...e1fd7d9649
[13]: 3c48925a6c...287c10d253
[14]: 2772a78349...468ff785bc
[15]: 66dbaefff0...1999c8c8ab
[16]: fa5acbd2cc...a112f15aa0
## Coherency Updates
The following updates ensure that dependencies with a *CoherentParentDependency*
attribute were produced in a build used as input to the parent dependency's build.
See [Dependency Description Format](https://github.com/dotnet/arcade/blob/master/Documentation/DependencyDescriptionFormat.md#dependency-description-overview)
- **Coherency Updates**:
- **Microsoft.NET.ILLink.Tasks**: from 8.0.0-rc.2.23431.9 to 8.0.0-rc.2.23466.4 (parent: Microsoft.Dotnet.Sdk.Internal)
- **Microsoft.AspNetCore.App.Ref**: from 8.0.0-rc.2.23455.8 to 8.0.0-rc.2.23465.17 (parent: Microsoft.Dotnet.Sdk.Internal)
- **Microsoft.NETCore.App.Ref**: from 8.0.0-rc.2.23431.9 to 8.0.0-rc.2.23466.4 (parent: Microsoft.Dotnet.Sdk.Internal)
- **Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport**: from 8.0.0-rc.1.23415.5 to 8.0.0-rc.2.23463.1 (parent: Microsoft.NETCore.App.Ref)
- **Microsoft.NETCore.App.Ref**: from 8.0.0-rc.2.23431.9 to 8.0.0-rc.2.23466.4 (parent: Microsoft.Dotnet.Sdk.Internal)
- **Microsoft.DotNet.Cecil**: from 0.11.4-alpha.23428.2 to 0.11.4-alpha.23461.1 (parent: Microsoft.NETCore.App.Ref)
With multi-targeting, we can end up supporting a newer target framework than
the current one (when including support for preview versions of Xcode), but we
can't build Mac Catalyst projects using these newer target frameworks, because
it would require using the corresponding Xcode version, which may not be
available (in particular on bots).
Fixes these test failures:
Xamarin.Tests.DotNetProjectTest.MultiTargetLibrary(MacCatalyst): 'dotnet build' failed with exit code 1
Full command: /Users/builder/azdo/_work/2/s/xamarin-macios/builds/downloads/dotnet-sdk-8.0.100-rc.1.23422.1/dotnet build /Users/builder/azdo/_work/2/s/xamarin-macios/tests/dotnet/MultiTargetingLibrary/MacCatalyst/MultiTargetingLibrary.csproj /p:_BundlerVerbosity=1 "/p:AllTheTargetFrameworks=\"net8.0-maccatalyst16.4;net7.0-maccatalyst15.4;net7.0-maccatalyst16.4;net8.0-maccatalyst17.0\"" /bl:/Users/builder/azdo/_work/2/s/xamarin-macios/tests/dotnet/MultiTargetingLibrary/MacCatalyst/log-build-20230912_200113.binlog /v:diag /consoleloggerparameters:Verbosity=Quiet
Listing first 1 error(s) (of 1 error(s)):
/Users/builder/azdo/_work/2/s/xamarin-macios/builds/downloads/dotnet-sdk-8.0.100-rc.1.23422.1/packs/Microsoft.MacCatalyst.Sdk.net8.0_17.0/17.0.8316-ci.release-test-net8-0-xcode15-multi-targeting/tools/msbuild/iOS/Xamarin.Shared.targets(535): error: Could not map the Mac Catalyst version 17.0 to a corresponding macOS version. Valid Mac Catalyst versions are: 15.0, 13.3.1, 16.2, 14.3, 15.5, 13.1, 16.0, 14.1, 15.3, 14.6, 13.4, 16.3, 15.6, 13.2, 14.4, 16.1, 14.2, 15.4, 13.5, 14.7, 15.2, 14.0, 16.4, 13.3, 14.5
Xamarin.Tests.PostBuildTest.PublishTest(MacCatalyst,"maccatalyst-arm64;maccatalyst-x64"): 'dotnet publish' failed with exit code 1
Full command: /Users/builder/azdo/_work/2/s/xamarin-macios/builds/downloads/dotnet-sdk-8.0.100-rc.1.23422.1/dotnet publish /Users/builder/azdo/_work/2/s/xamarin-macios/tests/dotnet/MySimpleApp/MacCatalyst/MySimpleApp.csproj /p:_BundlerVerbosity=1 "/p:RuntimeIdentifiers=\"maccatalyst-arm64;maccatalyst-x64\"" /p:PkgPackagePath=/Users/builder/azdo/_work/2/s/xamarin-macios/tests/dotnet/UnitTests/bin/Debug/net8.0/tmp-test-dir/Xamarin.Tests.PostBuildTest.PublishTest27/MyPackage.pkg /bl:/Users/builder/azdo/_work/2/s/xamarin-macios/tests/dotnet/MySimpleApp/MacCatalyst/log-publish-20230912_204753.binlog /v:diag /consoleloggerparameters:Verbosity=Quiet
Listing first 1 error(s) (of 1 error(s)):
/Users/builder/azdo/_work/2/s/xamarin-macios/builds/downloads/dotnet-sdk-8.0.100-rc.1.23422.1/sdk-manifests/8.0.100-rc.1/microsoft.net.workload.mono.toolchain.current/8.0.0-rc.1.23414.4/WorkloadTelemetry.targets(41): error MSB4186: Invalid static method invocation syntax: "[System.IO.Path]::GetFileName().ToLower()". Method 'System.IO.Path.GetFileName' not found. Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(`a`, `b`)). Check that all parameters are defined, are of the correct type, and are specified in the right order.