Opciones de recorte

Los siguientes elementos y propiedades de MSBuild influyen en el comportamiento de implementaciones autocontenidas recortadas. Algunas de las opciones mencionan ILLink, que es el nombre de la herramienta subyacente que implementa el recorte. Para obtener más información sobre la herramienta subyacente, vea la documentación del recortador.

El recorte PublishTrimmed con se presentó en .NET Core 3.0. Las demás opciones solo están disponibles en .NET 5 y versiones posteriores.

Habilitación del recorte

  • <PublishTrimmed>true</PublishTrimmed>

    Habilite el recorte durante la publicación. Esto también desactiva las características incompatibles con el recorte y habilita el análisis de recorte durante la compilación.

Nota

Si especifica el recorte como habilitado desde la línea de comandos, la experiencia de depuración variará y es posible que encuentre errores adicionales en el producto final.

Coloque este valor en el archivo del proyecto para asegurarse de que se aplica durante dotnet build, no solo dotnet publish.

Esta configuración habilita el recorte y recortará todos los ensamblados de forma predeterminada. En .NET 6, solo los ensamblados que optaron por el recorte mediante [AssemblyMetadata("IsTrimmable", "True")] se recortan de forma predeterminada. Puede volver al comportamiento anterior mediante <TrimMode>partial</TrimMode>.

Este valor recorta todos los ensamblados que se hayan configurado para el recorte. Con Microsoft.NET.Sdk en .NET 6, se incluyen los ensamblados con [AssemblyMetadata("IsTrimmable", "True")], como sucede con los ensamblados de entorno de ejecución .NET. En .NET 5, los ensamblados del paquete en tiempo de ejecución netcoreapp se configuran para el recorte mediante los metadatos <IsTrimmable> de MSBuild. Otros SDK pueden definir diferentes valores predeterminados.

Este valor también habilita el analizador Roslyn de compatibilidad con el recorte y deshabilita las características que no son compatibles con el recorte.

Granularidad del recorte

Use la propiedad TrimMode para establecer la granularidad de recorte en partial o full. La configuración predeterminada para las aplicaciones de consola (y, a partir de .NET 8, aplicaciones del SDK web) es full:

<TrimMode>full</TrimMode>

Para recortar solo los ensamblados que han optado por el recorte, establezca la propiedad en partial:

<TrimMode>partial</TrimMode>

Si cambia el modo de recorte a partial, puede participar en ensamblados individuales para recortar mediante un elemento de MSBuild <TrimmableAssembly>.

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

Esto equivale a establecer [AssemblyMetadata("IsTrimmable", "True")] al compilar el ensamblado.

La siguiente configuración de granularidad controla la agresividad con la que se descarta el IL sin usar. Esto se puede establecer como una propiedad que afecta a todos los ensamblados de entrada del recortador, o bien como metadatos en un ensamblado individual, lo que invalida el establecimiento de la propiedad.

  • <TrimMode>link</TrimMode>

    Habilite el recorte a nivel de miembro, lo que quita los miembros sin usar de los tipos. Este es el valor predeterminado en .NET 6+.

  • <TrimMode>copyused</TrimMode>

    Habilita el recorte en el nivel de ensamblado, lo que mantendrá un ensamblado completo si se usa cualquier parte de este (de manera estática).

Los ensamblados con metadatos de <IsTrimmable>true</IsTrimmable>, pero sin un valor de TrimMode explícito, usarán el valor global de TrimMode. El valor TrimMode predeterminado de Microsoft.NET.Sdk es link en .NET 6+, y copyused en versiones anteriores.

Recorte de ensamblados adicionales

En .NET 6 y versiones posteriores, PublishTrimmed recorta los ensamblados con el atributo de nivel de ensamblado siguiente:

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

Las bibliotecas de marco tienen este atributo. En .NET 6+, también puede optar por recortar una biblioteca sin este atributo, si especifica el ensamblado por nombre (sin la extensión .dll).

Configuración de recorte de ensamblados individuales

Al publicar una aplicación recortada, el SDK calcula un elemento ItemGroup llamado ManagedAssemblyToLink que representa el conjunto de archivos que se va a procesar para el recorte. ManagedAssemblyToLink puede tener metadatos que controlan el comportamiento de recorte por ensamblado. Para establecer estos metadatos, cree un destino que se ejecute antes del destino PrepareForILLink integrado. En el ejemplo siguiente se muestra cómo habilitar el recorte de MyAssembly.

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

También puede usarlo para invalidar el comportamiento de recorte especificado por el creador de la biblioteca, si establece <IsTrimmable>false</IsTrimmable> para un ensamblado con [AssemblyMetadata("IsTrimmable", "True"]).

No agregue ni quite elementos de ManagedAssemblyToLink, porque el SDK procesa este conjunto durante la publicación y espera que no cambie. Los metadatos admitidos son:

  • <IsTrimmable>true</IsTrimmable>

    Controle si se ha recortado el ensamblado especificado.

  • <TrimMode>copyused</TrimMode> o <TrimMode>link</TrimMode>

    Controle la granularidad del recorte de este ensamblado. Esto tiene prioridad sobre el valor global de TrimMode. La configuración del valor TrimMode en un ensamblado implica <IsTrimmable>true</IsTrimmable>.

  • <TrimmerSingleWarn>True</TrimmerSingleWarn> o <TrimmerSingleWarn>False</TrimmerSingleWarn>

    Controle si se muestran advertencias únicas para este ensamblado.

Ensamblados raíz

Si un ensamblado no se recorta, se considera "enraizado", lo que significa que se conservarán tanto este como todas sus dependencias estáticas. Se pueden "enraizar" ensamblados adicionales por nombre (sin la extensión .dll):

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

Descriptores raíz

Otra manera de especificar las raíces para el análisis consiste en usar un archivo XML que use el formato de descriptor del recortador. Esto le permite enraizar miembros específicos en lugar de un ensamblado completo.

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

Por ejemplo, MyRoots.xml podría enraizar un método específico al que la aplicación tiene acceso dinámicamente:

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

Advertencias de análisis

  • <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>

    Habilite las advertencias de análisis de recorte.

El recorte quita el IL que no es accesible estáticamente. Las aplicaciones que usan reflexión u otros patrones que crean dependencias dinámicas pueden romperse mediante el recorte. Para advertir sobre tales patrones, configure <SuppressTrimAnalysisWarnings> en false. Esto incluirá advertencias sobre toda la aplicación, incluidas las de su propio código, del código de la biblioteca y del código del marco.

Analizador de Roslyn

Al establecer PublishTrimmed en .NET 6+ también se habilita un analizador de Roslyn que muestra un conjunto limitado de advertencias de análisis. También puede habilitar o deshabilitar el analizador independientemente de PublishTrimmed.

  • <EnableTrimAnalyzer>true</EnableTrimAnalyzer>

    Habilite un analizador de Roslyn para un subconjunto de advertencias de análisis de recorte.

Suprimir advertencias

Puede suprimir los códigos de advertencia individuales mediante las propiedades de MSBuild habituales que respeta la cadena de herramientas, incluidas NoWarn, WarningsAsErrors, WarningsNotAsErrors y TreatWarningsAsErrors. Existe una opción adicional que controla el comportamiento de advertencia como error de ILLink de forma independiente:

  • <ILLinkTreatWarningsAsErrors>false</ILLinkTreatWarningsAsErrors>

    No trate las advertencias de ILLink como errores. Esto puede ser útil para evitar convertir advertencias de análisis de recorte en errores cuando se tratan las advertencias del compilador como errores globalmente.

Representación de advertencias detalladas

En .NET 6+, el análisis de recorte genera como máximo una advertencia para cada ensamblado que procede de un objeto PackageReference, lo que indica que los aspectos internos del ensamblado no son compatibles con el recorte. También puede mostrar advertencias individuales para todos los ensamblados:

  • <TrimmerSingleWarn>false</TrimmerSingleWarn>

    Se muestran todas las advertencias detalladas, en lugar de contraerlas en una única advertencia por ensamblado.

Eliminación de símbolos

Normalmente, los símbolos se recortan para que coincidan con los ensamblados recortados. También puede quitar todos los símbolos:

  • <TrimmerRemoveSymbols>true</TrimmerRemoveSymbols>

    Quite los símbolos de la aplicación recortada, incluidos los archivos PDB incrustados y los archivos PDB independientes. Esto se aplica tanto al código de la aplicación como a las dependencias de los símbolos.

El SDK también permite deshabilitar la compatibilidad del depurador con la propiedad DebuggerSupport. Cuando la compatibilidad con el depurador está deshabilitada, el recorte quitará los símbolos automáticamente (el valor predeterminado de TrimmerRemoveSymbols se establece en "true").

Características de recorte de las bibliotecas de marco

Varias áreas de características de las bibliotecas de marco incluyen directivas de recortador que permiten eliminar el código de las características deshabilitadas.

  • <AutoreleasePoolSupport>false</AutoreleasePoolSupport> (valor predeterminado)

    Quite el código que crea grupos de liberación automática en las plataformas admitidas. Vea AutoreleasePool para subprocesos administrados. Este es el valor predeterminado para el SDK de .NET.

  • <DebuggerSupport>false</DebuggerSupport>

    Elimina código que permite mejores experiencias de depuración. Esta configuración también quita símbolos.

  • <EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>

    Elimina la compatibilidad con la serialización BinaryFormatter. Para obtener más información, consulte la sección Métodos de serialización BinaryFormatter obsoletos.

  • <EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>

    Elimina el código de codificación UTF-7 poco seguro. Para obtener más información, vea la sección Rutas de acceso al código UTF-7 obsoletas.

  • <EventSourceSupport>false</EventSourceSupport>

    Elimina el código o la lógica relacionados con EventSource.

  • <HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>

    Elimina el código relacionado con la compatibilidad de diagnóstico para System.Net.Http.

  • <InvariantGlobalization>true</InvariantGlobalization>

    Elimina el código y los datos específicos de la globalización. Para obtener más información, consulte Modo invariable.

  • <MetadataUpdaterSupport>false</MetadataUpdaterSupport>

    Quite la lógica específica de actualización de metadatos relacionada con la recarga frecuente.

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

    Quite la compatibilidad con la generación de seguimientos de pila (por ejemplo, Environment.StackTraceo Exception.ToString) por el tiempo de ejecución. La cantidad de información que se quitará de las cadenas de seguimiento de pila puede depender de otras opciones de implementación. Esta opción no afecta a los seguimientos de pila generados por los depuradores.

  • <UseNativeHttpHandler>true</UseNativeHttpHandler>

    Use la implementación de plataforma predeterminada de HttpMessageHandler para Android/iOS y quite la implementación administrada.

  • <UseSystemResourceKeys>true</UseSystemResourceKeys>

    Elimina los mensajes de excepción para los ensamblados de System.*. Cuando un ensamblado de System.* produzca una excepción, el mensaje será un identificador de recurso simplificado en lugar del mensaje completo.

Estas propiedades hacen que el código relacionado se recorte y también deshabilitan las características a través del archivo runtimeconfig. Para obtener más información sobre estas propiedades, incluidas las opciones de runtimeconfig correspondientes, vea modificadores de características. Algunos SDK pueden tener valores predeterminados para estas propiedades.

Características del marco deshabilitadas al recortar

Las características siguientes no son compatibles con el recorte porque necesitan código al que no se le haga referencia de forma estática. Están deshabilitadas de forma predeterminada en las aplicaciones recortadas.

Advertencia

Habilite estas características por su cuenta y riesgo. Es probable que se interrumpan las aplicaciones recortadas sin trabajo adicional para conservar el código al que se hace referencia de forma dinámica.

  • <BuiltInComInteropSupport>

    La compatibilidad integrada con COM está deshabilitada.

  • <CustomResourceTypesSupport>

    No se admite el uso de tipos de recursos personalizados. Se recortan las rutas de acceso al código de ResourceManager que usan la reflexión para los tipos de recursos personalizados.

  • <EnableCppCLIHostActivation>

    La activación del host de C++/CLI está deshabilitada.

  • <EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization>

    Se ha deshabilitado el uso de la serialización BinaryFormatter en DesigntimeLicenseContextSerializer.

  • <StartupHookSupport>

    No se admite la ejecución de código anterior a Main con DOTNET_STARTUP_HOOKS. Para obtener más información, vea Hospedaje del enlace de inicio.