Skip to content

Commit 495e3e0

Browse files
dalexsotorolfbjarneGitHub CopilotGitHub Actions Autoformatter
authored
[release/10.0.1xx] [dotnet] Fix loading oldest reference assemblies for library projects Fixes #24043. (#24194)
Since this may result in unintuitive behavior (library projects are built differently than executable projects, so code that works in an executable project may not compile when moved to a library project), an escape hatch was implemented as well. One unintuitive behavior was when building an executable project with a library project from Windows: if the library project needs the remote connection, it would use a different workload, and different remote connection, than the executable project, which just wouldn't work. So we don't enable this new behavior when library projects need the remote connection (which is when bundle resources are precompiled for the library project; aka when `BundleOriginalResources=false` - note that it's enabled by default in .NET 10, so developers must opt in to run into this problem and thus not getting this new behavior). Fixes #24043. Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com> Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: GitHub Actions Autoformatter <github-actions-autoformatter@xamarin.com>
1 parent 3aa6069 commit 495e3e0

File tree

16 files changed

+84
-42
lines changed

16 files changed

+84
-42
lines changed

docs/building-apps/build-properties.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,35 @@ Specifies the minimum tvOS version the app can run on.
13251325

13261326
Applicable to tvOS; setting this value will set [SupportedOSPlatformVersion](#supportedosplatformversion) for tvOS projects (only).
13271327

1328+
## UseFloatingTargetPlatformVersion
1329+
1330+
A boolean property that controls whether library projects should use a floating target platform version or the oldest available platform version.
1331+
1332+
By default (starting in .NET 10), library projects without an explicit `TargetPlatformVersion` will use the oldest available reference assemblies for the current .NET version. This ensures maximum compatibility and allows library code to compile against the minimum API surface available for the target framework.
1333+
1334+
However, this default behavior means that library projects are built differently than executable projects (which use the latest platform version). Code that works in an executable project may not compile when moved to a library project if it uses APIs only available in newer platform versions.
1335+
1336+
Setting this property to `true` disables the automatic selection of the oldest platform version, allowing the library project to use the default (latest) platform version like executable projects do.
1337+
1338+
Example:
1339+
1340+
```xml
1341+
<PropertyGroup>
1342+
<!-- Use the latest platform version instead of the oldest -->
1343+
<UseFloatingTargetPlatformVersion>true</UseFloatingTargetPlatformVersion>
1344+
</PropertyGroup>
1345+
```
1346+
1347+
Default: `false` (use oldest platform version for library projects in .NET 10+).
1348+
1349+
This property only applies to library projects (`OutputType=Library`) that are
1350+
not app extensions and have not specified an explicit target platform version
1351+
(the target platform version is the optional version number at the end of the
1352+
`TargetFramework` property, for example for the TargetFramework
1353+
`net10.0-ios26.0` the target platform version is explicitly `26.0`).
1354+
1355+
This property was introduced in .NET 10.
1356+
13281357
## UseHardenedRuntime
13291358

13301359
A boolean property that specifies if a hardened runtime is enabled.

scripts/generate-workloadmanifest-targets/generate-workloadmanifest-targets.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@
6161
return max;
6262
}).
6363
ToHashSet ();
64+
var lowestTpvPerMajorDotNet = groupedByMajorDotNetVersion.
65+
Select (gr => {
66+
var min = gr.OrderBy (el => {
67+
var rv = tfmToTpvAndTfv (el);
68+
return float.Parse (rv.Tpv, System.Globalization.CultureInfo.InvariantCulture);
69+
}).First ();
70+
return min;
71+
}).
72+
ToHashSet ();
6473

6574
using (var writer = new StreamWriter (outputPath)) {
6675
writer.WriteLine ($"<Project>");
@@ -71,7 +80,11 @@
7180
var tpv = parsed.Tpv;
7281
supportedTFVs.Add (tfv);
7382
var workloadVersion = tfm;
74-
writer.WriteLine ($" <ImportGroup Condition=\" '$(TargetPlatformIdentifier)' == '{platform}' And '$(UsingAppleNETSdk)' != 'true' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '{tfv}')) And '$(TargetPlatformVersion)' == '{tpv}'\">");
83+
if (int.Parse (tfv.Split ('.') [0]) >= 10 && lowestTpvPerMajorDotNet.TryGetValue (tfm, out var lowest) && lowest.Split ('_') [1] == tpv) {
84+
writer.WriteLine ($" <ImportGroup Condition=\" '$(TargetPlatformIdentifier)' == '{platform}' And '$(UsingAppleNETSdk)' != 'true' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '{tfv}')) And ('$(TargetPlatformVersion)' == '{tpv}' Or ('$(TargetPlatformVersion)' == '' And '$(OutputType)' == 'Library' And '$(IsAppExtension)' != 'true' And '$(UseFloatingTargetPlatformVersion)' != 'true' And '$(BundleOriginalResources)' != 'false'))\">");
85+
} else {
86+
writer.WriteLine ($" <ImportGroup Condition=\" '$(TargetPlatformIdentifier)' == '{platform}' And '$(UsingAppleNETSdk)' != 'true' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '{tfv}')) And '$(TargetPlatformVersion)' == '{tpv}'\">");
87+
}
7588
writer.WriteLine ($" <Import Project=\"Sdk.props\" Sdk=\"Microsoft.{platform}.Sdk.{workloadVersion}\" />");
7689
if (hasWindows)
7790
writer.WriteLine ($" <Import Project=\"Sdk.props\" Sdk=\"Microsoft.{platform}.Windows.Sdk.Aliased.{tfm}\" Condition=\" $([MSBuild]::IsOSPlatform('windows'))\" />");

tests/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ test.config: Makefile $(TOP)/Make.config $(TOP)/mk/mono.mk $(TOP)/eng/Version.De
6565
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(platform)_NUGET_RUNTIME_MANAGED_NAME=$($(platform)_NUGET_RUNTIME_MANAGED_NAME)\\n)" | sed 's/^ //' >> $@
6666
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(rid)_NUGET_RUNTIME_NAME=$($(rid)_NUGET_RUNTIME_NAME)\\n))" | sed 's/^ //' >> $@
6767
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),SUPPORTED_API_VERSIONS_$(platform)='$(SUPPORTED_API_VERSIONS_$(platform))'\\n)" | sed 's/^ //' >> $@
68+
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(platform)_TARGET_PLATFORM_VERSION_LIBRARY=$($(platform)_TARGET_PLATFORM_VERSION_LIBRARY)\\n)" | sed 's/^ //' >> $@
6869
@printf "ENABLE_XAMARIN=$(ENABLE_XAMARIN)\n" >> $@
6970
@printf "ENABLE_ADR=$(ENABLE_ADR)\n" >> $@
7071
@printf "XCODE_IS_STABLE=$(XCODE_IS_STABLE)\n" >> $@
@@ -97,6 +98,7 @@ test-system.config: Makefile $(TOP)/Make.config $(TOP)/mk/mono.mk $(TOP)/eng/Ver
9798
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(platform)_NUGET_RUNTIME_MANAGED_NAME=$($(platform)_NUGET_RUNTIME_MANAGED_NAME)\\n)" | sed 's/^ //' >> $@
9899
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(rid)_NUGET_RUNTIME_NAME=$($(rid)_NUGET_RUNTIME_NAME)\\n))" | sed 's/^ //' >> $@
99100
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),SUPPORTED_API_VERSIONS_$(platform)='$(SUPPORTED_API_VERSIONS_$(platform))'\\n)" | sed 's/^ //' >> $@
101+
@printf "$(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(platform)_TARGET_PLATFORM_VERSION_LIBRARY=$($(platform)_TARGET_PLATFORM_VERSION_LIBRARY)\\n)" | sed 's/^ //' >> $@
100102
@printf "ENABLE_XAMARIN=$(ENABLE_XAMARIN)\n" >> $@
101103
@printf "ENABLE_ADR=$(ENABLE_ADR)\n" >> $@
102104
@printf "XCODE_IS_STABLE=$(XCODE_IS_STABLE)\n" >> $@

tests/common/Configuration.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ static void ParseConfigFiles ()
180180
ParseConfigFiles (FindConfigFiles ("configure.inc"));
181181
ParseConfigFiles (FindConfigFiles ("Make.config.local"));
182182
ParseConfigFiles (FindConfigFiles ("Make.config"));
183+
ParseConfigFiles (FindConfigFiles ("Make.versions"));
183184
}
184185

185186
static void ParseConfigFiles (IEnumerable<string> files)

tests/dotnet/MyClassLibrary/MacCatalyst/MyClass.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.

tests/dotnet/MyClassLibrary/MacCatalyst/MyClassLibrary.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
<PropertyGroup>
44
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-maccatalyst</TargetFramework>
55
</PropertyGroup>
6+
<Import Project="..\shared.csproj" />
67
</Project>
78

tests/dotnet/MyClassLibrary/MyClass.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System;
2+
3+
using Foundation;
4+
25
namespace MyClassLibrary {
3-
public class MyClass {
6+
public class MyClass : NSObject {
47
public MyClass ()
58
{
69
}

tests/dotnet/MyClassLibrary/iOS/MyClass.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.

tests/dotnet/MyClassLibrary/iOS/MyClassLibrary.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
<PropertyGroup>
44
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-ios</TargetFramework>
55
</PropertyGroup>
6+
<Import Project="..\shared.csproj" />
67
</Project>
78

tests/dotnet/MyClassLibrary/macOS/MyClass.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)