次の方法で共有


.NET MAUI Mac Catalyst アプリのリンク

アプリをビルドするときに、.NET Multi-Platform App UI (.NET MAUI) で呼び出された ILLink というリンカーを使用して、アプリの全体的なサイズを小さくできます。 ILLink は、コンパイラによって生成された中間コードを分析することによってサイズを小さくします。 使用されていないメソッド、プロパティ、フィールド、イベント、構造体、クラスを削除して、アプリの実行に必要なコードとアセンブリの依存関係のみを含むアプリを生成します。

リンカーの動作

リンカーは、iOS と Mac Catalyst 上の .NET MAUI アプリに対して次の 3 つのモードをサポートしています。

  • リンクしない リンクを無効にすると、アセンブリが変更されないようにします。
  • SDK アセンブリのみをリンクする このモードでは、リンカーはアセンブリをそのまま残し、アプリで使用しない型とメンバーを削除することで、SDK アセンブリのサイズを小さくします。
  • すべてのアセンブリをリンクする すべてのアセンブリをリンクすると、リンカーは追加の最適化を実行して、アプリをできるだけ小さくします。 ソース コードの中間コードが変更されます。リンカーの静的分析では検出できないアプローチを使用した機能を使用すると、アプリが中断する可能性があります。 このような場合は、アプリを正しく動作させるために、ソース コードの調整が必要になる場合があります。

リンカーの動作は、アプリのビルド構成ごとに構成できます。

警告

アプリのデバッグ構成に対してリンカーを有効にすると、オブジェクトの状態を検査できるプロパティ アクセサーが削除される可能性があるため、デバッグ エクスペリエンスが妨げられる可能性があります。

Visual Studio Code でリンカーの動作を構成するには、$(MtouchLink) ビルド プロパティをアプリの .csproj ファイル内のプロパティ グループに追加する必要があります。 このビルド プロパティは、NoneSdkOnly または Full に設定する必要があります。

<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0-maccatalyst|AnyCPU'">
  <MtouchLink>SdkOnly</MtouchLink>
</PropertyGroup>

または、アプリをビルドして発行するときに、CLI を使用してリンカーの動作を指定することもできます。 詳細については、「.NET MAUI Mac Catalyst アプリを発行する」をご覧ください。

重要

$(MtouchLink) ビルド プロパティは、アプリのビルド構成ごとに個別に設定できます。

コードを保持する

トリマを使用すると、動的に呼び出した可能性のあるコードが、間接的に削除されることがあります。 属性を使用してメンバーに注釈を付けることで、メンバーを保持するようにトリマーに DynamicDependency 指示できます。 この属性は、メンバーの型とサブセット、または特定のメンバーへの依存関係を表すために使用できます。

重要

アプリで使用されると静的に判断できない BCL 内のすべてのメンバーが削除される可能性があります。

DynamicDependency 属性は、コンストラクター、フィールド、メソッドに適用できます。

[DynamicDependency("Helper", "MyType", "MyAssembly")]
static void RunHelper()
{
    var helper = Assembly.Load("MyAssembly").GetType("MyType").GetMethod("Helper");
    helper.Invoke(null, null);
}

この例では、DynamicDependencyHelper メソッドが保持されていることを確認します。 属性がない場合、トリミングは他の場所からHelper参照されていない場合は完全に削除MyAssemblyMyAssemblyされます。

この属性では、string または DynamicallyAccessedMembers 属性を介して保持するメンバーを指定します。 型とアセンブリは、属性コンテキスト内で暗黙的に指定されるか、または属性内で明示的に指定されます (Type によって、または型とアセンブリ名の場合は string によって)。

型とメンバーの文字列では、C# ドキュメントのコメント ID 文字列の形式 のバリエーションを、メンバー プレフィックスなしで使用します。 メンバー文字列には、宣言する型の名前を含めることはできません。指定した名前のすべてのメンバーを保持するにはパラメーターを省略してかまいません。 次の例は、有効な用途を示しています。

[DynamicDependency("Method()")]
[DynamicDependency("Method(System,Boolean,System.String)")]
[DynamicDependency("MethodOnDifferentType()", typeof(ContainingType))]
[DynamicDependency("MemberName")]
[DynamicDependency("MemberOnUnreferencedAssembly", "ContainingType", "UnreferencedAssembly")]
[DynamicDependency("MemberName", "Namespace.ContainingType.NestedType", "Assembly")]
// generics
[DynamicDependency("GenericMethodName``1")]
[DynamicDependency("GenericMethod``2(``0,``1)")]
[DynamicDependency("MethodWithGenericParameterTypes(System.Collections.Generic.List{System.String})")]
[DynamicDependency("MethodOnGenericType(`0)", "GenericType`1", "UnreferencedAssembly")]
[DynamicDependency("MethodOnGenericType(`0)", typeof(GenericType<>))]

アセンブリを保持する

他のアセンブリをトリミングできるようにしながら、トリミング プロセスから除外するアセンブリを指定できます。 この方法は、属性を簡単に DynamicDependency 使用できない場合や、トリミングされるコードを制御できない場合に役立ちます。

すべてのアセンブリをトリミングするときに、プロジェクト ファイルで MSBuild 項目を設定 TrimmerRootAssembly することで、アセンブリをスキップするようにトリマーに指示できます。

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

Note

.dll MSBuild プロパティを設定するときに、TrimmerRootAssembly 拡張機能は必要ありません。

トリマーがアセンブリをスキップすると、ルート化されたと見な されます。つまり、そのアセンブリとその静的に認識されたすべての依存関係が保持されます。 TrimmerRootAssembly<ItemGroup> MSBuild プロパティを追加することで、追加のアセンブリをスキップできます。

アセンブリ、型、メンバーを保持する

保持する必要があるアセンブリ、型、およびメンバーを指定する XML 記述ファイルをトリマーに渡すことができます。

すべてのアセンブリをトリミングするときにメンバーをトリミング プロセスから除外するには、プロジェクト ファイル内の TrimmerRootDescriptor MSBuild 項目を、除外するメンバーを定義する XML ファイルに設定します。

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

その後、XML ファイルはトリマ 記述子形式 を使用して、除外するメンバーを定義します。

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

この例では、XML ファイルは、トリミングから除外される、アプリによって動的にアクセスされるメソッドを指定します。

アセンブリ、型、またはメンバーが XML にリストされている場合、既定のアクションは保持です。つまり、トリマーが使用されていると見なすかどうかにかかわらず、出力に保持されます。

Note

保持タグはあいまいに包括的です。 次のレベルの詳細を指定しない場合は、すべての子が含まれます。 アセンブリが型なしで一覧表示されている場合は、アセンブリのすべての型とメンバーが保持されます。

アセンブリをトリム セーフとしてマークする

プロジェクトにライブラリがある場合、または再利用可能なライブラリの開発者で、トリマでアセンブリをトリミング可能として扱いたい場合は、アセンブリのプロジェクト ファイルに MSBuild プロパティを追加 IsTrimmable することで、アセンブリをトリム セーフとしてマークできます。

<PropertyGroup>
    <IsTrimmable>true</IsTrimmable>
</PropertyGroup>

これにより、アセンブリが「トリミング可能」としてマークされ、そのプロジェクトに対するトリミングの警告が有効になります。 「トリミング可能」とは、ライブラリがトリミングと互換性があると見なされ、ライブラリのビルド時にトリミングの警告が発生しないはずであることを意味します。 トリミングされたアプリで使用されたとき、最終的な出力において、アセンブリではその未使用のメンバーが削除されます。

.NET 9 以降でネイティブ AOT 展開を使用する場合、IsAotCompatible MSBuild プロパティを true に設定すると、true の値も IsTrimmable プロパティに割り当てられ、追加の AOT アナライザーのビルド プロパティが有効になります。 AOT アナライザーの詳細については、「AOT 互換性アナライザーの」を参照してください。 .NET MAUI のネイティブ AOT デプロイの詳細については、「Native AOT deployment」を参照してください。

プロジェクト ファイルで IsTrimmable MSBuild プロパティを true に設定すると、アセンブリに AssemblyMetadata 属性が挿入されます。

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

または、アセンブリのプロジェクト ファイルに AssemblyMetadata MSBuild プロパティを追加せずに、アセンブリに IsTrimmable 属性を追加することもできます。

Note

アセンブリに対して IsTrimmable MSBuild プロパティが設定されている場合は、AssemblyMetadata("IsTrimmable", "True") 属性がオーバーライドされます。 これにより、属性がない場合でもアセンブリのトリミングを選択したり、属性を持つアセンブリのトリミングを無効にしたりすることができます。

分析の警告を抑制する

トリマーが有効になっていると、静的に到達できない IL が削除されます。 リフレクションまたは動的な依存関係を作成するその他のパターンを使用するアプリは、結果として壊れることがあります。 このようなパターンに関する警告を表示するには、アセンブリをトリム セーフとしてマークする場合、ライブラリ作成者は MSBuild プロパティを SuppressTrimAnalysisWarnings 次のように設定する false必要があります。

<PropertyGroup>
  <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
</PropertyGroup>

トリミング分析の警告を抑制しない場合、独自のコード、ライブラリ コード、SDK コードを含む、アプリ全体に関する警告が含まれます。

詳細な警告の表示

トリミング分析では、アセンブリの内部構造とトリミングに互換性がないことを示す PackageReference からの警告が、アセンブリごとに最大で 1 つ生成されます。 ライブラリの作成者として、アセンブリをトリム セーフとしてマークする場合は、MSBuild プロパティを次のように設定して、すべてのアセンブリに対して個別の TrimmerSingleWarn 警告を有効にする false必要があります。

<PropertyGroup>
  <TrimmerSingleWarn>false</TrimmerSingleWarn>
</PropertyGroup>

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