トリミングのオプション

トリミングされた自己完結型の展開の動作は、MSBuild の次のプロパティと項目によって影響を受けます。 一部のオプションで示されている ILLink は、トリミングが実装されている、基になるツールの名前です。 基になるツールの詳細については、トリマーのドキュメントに関するページを参照してください。

PublishTrimmed を使用したトリミングは、.NET Core 3.0 で導入されました。 その他のオプションは、.NET 5 以降のバージョンでのみ使用できます。

トリミングを有効にする

  • <PublishTrimmed>true</PublishTrimmed>

    発行時のトリミングを有効にします。 また、この設定では、トリムと互換性のない機能がオフになり、ビルド中にトリム分析が有効になります。 .NET 8 以降のアプリでは、この設定により、構成バインドと要求デリゲート ソース ジェネレーターも有効になります。

Note

コマンド ラインからトリミングを有効に指定すると、デバッグ エクスペリエンスが異なり、最終製品で追加のバグが発生する可能性があります。

この設定をプロジェクト ファイルに配置して、設定が dotnet publish のみでなく、dotnet build 時にも適用されるようにします。

この設定により、既定ですべてのアセンブリのトリミングとトリミングが有効になります。 .NET 6 では、トリミングをオプトインしたアセンブリのみが既定でトリミング [AssemblyMetadata("IsTrimmable", "True")] されていました。 <TrimMode>partial</TrimMode> を使用して前の動作に戻ることができます。

この設定により、トリミング用に構成されているすべてのアセンブリがトリミングされます。 .NET 6 の Microsoft.NET.Sdk には、[AssemblyMetadata("IsTrimmable", "True")] を含むすべてのアセンブリが含まれます。これは .NET ランタイム アセンブリの場合です。 .NET 5 では、netcoreapp ランタイム パックからのアセンブリは、<IsTrimmable> MSBuild メタデータを使用したトリミング用に構成されています。 その他の SDK では、異なる既定値が定義されている場合があります。

この設定によってトリミング互換の Roslyn アナライザーも有効になり、トリミングと互換性のない機能は無効になります。

トリミングの最小単位

トリミングの細分性を partial または full に設定するには、 TrimModeプロパティを使用します。 コンソール アプリ (および .NET 8 以降では Web SDK アプリ) の既定の設定は、full です。

<TrimMode>full</TrimMode>

トリミングをオプトインしたアセンブリのみをトリミングするには、プロパティを partial に設定します。

<TrimMode>partial</TrimMode>

トリミング モードを partial に変更した場合は、<TrimmableAssembly> MSBuild 項目を使用して個々のアセンブリのトリミングをオプトインできます。

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

これはアセンブリのビルド時に [AssemblyMetadata("IsTrimmable", "True")] を設定することと同じです。

次の最小単位の設定により、使用されていない IL をどの程度まで破棄するかが制御されます。 これは、すべてのトリマー入力アセンブリに影響を与えるプロパティとして、またはプロパティ設定をオーバーライドする個々のアセンブリのメタデータとして設定できます。

  • <TrimMode>link</TrimMode>

    メンバー レベルのトリミングを有効にします。これにより、使用されていないメンバーが型から削除されます。 これは、.NET 6 以降の既定の設定です。

  • <TrimMode>copyused</TrimMode>

    アセンブリ レベルのトリミングを有効にします。一部でも使用されているアセンブリは、その全体が保持されます (静的に認識されます)。

<IsTrimmable>true</IsTrimmable> メタデータが設定されていても、TrimMode が明示的に設定されていないアセンブリでは、グローバルな TrimMode が使用されます。 Microsoft.NET.Sdk の既定の TrimMode は、.NET 6 以降では link で、以前のバージョンでは copyused です。

追加のアセンブリのトリミング

.NET 6 以降で PublishTrimmed を使用すると、次のアセンブリレベルの属性を持つアセンブリがトリミングされます。

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

フレームワーク ライブラリには、この属性があります。 .NET 6 以降では、この属性を使用せずにアセンブリを (.dll 拡張子を付けずに) 名前で指定して、ライブラリのトリミングをオプトインすることもできます。

個々のアセンブリのトリミング設定

トリミングされたアプリが発行されるとき、SDK では、トリミングで処理されるファイルのセットを表す、ManagedAssemblyToLink と呼ばれる ItemGroup が計算されます。 ManagedAssemblyToLink には、アセンブリごとのトリミング動作を制御するメタデータが含まれている可能性があります。 このメタデータを設定するには、組み込みの PrepareForILLink ターゲットの前に実行されるターゲットを作成します。 次の例からは、MyAssembly のトリミングを有効にする方法がわかります。

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

また、このターゲットを使用して、ライブラリの作成者が指定したトリミング動作をオーバーライドすることもできます。そのためには、次を使用してアセンブリ[AssemblyMetadata("IsTrimmable", "True"])を設定<IsTrimmable>false</IsTrimmable>します。

SDK は発行時にこのセットを計算し、変更しないことを想定しているため、項目 ManagedAssemblyToLinkを追加または削除しないでください。 サポートされているメタデータは次のとおりです。

  • <IsTrimmable>true</IsTrimmable>

    特定のアセンブリをトリミングするかどうかを制御します。

  • <TrimMode>copyused</TrimMode> または <TrimMode>link</TrimMode>

    このアセンブリのトリミングの最小単位を制御します。 このメタデータは、グローバル TrimModeに優先されます。 アセンブリで TrimMode を設定すると、<IsTrimmable>true</IsTrimmable> を示します。

  • <TrimmerSingleWarn>True</TrimmerSingleWarn>

    このアセンブリに対して単一の警告を表示するかどうかを制御します。

ルート アセンブリ

アセンブリがトリミングされていない場合は、"rooted" と見なされます。つまり、アセンブリとその静的に認識されるすべての依存関係が保持されます。 追加のアセンブリは、名前によって "ルート化" できます (拡張子なし .dll )。

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

ルート記述子

分析に対するルートを指定するもう 1 つの方法は、トリマーの記述子形式を使用する XML ファイルを使用することです。 これにより、アセンブリ全体ではなく、特定のメンバーをルートにすることができます。

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

たとえば、 MyRoots.xml アプリケーションによって動的にアクセスされる特定のメソッドをルート化できます。

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

分析の警告

  • <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>

    トリミング分析の警告を有効にします。

トリミングすると、静的に到達できない IL が削除されます。 リフレクションまたはその他のパターンを使用して動的な依存関係を作成するアプリは、トリミングによって破損する可能性があります。 そのようなパターンについて警告するには、<SuppressTrimAnalysisWarnings>false に設定します。 この設定により、独自のコード、ライブラリ コード、フレームワーク コードなど、アプリ全体に関する警告が表示されます。

Roslyn アナライザー

.NET 6 以降で PublishTrimmed を設定すると、"制限された" 分析の警告セットを示す Roslyn アナライザーも有効になります。 また、アナライザーは、PublishTrimmed とは別に有効または無効にできます。

  • <EnableTrimAnalyzer>true</EnableTrimAnalyzer>

    トリム分析の警告のサブセットに対して Roslyn アナライザーを有効にします。

警告を表示しない

NoWarnWarningsAsErrorsWarningsNotAsErrorsTreatWarningsAsErrors など、ツールチェーンによって適用される通常の MSBuild プロパティを使用して、個々の警告コードを抑制できます。 ILLink のエラーとしての警告動作を個別に制御する追加のオプションがあります。

  • <ILLinkTreatWarningsAsErrors>false</ILLinkTreatWarningsAsErrors>

    ILLink の警告をエラーとして扱いません。 これは、コンパイラの警告をエラーとしてグローバルに扱うときに、トリミング分析の警告をエラーに変えないようにする場合に役立ちます。

詳細な警告の表示

.NET 6 以降では、トリム分析によって、アセンブリの内部がトリムと互換性がないことを示す PackageReference からの警告が、アセンブリごとに最大で 1 つ生成されます。 すべてのアセンブリの個別の警告を表示することもできます。

  • <TrimmerSingleWarn>false</TrimmerSingleWarn>

    アセンブリごとに 1 つの警告に折りたたむのではなく、すべての詳細な警告を表示します。

シンボルの削除

通常、シンボルは、トリミングされたアセンブリと一致するようにトリミングされます。 すべてのシンボルを削除することもできます。

  • <TrimmerRemoveSymbols>true</TrimmerRemoveSymbols>

    埋め込み PDB や別の PDB ファイルなど、トリミングされたアプリケーションからシンボルを削除します。 これは、アプリケーションのコードと、シンボルに付属するすべての依存関係の両方に適用されます。

また、SDK では、DebuggerSupport プロパティを使用してデバッガーのサポートを無効にすることもできます。 デバッガーのサポートを無効にすると、トリミングによってシンボルが自動的に削除されます (TrimmerRemoveSymbols 既定値は true になります)。

フレームワーク ライブラリ機能のトリミング

フレームワーク ライブラリのいくつかの機能領域には、トリマー ディレクティブが付属しています。これにより、無効な機能のコードを削除できます。

  • <AutoreleasePoolSupport>false</AutoreleasePoolSupport> (既定)

    サポートされているプラットフォームで自動開放プールを作成するコードを削除します。 マネージド スレッドでの AutoreleasePool に関するページ参照してください。 これは、.NET SDK の既定です。

  • <DebuggerSupport>false</DebuggerSupport>

    デバッグ エクスペリエンスを向上させるコードを削除します。 この設定では、シンボルも削除されます

  • <EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>

    BinaryFormatter のシリアル化サポートを削除します。 詳細については、古い形式の BinaryFormatter シリアル化メソッドに関する記事を参照してください。

  • <EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>

    安全でない UTF-7 エンコード コードを削除します。 詳細については、「UTF-7 コード パスが古い形式に」を参照してください。

  • <EventSourceSupport>false</EventSourceSupport>

    EventSource に関連するコードまたはロジックを削除します。

  • <HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>

    System.Net.Http の診断サポートに関連するコードを削除します。

  • <InvariantGlobalization>true</InvariantGlobalization>

    グローバリゼーション固有のコードとデータを削除します。 詳細については、「インバリアント モード」を参照してください。

  • <MetadataUpdaterSupport>false</MetadataUpdaterSupport>

    ホット リロードに関連するメタデータの更新固有のロジックを削除します。

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

    ランタイムによるスタック トレースの生成 (Environment.StackTraceException.ToStringなど) のサポートを削除します。 スタック トレース文字列から削除される情報の量は、他のデプロイ オプションによって異なります。 このオプションは、デバッガーによって生成されるスタック トレースには影響しません。

  • <UseNativeHttpHandler>true</UseNativeHttpHandler>

    Android/iOS 用の HttpMessageHandler の既定のプラットフォーム実装を使用し、マネージド実装を削除します。

  • <UseSystemResourceKeys>true</UseSystemResourceKeys>

    System.* アセンブリの例外メッセージを削除します。 アセンブリから System.* 例外がスローされると、メッセージは完全なメッセージではなく簡略化されたリソース ID になります。

これらのプロパティを使用すると、関連するコードがトリミングされ、runtimeconfig ファイルを介して機能も無効になります。 対応する runtimeconfig オプションなど、これらのプロパティの詳細については、機能スイッチに関するページを参照してください。 一部の SDK には、これらのプロパティの既定値が設定されている場合があります。

トリミング時に無効になっているフレームワーク機能

次の機能は、静的に参照されないコードを必要とするため、トリミングと互換性がありません。 トリミングされたアプリでは、これらの機能は既定で無効になっています。

警告

これらの機能は、ご自身の責任において有効にしてください。 追加の作業を行わない場合、動的に参照されるコードを保持するために、トリミングされたアプリが破損する可能性があります。

  • <BuiltInComInteropSupport>

    組み込みの COM サポートは無効です。

  • <CustomResourceTypesSupport>

    カスタム リソースの種類の使用はサポートされていません。 カスタム リソースの種類にリフレクションを使用する ResourceManager コード パスはトリミングされます。

  • <EnableCppCLIHostActivation>

    C++/CLI ホストのアクティブ化は無効です。

  • <EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization>

    DesigntimeLicenseContextSerializerBinaryFormatter のシリアル化は無効です。

  • <StartupHookSupport>

    以前の Main コードの DOTNET_STARTUP_HOOKS 実行はサポートされていません。 詳細については、スタートアップ フックのホストに関するページをご覧ください。