Opzioni di trimming

Le proprietà e gli elementi di MSBuild seguenti influiscono sul comportamento delle distribuzioni autonome su cui è stato eseguito il trimming. Alcune delle opzioni indicano ILLink, che è il nome dello strumento sottostante che implementa il trimming. Per altre informazioni sullo strumento sottostante, vedere la documentazione di trimmer.

Il trimming con PublishTrimmed è stato introdotto in .NET Core 3.0. Le altre opzioni sono disponibili solo in .NET 5 e versioni successive.

Abilita trimming

  • <PublishTrimmed>true</PublishTrimmed>

    Abilita il trimming durante la pubblicazione. In questo modo vengono disattivate anche le funzionalità non compatibili con il taglio e viene abilitata l'analisi di trimming durante la compilazione.

Nota

Se si specifica il trimming come abilitato dalla riga di comando, l'esperienza di debug sarà diversa e potrebbero verificarsi bug aggiuntivi nel prodotto finale.

Inserire questa impostazione nel file di progetto per assicurarsi che l'impostazione venga applicata durante dotnet build, non solo durante dotnet publish.

Questa impostazione abilita il trimming ed esegue il trimming su tutti gli assembly per impostazione predefinita. In .NET 6 solo sugli assembly che hanno accodato esplicitamente il trimming tramite [AssemblyMetadata("IsTrimmable", "True")] verrebbe eseguito il trimming per impostazione predefinita. È possibile tornare al comportamento precedente usando <TrimMode>partial</TrimMode>.

Questa impostazione consente di eseguire il trimming su tutti gli assembly configurati per il trimming. Con Microsoft.NET.Sdk in .NET 6, include tutti gli assembly con [AssemblyMetadata("IsTrimmable", "True")], che è il caso per gli assembly di runtime .NET. In .NET 5 gli assembly del pacchetto runtime netcoreapp sono configurati per il trimming tramite i metadati di MSBuild <IsTrimmable>. Altri SDK possono definire impostazioni predefinite diverse.

Questa impostazione abilita anche l'analizzatore Roslyn per la compatibilità di trim e disabilita le funzionalità incompatibili con il trimming.

Granularità trimming

Utilizzare la TrimMode proprietà per impostare la granularità di trimming su partial o full. L'impostazione predefinita per le app console (e, a partire da .NET 8, app Web SDK) è full:

<TrimMode>full</TrimMode>

Per eseguire il trimming solo sugli assembly che hanno accodato esplicitamente il trimming, impostare la proprietà su partial:

<TrimMode>partial</TrimMode>

Se si modifica la modalità di trimming in partial, è possibile acconsentire esplicitamente ai singoli assembly per eseguire il trimming usando un elemento MSBuild <TrimmableAssembly>.

<ItemGroup>
  <TrimmableAssembly Include="MyAssembly" />
</ItemGroup>

Equivale all'impostazione [AssemblyMetadata("IsTrimmable", "True")] durante la compilazione dell'assembly.

Le impostazioni di granularità seguenti controllano la modalità di eliminazione dell'IL non usato in modo aggressivo. Può essere impostata come proprietà che influisce su tutti gli assembly di input trimmer o come metadati in un singolo assembly, che esegue l'override dell'impostazione della proprietà.

  • <TrimMode>link</TrimMode>

    Abilitare il trimming a livello di membro, che rimuove i membri inutilizzati dai tipi. Equivale all'impostazione predefinita in .NET 6+.

  • <TrimMode>copyused</TrimMode>

    Abilitare il trimming a livello di assembly, che mantiene un intero assembly se ne viene usata una parte (in modo statico compreso).

Gli assembly con metadati <IsTrimmable>true</IsTrimmable>, ma non espliciti TrimMode useranno l'oggetto globale TrimMode. Il valore predefinito TrimMode per Microsoft.NET.Sdk è link in .NET 6+ e copyused nelle versioni precedenti.

Eseguire il trimming sugli assembly aggiuntivi

In .NET 6+, PublishTrimmed esegue il trimming sugli assembly con l'attributo a livello di assembly seguente:

[AssemblyMetadata("IsTrimmable", "True")]

Le librerie framework hanno questo attributo. In .NET 6+, è anche possibile acconsentire esplicitamente alla rimozione di una libreria senza questo attributo, specificando l'assembly in base al nome (senza l'estensione .dll).

Impostazioni di trimming per singoli assembly

Quando si pubblica un'app tagliata, l'SDK calcola un oggetto ItemGroup denominato ManagedAssemblyToLink che rappresenta il set di file da elaborare per il trimming. ManagedAssemblyToLink può contenere metadati che controllano il comportamento di trimming per assembly. Per impostare questi metadati, creare una destinazione eseguita prima della destinazione predefinita PrepareForILLink. Nell'esempio riportato di seguito viene illustrato come abilitare il trimming di MyAssembly.

<Target Name="ConfigureTrimming"
        BeforeTargets="PrepareForILLink">
  <ItemGroup>
    <ManagedAssemblyToLink Condition="'%(Filename)' == 'MyAssembly'">
      <IsTrimmable>true</IsTrimmable>
    </ManagedAssemblyToLink>
  </ItemGroup>
</Target>

È anche possibile usarlo per eseguire l'override del comportamento di trimming specificato dall'autore della libreria, impostando <IsTrimmable>false</IsTrimmable> per un assembly con [AssemblyMetadata("IsTrimmable", "True"]).

Non aggiungere o rimuovere elementi da e verso ManagedAssemblyToLink, perché l'SDK calcola questo set durante la pubblicazione e prevede che non venga modificato. I metadati supportati sono:

  • <IsTrimmable>true</IsTrimmable>

    Controllare se sull'assembly specificato viene eseguito il trimming.

  • <TrimMode>copyused</TrimMode> oppure <TrimMode>link</TrimMode>

    Controllare la granularità di trimming di questo assembly. Questa operazione ha la precedenza sull'oggetto globale TrimMode. L'impostazione TrimMode su un assembly implica <IsTrimmable>true</IsTrimmable>.

  • <TrimmerSingleWarn>True</TrimmerSingleWarn> oppure <TrimmerSingleWarn>False</TrimmerSingleWarn>

    Controllare se visualizzare singoli avvisi per questo assembly.

Assembly radice

Se su un assembly non viene eseguito il trimming, viene considerato "rooted", il che significa che verranno mantenute tutte le relative dipendenze comprensibili in modo statico. Gli assembly aggiuntivi possono essere "rooted" per nome (senza l'estensione .dll):

<ItemGroup>
  <TrimmerRootAssembly Include="MyAssembly" />
</ItemGroup>

Descrittori radice

Un altro modo per specificare le radici per l'analisi consiste nell'usare un file XML che usa il formato del descrittore trimmer. In questo modo è possibile eseguire la radice di membri specifici anziché un intero assembly.

<ItemGroup>
  <TrimmerRootDescriptor Include="MyRoots.xml" />
</ItemGroup>

Ad esempio, MyRoots.xml potrebbe eseguire la radice di un metodo specifico a cui l'applicazione accede in modo dinamico:

<linker>
  <assembly fullname="MyAssembly">
    <type fullname="MyAssembly.MyClass">
      <method name="DynamicallyAccessedMethod" />
    </type>
  </assembly>
</linker>

Avvisi di analisi

  • <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>

    Abilitare gli avvisi di analisi di trimming.

Il trimming rimuove IL, che non è raggiungibile in modo statico. Sulle app che usano reflection o altri modelli che creano dipendenze dinamiche possono essere interrotte eseguendo il trimming. Per attivare avvisi su tali modelli, impostare su <SuppressTrimAnalysisWarnings>false. Questo includerà avvisi sull'intera app, inclusi il codice personalizzato, il codice della libreria e il codice del framework.

Analizzatori Roslyn

L'impostazione PublishTrimmed in .NET 6+ abilita anche un analizzatore Roslyn che mostra un set limitato di avvisi di analisi. È anche possibile abilitare o disabilitare l'analizzatore indipendentemente da PublishTrimmed.

  • <EnableTrimAnalyzer>true</EnableTrimAnalyzer>

    Abilitare un analizzatore Roslyn per un subset di avvisi di analisi di trimming.

Non visualizzare gli avvisi

È possibile eliminare i singoli codici di avviso usando le normali proprietà di MSBuild rispettate dalla toolchain, tra cui NoWarn, WarningsAsErrors, WarningsNotAsErrors e TreatWarningsAsErrors. È disponibile un'opzione aggiuntiva che controlla in modo indipendente il comportamento di ILLink warn-as-error:

  • <ILLinkTreatWarningsAsErrors>false</ILLinkTreatWarningsAsErrors>

    Non considerare gli avvisi ILLink come errori. Ciò può essere utile per evitare di trasformare gli avvisi di analisi di trimming in errori quando si considerano gli avvisi del compilatore come errori a livello globale.

Mostra avvisi dettagliati

In .NET 6+, l'analisi di trimming genera al massimo un avviso per ogni assembly proveniente da un PackageReference, a indicare che gli elementi interni dell'assembly non sono compatibili con il trimming. È anche possibile visualizzare singoli avvisi per tutti gli assembly:

  • <TrimmerSingleWarn>false</TrimmerSingleWarn>

    Mostra tutti gli avvisi dettagliati, invece di compressione in un singolo avviso per assembly.

Rimuovere i simboli

Sui simboli viene in genere eseguito il trimming in modo che corrispondano agli assembly su cui è stato eseguito il trimming. È anche possibile rimuovere tutti i simboli:

  • <TrimmerRemoveSymbols>true</TrimmerRemoveSymbols>

    Rimuovere i simboli dall'applicazione tagliata, inclusi i FILE PDB incorporati e i file PDB separati. Questo vale sia per il codice dell'applicazione che per le dipendenze fornite con simboli.

L'SDK consente anche di disabilitare il supporto del debugger usando la proprietà DebuggerSupport. Quando il supporto del debugger è disabilitato, il taglio rimuove automaticamente i simboli (il valore predefinito TrimmerRemoveSymbols è impostato su true).

Funzionalità della libreria framework di trimming

Diverse aree di funzionalità delle librerie framework includono direttive trimmer che consentono di rimuovere il codice per le funzionalità disabilitate.

  • <AutoreleasePoolSupport>false</AutoreleasePoolSupport> (predefinito)

    Rimuovere il codice che crea pool di versione automatica nelle piattaforme supportate. Vedere AutoreleasePool per i thread gestiti. Equivale all'impostazione predefinita per .NET SDK.

  • <DebuggerSupport>false</DebuggerSupport>

    Rimuovere il codice che consente esperienze di debug migliori. Questa impostazione rimuove anche i simboli.

  • <EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>

    Rimuovere il supporto della serializzazione BinaryFormatter. Per altre informazioni, vedere Metodi di serializzazione BinaryFormatter obsoleti.

  • <EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>

    Rimuovere il codice di codifica UTF-7 non sicuro. Per altre informazioni, vedere I percorsi di codice UTF-7 sono obsoleti.

  • <EventSourceSupport>false</EventSourceSupport>

    Rimuovere il codice o la logica correlati a EventSource.

  • <HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>

    Rimuovere il codice correlato al supporto di diagnostica per System.Net.Http.

  • <InvariantGlobalization>true</InvariantGlobalization>

    Rimuovere codice e dati specifici della globalizzazione. Per altre informazioni, vedere Modalità multiriga.

  • <MetadataUpdaterSupport>false</MetadataUpdaterSupport>

    Rimuovere la logica specifica dell'aggiornamento dei metadati correlata al ricaricamento rapido.

  • <StackTraceSupport>false</StackTraceSupport> (.NET 8+)

    Rimuovere il supporto per la generazione di tracce dello stack (ad esempio, Environment.StackTrace o Exception.ToString) dal runtime. La quantità di informazioni che verranno rimosse dalle stringhe di analisi dello stack può dipendere da altre opzioni di distribuzione. Questa opzione non influisce sulle analisi dello stack generate dai debugger.

  • <UseNativeHttpHandler>true</UseNativeHttpHandler>

    Usare l'implementazione della piattaforma predefinita di HttpMessageHandler per Android/iOS e rimuovere l'implementazione gestita.

  • <UseSystemResourceKeys>true</UseSystemResourceKeys>

    Rimuovere i messaggi di eccezione per gli assembly System.*. Quando viene generata un'eccezione da un assembly System.*, il messaggio sarà un ID risorsa semplificato anziché il messaggio completo.

Queste proprietà causano il taglio del codice correlato e disabilitano anche le funzionalità tramite il file runtimeconfig. Per altre informazioni su queste proprietà, incluse le opzioni runtimeconfig corrispondenti, vedere Opzioni delle funzionalità. Alcuni SDK possono avere valori predefiniti per queste proprietà.

Funzionalità del framework disabilitate durante il trimming

Le funzionalità seguenti non sono compatibili con il trimming perché richiedono codice non a cui viene fatto riferimento staticamente. Questi sono disabilitati per impostazione predefinita nelle app su cui è stato eseguito il trimming.

Avviso

Abilitare queste funzionalità a proprio rischio. È probabile che interrompano le app su cui è stato eseguito il trimming senza lavoro aggiuntivo per preservare il codice a cui si fa riferimento dinamicamente.

  • <BuiltInComInteropSupport>

    Il supporto COM predefinito è disabilitato.

  • <CustomResourceTypesSupport>

    L'uso di tipi di risorse personalizzati non è supportato. I percorsi di codice ResourceManager che usano la reflection per i tipi di risorse personalizzati vengono eliminati.

  • <EnableCppCLIHostActivation>

    L'attivazione dell'host C++/CLI è disabilitata.

  • <EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization>

    L'uso DesigntimeLicenseContextSerializer della serializzazione BinaryFormatter è disabilitato.

  • <StartupHookSupport>

    L'esecuzione del codice prima di Main con DOTNET_STARTUP_HOOKS non è supportata. Per ulteriori informazioni, vedere Host startup hook (Hook di avvio degli host).