Skip to content

Commit d0ca2a6

Browse files
authored
Make serialization discovery opt-in (#2929)
Serialization discovery is an undocumented quirk that exists for back-compat in xamarin scenarios. We turned it on by default in .NET 6, but would like to remove such quirks from the default options in .NET 7. This changes the (undocumented) command-line option to be opt-in. Xamarin SDKs will be expected to pass this option by setting <_ExtraTrimmerArgs>--enable-serialization-discovery</_ExtraTrimmerArgs>.
1 parent 463997e commit d0ca2a6

File tree

9 files changed

+17
-7
lines changed

9 files changed

+17
-7
lines changed

docs/serialization.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ If possible, avoid using reflection-based serializers with trimming, and prefer
66

77
As a last resort, the linker does have limited heuristics that can be enabled to keep _some_ of the types and members required for serialization, but this provides no correctness guarantees; apps which use reflection-based serializers are still considered "broken" as far as the static analysis can tell, and it is up to you to make sure that the app works as intended.
88

9+
Serialization discovery is disabled by default, and can be enabled by passing `--enable-serialization-discovery`.
10+
911
## History
1012

1113
The linker has historically been used for Xamarin scenarios that use reflection-based serializers like XmlSerializer, since before the introduction of the trim analysis warnings. There were limited heuristics to satisfy some simple uses of serializers. To provide backwards compatibility for such scenarios, the linker has built-in heuristics that makes some simple cases "just work", albeit in an opaque and unpredictable way.
1214

13-
Consider disabling this behavior by passing `--disable-serialization-discovery` if possible, but it may be necessary when using legacy serializers that don't provide source generators or a similar solution that is statically analyzable. The following is a description of the heuristics for anyone who is unfortunate enough to have to rely on this behavior.
15+
Consider disabling this behavior if possible, but it may be necessary when using legacy serializers that don't provide source generators or a similar solution that is statically analyzable. The following is a description of the heuristics for anyone who is unfortunate enough to have to rely on this behavior.
1416

1517
## Heuristics
1618

17-
Serialization discovery is enabled by default, and can be disabled by passing `--disable-serialization-discovery`. There are four parts to the heuristics:
19+
There are four parts to the heuristics:
1820
- Activation: which conditions cause the discovered roots and their recursive types to be kept
1921
- Root discovery: logic to discover types and members are entry points to serialization
2022
- Type graph: recursive logic to build a set of types to consider for serialization, starting from the roots

src/ILLink.Tasks/build/Microsoft.NET.ILLink.targets

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,11 @@ Copyright (c) .NET Foundation. All rights reserved.
259259
<NoWarn Condition=" '$(PlatformTarget)' != 'x64' AND '$(PlatformTarget)' != 'arm64'">$(NoWarn);IL2009;IL2012</NoWarn> <!-- Unresolved field referenced in XML -->
260260
</PropertyGroup>
261261

262+
<!-- Enable serialization discovery for compat in < 7.0 -->
263+
<PropertyGroup Condition="$([MSBuild]::VersionLessThan('$(TargetFrameworkVersion)', '7.0')">
264+
<_ExtraTrimmerArgs>--enable-serialization-discovery $(_ExtraTrimmerArgs)</_ExtraTrimmerArgs>
265+
</PropertyGroup>
266+
262267
<!-- Set a default value for TrimmerRemoveSymbols unless set explicitly. -->
263268
<PropertyGroup Condition=" '$(TrimmerRemoveSymbols)' == '' ">
264269
<!-- The default is to remove symbols when debugger support is disabled, and keep them otherwise. -->

src/linker/Linker/Driver.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,8 @@ protected int SetupContext (ILogger? customLogger = null)
375375
continue;
376376
}
377377

378-
case "--disable-serialization-discovery":
379-
if (!GetBoolParam (token, l => context.DisableSerializationDiscovery = l))
378+
case "--enable-serialization-discovery":
379+
if (!GetBoolParam (token, l => context.EnableSerializationDiscovery = l))
380380
return -1;
381381

382382
continue;
@@ -773,7 +773,7 @@ protected int SetupContext (ILogger? customLogger = null)
773773
// SealerStep
774774
// OutputStep
775775

776-
if (!context.DisableSerializationDiscovery)
776+
if (context.EnableSerializationDiscovery)
777777
p.MarkHandlers.Add (new DiscoverSerializationHandler ());
778778

779779
if (!context.DisableOperatorDiscovery)

src/linker/Linker/LinkContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public Pipeline Pipeline {
115115

116116
public bool KeepUsedAttributeTypesOnly { get; set; }
117117

118-
public bool DisableSerializationDiscovery { get; set; }
118+
public bool EnableSerializationDiscovery { get; set; }
119119

120120
public bool DisableOperatorDiscovery { get; set; }
121121

test/Mono.Linker.Tests.Cases/Serialization/CanDisableSerializationDiscovery.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ namespace Mono.Linker.Tests.Cases.Serialization
99
{
1010
[Reference ("System.Xml.ReaderWriter.dll")]
1111
[Reference ("System.Xml.XmlSerializer.dll")]
12-
[SetupLinkerArgument ("--disable-serialization-discovery")]
1312
public class CanDisableSerializationDiscovery
1413
{
1514
public static void Main ()

test/Mono.Linker.Tests.Cases/Serialization/DataContractJsonSerialization.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Mono.Linker.Tests.Cases.Serialization
99
[Reference ("System.Runtime.Serialization.dll")]
1010
[Reference ("System.Runtime.Serialization.Primitives.dll")]
1111
[Reference ("System.Runtime.Serialization.Json.dll")]
12+
[SetupLinkerArgument ("--enable-serialization-discovery")]
1213
public class DataContractJsonSerialization
1314
{
1415
public static void Main ()

test/Mono.Linker.Tests.Cases/Serialization/DataContractSerialization.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace Mono.Linker.Tests.Cases.Serialization
1010
[Reference ("System.Runtime.Serialization.dll")]
1111
[Reference ("System.Runtime.Serialization.Xml.dll")]
1212
[Reference ("System.Runtime.Serialization.Primitives.dll")]
13+
[SetupLinkerArgument ("--enable-serialization-discovery")]
1314
public class DataContractSerialization
1415
{
1516
public static void Main ()

test/Mono.Linker.Tests.Cases/Serialization/SerializationTypeRecursion.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Mono.Linker.Tests.Cases.Serialization
99
[Reference ("System.Xml.ReaderWriter.dll")]
1010
[Reference ("System.Xml.XmlSerializer.dll")]
1111
[SetupCompileArgument ("/unsafe")]
12+
[SetupLinkerArgument ("--enable-serialization-discovery")]
1213
public class SerializationTypeRecursion
1314
{
1415
public static void Main ()

test/Mono.Linker.Tests.Cases/Serialization/XmlSerialization.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Mono.Linker.Tests.Cases.Serialization
99
{
1010
[Reference ("System.Xml.ReaderWriter.dll")]
1111
[Reference ("System.Xml.XmlSerializer.dll")]
12+
[SetupLinkerArgument ("--enable-serialization-discovery")]
1213
public class XmlSerialization
1314
{
1415
public static void Main ()

0 commit comments

Comments
 (0)