This is because `EnablePreviewFeatures=true` doesn't quite work, since it
requires the building .NET and the target .NET to be on the same version.
We might want to build with .NET 9, but the Xcode branch is targeting .NET 8,
so it doesn't work.
This behavior is explained here:
https://github.com/dotnet/designs/blob/main/accepted/2021/preview-features/preview-features.md#meaning-of-property-in-multi-targeted-projects
The best solution seems to switch to using the Experimental attribute instead,
which was designed for our scenario (and explicitly to fix the problem we're
running into): bba3216250/accepted/2023/preview-apis/preview-apis.md
This also meant we had to augment `-nowarn` for bgen to:
* Pass any nowarn values to the compiler when bgen compiles stuff.
* Pass `$(NoWarn)` (the MSBuild property) to bgen when building a binding project.
---------
Co-authored-by: Alex Soto <alex@soto.dev>
When VS (Windows) needs to figure out where the iOS SDK is located on disk on
the Mac machine, the project is evaluated and
the`_XamarinRelativeSdkRootDirectory` property is read. Unfortunately an
MSBuild optimization recently occurred in VS, where they don't keep
underscored properties around after the build, and thus the property XVS needs
to inspect isn't there anymore.
So make `_XamarinRelativeSdkRootDirectory` and `_RelativeMlaunchPath` public
properties by removing the underscore.
Fixes https://dev.azure.com/devdiv/DevDiv/_workitems/edit/2220369.
Backports the following maestro and artifact storage changes,
removing dependencies on bosstoragemirror and adding support
for passwordless maestro auth.
0d1bd7b1bcebf969ee402562461eeb
This will hopefully make it easier to diagnose these kinds of crashes:
Thread 0 Crashed:
0 libobjc.A.dylib 0x00000001a6f6e7f8 object_getClass + 48
1 MyTestDotNetApp.Net 0x0000000104b90a68 do_icall (interp.c:2273)
2 MyTestDotNetApp.Net 0x0000000104b8f838 do_icall_wrapper (interp.c:2361)
3 MyTestDotNetApp.Net 0x0000000104b85214 interp_exec_method (interp.c:3885)
4 MyTestDotNetApp.Net 0x0000000104b82de8 interp_runtime_invoke (interp.c:2122)
5 MyTestDotNetApp.Net 0x0000000104b4aedc mono_jit_runtime_invoke (mini-runtime.c:3650)
6 MyTestDotNetApp.Net 0x0000000104a8b874 mono_runtime_try_invoke (object.c:2415)
7 MyTestDotNetApp.Net 0x0000000104a8d8a0 mono_runtime_invoke (object.c:2464)
8 MyTestDotNetApp.Net 0x0000000104c42b68 native_to_managed_trampoline_68(objc_object*, objc_selector*, _MonoMethod**, objc_object*, unsigned int) (registrar.mm:4511)
9 MyTestDotNetApp.Net 0x0000000104c42a00 +[__NSObject_Disposer drain:] (registrar.mm:20968)
10 Foundation 0x00000001adc13b14 __NSThreadPerformPerform + 260
This happens because we try to access freed/invalid memory, but unfortunately
the crash report / stack trace does not contain any hint whatsoever about the
memory that triggered the crash.
By adding an opt-in to validate the memory for a given object, we might be
able to detect this crash in a few cases, and instead throw a managed
exception with much more information.
A project opts-in by setting `_ValidateObjectPointers=true` in the csproj.
Ref: https://github.com/xamarin/xamarin-macios/issues/19493
---------
Co-authored-by: Manuel de la Pena <mandel@microsoft.com>
Backport of https://github.com/xamarin/xamarin-macios/pull/20952
--------
## Description
Previous fix https://github.com/xamarin/xamarin-macios/pull/20945 did
not take into account that when we target non arm64 apple mobile
platforms we are using `MONO_AOT_MODE_INTERP_ONLY` which cannot use
dedup optimization as it discards AOT images during runtime.
## Changes
- Enable dedup only when targeting ARM64
- Fix tests to cover builds for both ARM64 and X64 builds
Finally, the change was tested against MAUI iossimulator-x64 template
app
---------
Co-authored-by: Ivan Povazan <ivan.povazan@gmail.com>
Co-authored-by: Ivan Povazan <55002338+ivanpovazan@users.noreply.github.com>
## Description
This is a follow-up PR to:
https://github.com/xamarin/xamarin-macios/pull/20936
We should not enable dedup when targeting `maccatalyst-x64` because in
case when the project file specifies
`MtouchInterpreter=all,-System.Private.CoreLib`, the build will run the
full AOT compiler with interpreter enabled.
In this setup the runtime is configured to run in interp only mode:
97a91cc4e3/tools/common/Target.cs (L812-L813)
which means that during runtime, AOT images will be ignored - aot
runtime will load them but mark them as unusuable since they are
compiled with `full` compiler switch and the code falls back to
interpreter (ref:
efebf202a4/src/mono/mono/mini/aot-runtime.c (L2131-L2148)
)
This is problematic for the `aot-instances` container image, which has a
special handling at the runtime and does not accept it to be marked as
unusable (we might want to revisit this in the future):
efebf202a4/src/mono/mono/mini/aot-runtime.c (L2527-L2529)
## Changes
This PR disables dedup optimization when targeting `maccatalyst-x64` and
updates the required tests to match the behavior.
---
Backports:
- [x] https://github.com/xamarin/xamarin-macios/pull/20946
- [x] Original reenabling of dedup for .NET 9 already includes these
changes: https://github.com/xamarin/xamarin-macios/pull/20941
---------
Co-authored-by: GitHub Actions Autoformatter <github-actions-autoformatter@xamarin.com>
## Description
As part of the fix for: https://github.com/dotnet/runtime/issues/99248
we disabled dedup optimization in partial/hybrid AOT mode (when both
interpreter and AOT compiler are enabled). This change got backported to
.NET 8 and with the latest servicing release regressed build times and
app sizes significantly as reported in:
https://github.com/xamarin/xamarin-macios/issues/20848
However, it turns out that disabling dedup optimization is not required
to fix https://github.com/dotnet/runtime/issues/99248 but instead we
should correct the Xamarin SDK integration with this optimization which
this PR is doing. The following section describes the initial problem in
more details.
## Overview of AOT modes and dedup optimization
When the repro project from
https://github.com/dotnet/runtime/issues/99248 is built with dedup
enabled in hybrid AOT+interpreter mode, the app crashes with:
```
024-07-23 14:32:37.524110+0200 IvansApp[12711:20244208] debug: AOT NOT FOUND: (wrapper other) object:gsharedvt_out_sig (intptr).
2024-07-23 14:32:37.524120+0200 IvansApp[12711:20244208] error: * Assertion at /Users/ivan/repos/runtime-mono-iOS/src/mono/mono/mini/interp/interp.c:2667, condition `is_ok (error)' not met, function:init_jit_call_info, Attempting to JIT compile method '(wrapper other) void object:gsharedvt_out_sig (intptr)' while running in aot-only mode. See https://learn.microsoft.com/xamarin/ios/internals/limitations for more information.
```
To track down why these wrappers which are used to transition from
interpreter to AOT code, are not generated we need to understand when
they are compiled in different AOT modes with and without dedup
optimization enabled:
- In full AOT setup - all assemblies AOT compiled
- `gsharedvt_out_sig` methods are never generated
- In hybrid AOT + interpreter setup - all assemblies AOT compiled:
`MtouchInterpreter=-all`
- Dedup OFF:
- `gsharedvt_out_sig` methods are generated in AOT images of every
assembly (to enable interpreter calling into each specific assembly -
here wrappers with same signatures are duplicated)
- Dedup ON:
- `gsharedvt_out_sig` methods are generated only in `aot-instances` AOT
image
- during AOT compilation of individual assemblies generation of
`gsharedvt_out_sig` is skipped
- during AOT compilation of `aot-instances` assembly we collect all
`gsharedvt_out_sig` variants from the full program scope and generate
code for them in `aot-instances` AOT image
- In hybrid AOT + interpreter setup - all assemblies interpreted except
a given assembly: `MtouchInterpreter=all,-MyAssembly`
- Dedup OFF:
- `gsharedvt_out_sig` methods are generated in AOT image of `MyAssembly`
(to enable interpreter calling into it)
- Dedup ON: <- $${\color{red} ISSUE }$$
- `gsharedvt_out_sig` methods *should* be generated only in
`aot-instances` AOT image, but the `aot-instances` image is missing
- explanation:
- what happens is that generation of `gsharedvt_out_sig` is skipped
during AOT compilation of `MyAssembly` (as expected).
- But, the build does not mark `aot-instances` assembly as the one that
should be AOT compiled.
- The reason for this is that we have a global `_IsDedupEnabled` flag,
but when custom linker step analysis `aot-instances.dll` it does not see
it as an assembly which should not be interpreted.
- To explain that better: we mark *all* assemblies as to be interpreted
(via: `MtouchInterpreter=all`), but exclude only `MyAssembly` (via:
`MtouchInterpreter=all,-MyAssembly`).
- So when custom linker step processes `aot-instaces.dll` it treats it
as an assembly to be interpreted, so it does not mark it for AOT
compilation.
- This further results with `aot-instances` AOT image missing, and all
the methods which we skipped during AOT compilation never get generated.
## The fix
To fix this and address regressions reported in:
https://github.com/xamarin/xamarin-macios/issues/20848 we are reenabling
dedup optimization whenever AOT compilation is requested and fixing the
issue where the custom linker step for generating AOT parameters always
treates the dedup assembly as the one to be AOTed.
Once approved this should be backported to .NET 8 as servicing releases
are also affected with it.
---------
Co-authored-by: GitHub Actions Autoformatter <github-actions-autoformatter@xamarin.com>
fixes: https://github.com/dotnet/maui/issues/23577
## Cause:
`MtouchInterpreter` is set as
d1ec7a793f/msbuild/Xamarin.Shared/Xamarin.Shared.props (L308)
`DynamicCodeSupport` is set by
d1ec7a793f/dotnet/targets/Xamarin.Shared.Sdk.targets (L146)
`Xamarin.Shared.Sdk.targets` is imported *before* `Xamarin.Shared.props`
as shown below (courtesy of @ivanpovazan)
<img
src="https://github.com/user-attachments/assets/c97b7f01-2372-4f9d-bedf-83060eed1c50">
so unless the value of `MtouchInterpreter` is set in the project, it's
value will be empty when the `DynamicCodeSupport` property is evaluated.
## Resolution:
To minimize the impact of this change, until it can be investigated more
fully, the value of `MtouchInterpreter` is evaluated as
d1ec7a793f/msbuild/Xamarin.Shared/Xamarin.Shared.props (L308)
So adding `( '$(MtouchInterpreter)' == '' And '$(UseInterpreter)' ==
'false' )` to the definition of `DynamicCodeSupport` to match the
`MtouchInterpreter` definition.
A further fix might be to either:
1. Reorder the imports so that the props are included before the
targets, although the ramifications of that change could be significant
2. Move the definition of `DynamicCodeSupport` to
`Xamarin.Shared.props`. This at first glance seems to be less
significant than 1) but would need review and testing.
---------
Co-authored-by: Ivan Povazan <55002338+ivanpovazan@users.noreply.github.com>
When building universal apps, each inner build must add the runtime identifier to the output path, otherwise the inner builds may conflict with eachother, overwriting eachother's files.
That's bad.
So we explicitly set `AppendRuntimeIdentifierToOutputPath` to `true` when building inner builds.
Ignore a few warnings by default, when reporting about types that we
couldn't register because they're deprecated/removed.
Also add a way to re-enable these warnings.
Fixes https://github.com/xamarin/xamarin-macios/issues/20670.
This reverts commit f8552e9294.
This change is only supposed to be released with .NET 9, and we might
release new .NET 8 updates from main. Thus we need to make sure these
changes are only in the net9.0 branch (they already are).
We fixed the credscan issue in two diff ways:
1. When the job allows it, we checkout all repos using our own checkout template.
2. When the jib does not allow it, we create an empty json file. In the future we can add any needed exception.
We also needed to fix the signature because the VS code moved to net core which changed the extension of their build.exe to build.dll.
Dynamic code is not supported if the interpreter is not enabled, and the
interpreter is not enabled if the MtouchInterpreter property is *empty*.
This regression was introduced in #19812.
Fixes https://github.com/dotnet/runtime/issues/101840.
## Description
This PR enables the dedup optimization in FullAOT mode only. The
optimization can only run in FullAOT mode with complete application
context. Without it, the AOT compiler may fail to collect all generic
instances, and the runtime can't find them as they are searched in the
dedup assembly.
## Changes
This PR updates the SDK targets to enable dedup optimization in FullAOT
mode only. This change doesn't depend on any runtime changes.
## Verification
This PR also introduces partial AOT tests. They inspect the bundle for
`aot-instances.dll`, which shouldn't be generated in a partial AOT
compilation setup. Additionally, basic functionality is tested by
asserting at app startup.
## Additional notes
This change should be backported to .NET 8 as well.
Fixes https://github.com/dotnet/runtime/issues/99248
The steps used to publish build asset information to maestro have been
updated. The post build stage has been disabled for main and .NET 9, as
maestro manifest generation and channel promotion will now run as part
of the "Prepare .NET Release" stage.
With the new `PushToAzureDevOpsArtifacts` task the build pipeline should
now create all of the artifacts required for maestro artifact
publishing.
The `add-build-to-channel` darc command will now trigger a
[Build Promotion Pipeline][0] that pushes build assets to the feed that
corresponds to the maestro channel that is being updated. We should
no longer need to push assets to various NuGet feeds in a separate step.
[0]:
https://dev.azure.com/devdiv/DevDiv/_build/results?buildId=9654802&view=logs&j=ba23343f-f710-5af9-782d-5bd26b102304&t=aec38b44-8611-5dd5-3900-5feff4e06d1b
---------
Co-authored-by: Alex Soto <alex@alexsoto.me>
Add support for the LinkWithSwiftSystemLibraries metadata to specify whether a native library is a Swift library, in which case we'll automatically set the `LinkWithSwiftSystemLibraries` MSBuild property to `true`.
Also add a test.
VB doesn't support default interface members, and will show an error for all
unimplemented interface members, even if they have a default implementation.
This is a problem for the VB templates, because they make use of protocol
interfaces, which will soon have interface members with default
implementations.
In order to get around this, change the VB templates to use the model class
instead of the protocol interfaces.
Stop requiring a LinkWith attribute in an assembly in order to keep any Objective-C
types within. There are many ways to include a native library in a build nowadays,
and more and more often they don't need any LinkWith attributes to specify custom
linker behavior (in particular for frameworks, which can typically be included as-is).
The result of not searching such assemblies for Objective-C types would be that the
native linker would strip them away, and that would mean incorrect behavior at runtime.
However, this is a rather invasive change, especially for a minor release, so I'm
adding two things to make it better:
1. An opt-out MSBuild property: `RequireLinkWithAttributeForObjectiveCClassSearch`.
Set to 'true' to opt-out (default is 'false').
2. Improve handling of native symbols with regards to the native linker.
Add a new item group, ReferenceNativeSymbol, that contains native symbols
we handle in some way - either to be ignored or we ask the native linker
to keep it (by passing it as '-u ...' or in a symbol list file).
There are two supported types of metadata:
* SymbolType: either 'ObjectiveCClass', 'Function' or 'Field'. Used to
compute the complete native name of a symbol (for instance, the native
symbol for the Objective-C class "MyClass" is `_OBJC_CLASS_$_MyClass`,
while for a function "MyFunction" it's just `_MyFunction`.
* SymbolMode: either 'Ignore' or 'Default'. "Ignore" means to not pass the given
symbol to the native linker, the default is to do so.
SymbolType is required, while SymbolMode isn't.
Example symbol to keep:
```xml
<ItemGroup>
<ReferenceNativeSymbol Include="MyClass" SymbolType="ObjectiveCClass" />
</ItemGroup>
```
Example symbol to ignore:
```xml
<ItemGroup>
<ReferenceNativeSymbol Include="MyClass" SymbolType="ObjectiveCClass" SymbolMode="Ignore" />
</ItemGroup>
```
Finally use the latter solution to work around an issue that arouse with monotouch-test:
we reference an Objective-C class that doesn't exist in monotouch-test. This worked
because the referencing assembly didn't have a LinkWith attribute (and thus the reference
was ignored), but now that the reference isn't ignored anymore, we need to explicitly
ignore the Objective-C class.
Make sure Microsoft.\<platform\>.Sdk.DefaultItems.props is rebuilt if the
current hash changes.
This fixes a local rebuild issue, where we'd rebuild
Microsoft.\<platform\>.Sdk.Versions.props, but not
Microsoft.\<platform\>.Sdk.DefaultItems.props.
A build failure like this would thus result:
tools/msbuild/iOS/Xamarin.Shared.targets(606,3): error : A bundle identifier is required. Either add an 'ApplicationId' property in the project file, or add a 'CFBundleIdentifier' entry in the project's Info.plist file.
because:
* We store the current git hash in both of the files mentioned above.
* We only include default items in a build if the git hashes match.
* Since the files weren't both rebuilt, they'd contain different hashes, and
thus we wouldn't include Info.plist in the build, leading to the build
error.
By adding the 'LinkWithSwiftSystemLibraries=true' property in a project file, we'll
now add the location of Swift's system libraries to the linker arguments.
Fixes https://github.com/xamarin/xamarin-macios/issues/18848.
We can determine whether we're building for the simulator or not as soon as we know
the RuntimeIdentifier, so do that, and set _SdkIsSimulator accordingly.
In legacy Xamarin we had to execute a target in order to compute _SdkIsSimulator
(_DetectSdkLocations), but with this change we won't have to in .NET anymore, which
makes it possible to simplify some logic.
The first thing we do here is to also move the computation of the trimmer configuration
to right after computing _SdkIsSimulator (because we only need to know three things
to compute the default trimmer mode: the target platform + whether we're building
for the simulator or not + the configuration, and those are all known at this point
now).
This will make it possible to stop suppressing trimmer warnings depending on the
trimming mode in effect (we have to suppress (or decide not to) the warnings in the
initial MSBuild evaluation phase, before any targets are executed, because the properties
in question are read during the evaluation phase in .NET). Note that this PR is not
changing any trimmer warnings, that will only happen in .NET 9.
The 'MSBuild::MakeRelative' path takes the current directory into
account.
Given the following example:
$([MSBuild]::MakeRelative('/Users/rolf/testproject/','Info.plist'))
returns:
1. `/Info.plist` if the current directory is the root directory (`/`).
2. `Info.plist` otherwise.
This is a problem, because we specifically look for "Info.plist" during
the
build, and if we don't find it, we may end up with this error:
> A bundle identifier is required. Either add an 'ApplicationId'
property in the project file, or add a 'CFBundleIdentifier' entry in the
project's Info.plist file.
The fix is to instead of use the relative `Info.plist` path in the call
to
`[MSBuild]::MakeRelative`, use the full path instead:
$([MSBuild]::MakeRelative('/Users/rolf/testproject/','/Users/rolf/testproject/Info.plist'))
and that always yields the expected "Info.plist" result.
This deduplicates some code, and also ensures we specifiy a max limit to the
level of parallelism. This fixes an issue in the AOTCompile and ScnTool tasks,
where we'd have no limit, launching as many subprocesses as tasks there are to
execute. In particular for the AOTCompile task, this can put a rather heavy
burden on build machines, slowing everything down to a crawl.
Fixes https://github.com/xamarin/xamarin-macios/issues/20210.
If a project tried to use a .NET 9 project (say TargetFramework=net9.0-ios), then
we used to show these rather unhelpful errors:
error NETSDK1147: The target platform identifier ios was not recognized.
The underlying problem is that we don't support .NET 9 yet, so with this fix we now show:
error NETSDK1202: The current .NET SDK does not support targeting .NET 9.0. Either target .NET 8.0 or lower, or use a version of the .NET SDK that supports .NET 9.0. Download the .NET SDK from https://aka.ms/dotnet/download
which is much more helpful.
This is accomplished by loading our workload even when using newer .NET
versions we don't support, because the .NET build logic will show the better
error later on.
The extracted files show up in the build later on, and if only the 0-length
mirror file exists on Windows, it'll be copied as such to the Mac, producing
incorrect build results.
Add multi-targeting support for our initial .NET 8 packs (for Xcode
15.0).
This means a library/binding project can do:
```xml
<TargetFrameworks>net8.0-ios17.0;net8.0-ios17.2</TargetFrameworks>
```
and the library will be built in two varieties: once using our iOS 17.0
bindings, and once using our iOS 17.2 bindings.
An app project can also do:
```xml
<TargetFramework>net8.0-ios17.0</TargetFramework>
```
to build with the iOS 17.0 bindings (which is typically not very useful,
since building with the latest iOS SDK is usually best).
After this the Xamarin.iOS.Tasks and Xamarin.Mac.Tasks assemblies are empty,
so the next step will be to remove them completely (this will happen in a
different pull request).
---------
Co-authored-by: Alex Soto <alex@alexsoto.me>
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.
This is the first step towards [multi-targeting support][1]. In order to
support multi-targeting, it must be possible to install several versions of
our packs simultaneously, and that also means that it becomes a lot easier to
visualize and work with the version we want to support if the packs were named
in a helpful way.
In particular, this PR changes the sdk, ref and runtime pack names to contain
the target framework + target platform version.
This will be the new names:
* iOS
* Microsoft.iOS.Sdk.net8.0_17.2
* Microsoft.iOS.Ref.net8.0_17.2
* Microsoft.iOS.Runtime.ios-arm64.net8.0_17.2
* Microsoft.iOS.Runtime.iossimulator-arm64.net8.0_17.2
* Microsoft.iOS.Runtime.iossimulator-x64.net8.0_17.2
* tvOS
* Microsoft.tvOS.Sdk.net8.0_17.2
* Microsoft.tvOS.Ref.net8.0_17.2
* Microsoft.tvOS.Runtime.ios-arm64.net8.0_17.2
* Microsoft.tvOS.Runtime.iossimulator-arm64.net8.0_17.2
* Microsoft.tvOS.Runtime.iossimulator-x64.net8.0_17.2
* Mac Catalyst
* Microsoft.MacCatalyst.Sdk.net8.0_17.2
* Microsoft.MacCatalyst.Ref.net8.0_17.2
* Microsoft.MacCatalyst.Runtime.maccatalyst-x64.net8.0_17.2
* Microsoft.MacCatalyst.Runtime.maccatalyst-arm64.net8.0_17.2
* macOS
* Microsoft.macOS.Sdk.net8.0_14.2
* Microsoft.macOS.Ref.net8.0_14.2
* Microsoft.macOS.Runtime.osx-x64.net8.0_14.2
* Microsoft.macOS.Runtime.osx-arm64.net8.0_14.2
There are two main benefits to renaming the packs:
* It becomes a lot easier to understand which versions we support when we
support multi-targeting. For example, say we want to support:
* net8.0-ios17.0
* net8.0-ios17.2
* net9.0-ios18.0
In this case we'd ship packs for `Microsoft.iOS.Sdk.net8.0_17.0`,
`Microsoft.iOS.Sdk.net8.0_17.2`, `Microsoft.iOS.Sdk.net9.0_18.0` (the
exact version number for each pack wouldn't be important).
If we didn't change the pack names, we'd need to track the exact versions
of the Microsoft.iOS.Sdk pack, mapping them to the correct target
framework + target platform version we want to support.
* It'll be possible to add maestro subscriptions between versions. Given the
previous example:
* net8.0-ios17.0
* net8.0-ios17.2
* net9.0-ios18.0
The branch producing `net9.0-ios8.0` could have a maestro subscription on
the branches producing `net7.0-ios17.0` and `net7.0-ios17.2`,
automatically bumping the versions whenever those branches have any
changes.
This would be rather annoying to keep track of and bump manually.
[1]: https://github.com/xamarin/xamarin-macios/blob/main/docs/multi-target-framework.md
Currently for universal apps we build the project once for each RuntimeIdentifier,
and each time we end up building any referenced projects as well.
It's not necessary to build referenced (library) projects on a per-RID basis, because
the RID isn't taken into account.
So optimize this:
1. Build project references in the containing build, before the RID-specific build.
This is accomplished by adding a dependency on the ResolveReferences target (which
also needs the BuildOnlySettings target to run first in order to actually build
any referenced projects).
2. Set "BuildProjectReferences=false" when running the RID-specific build, so
that any project references aren't built.
3. Also change how we override the BuildDependsOn property: we now have special
logic for library projects, where we don't do any kind of app-building stuff,
we only deal with resources.
4. This required adding another target dependency for _UnpackLibraryResources:
it now depends on the BuildOnlySettings target as well (for the same reason as
in point 1).
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.
The `SdkSupportedTargetPlatformVersion` item group is used for (at least) two things:
1. Generate the `_OR_GREATER` preprocessing symbols:
bfd2919bc4/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.BeforeCommon.targets (L230-L237)
2. Validate the TargetPlatformVersion:
bfd2919bc4/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.TargetFrameworkInference.targets (L233-L246)
The problem is that these two uses aren't equivalent.
Take for example the following scenario:
We release bindings for iOS 10, and a library developer takes advantage of the
bindings for the new iOS version, while at the same time supporting
multi-targeting to older platforms:
```csharp
#if IOS10_0_OR_GREATER
UseNewApi ();
#else
UseOldApi ();
#endif
```
Time passes, iOS 11 comes out, and we stop shipping bindings specifically for
iOS 10 (the APIs themselves would be included in the bindings for iOS 11). The
code above should continue to work, but iOS 10 is not a valid
TargetPlatformVersion anymore. However, with the current situation there's no
way to express this, because the moment we remove the "10.0" version from
SdkSupportedTargetPlatformVersion, the IOS10_0_OR_GREATER define isn't
generated anymore.
We discussed this in a meeting internally, and the suggestion that came up was
to use metadata to handle this situation, and we've decided to add the
"DefineConstantsOnly=true" metadata to items in
SdkSupportedTargetPlatformVersion that are "OS versions we support or have
supported", but not "OS versions we support as TargetPlatformVersion".
Note: we're adding this to .NET 8, but .NET will not understand the new
metadata until .NET 9, which means this won't be a breaking change until .NET
9.
In a different PR I'll add logic to warn if a project uses a
TargetPlatformVersion that is no longer valid (so that people will start
getting a warning in .NET 8 instead of getting surprised by a build error in
.NET 9).
Ref: https://github.com/dotnet/sdk/issues/38016
The canonical property we use for the interpreter is `MtouchInterpreter` - and
the interpreter is enabled if `MtouchInterpreter` is set to any value (the
`MtouchInterpreter` value is used to select which assemblies to interpret, the
only way to completely disable the interpreter is to not set
`MtouchInterpreter` at all).
So fix a couple of cases of wrong comparison:
* Don't use `UseInterpreter` - which is used to compute a specific value for
`MtouchInterpreter` - because developers don't have to set `UseInterpreter`
to enable the interpreter, they can set `MtouchInterpreter` directly.
* Don't compare `MtouchInterpreter` with `true`: that only checks if the
assembly "true" is interpreted (which it rarely is).
Fixes https://github.com/dotnet/runtime/issues/96920.