Opções de corte

As propriedades e itens do MSBuild a seguir influenciam o comportamento das implantações autossuficientes cortadas. Algumas das opções mencionam ILLink, que é o nome da ferramenta subjacente que implementa o corte. Para obter mais informações sobre a ferramenta subjacente, consulte a Documentação do filtro.

O corte com PublishTrimmed foi introduzido no .NET Core 3.0. As outras opções estão disponíveis apenas no .NET 5 e versões posteriores.

Habilitar a filtragem

  • <PublishTrimmed>true</PublishTrimmed>

    Habilite a filtragem durante a publicação. Essa configuração também desativa os recursos incompatíveis com o corte e habilita a análise de corte durante a compilação. Em aplicativos .NET 8 e posteriores, essa configuração também habilita a vinculação de configuração e a solicitação delegar geradores de origem.

Observação

Se você especificar a filtragem como habilitada na linha de comando, sua experiência de depuração será diferente e você poderá encontrar bugs adicionais no produto final.

Coloque essa configuração no arquivo de projeto para garantir que a configuração se aplique durante dotnet build, não apenas dotnet publish.

Essa configuração habilita o corte e corta todos os assemblies por padrão. No .NET 6, somente os assemblies que optaram pelo corte por meio [AssemblyMetadata("IsTrimmable", "True")] foram cortados por padrão. Você pode retornar ao comportamento anterior usando <TrimMode>partial</TrimMode>.

Essa configuração corta todos os assemblies que foram configurados para corte. Com Microsoft.NET.Sdk no .NET 6, isso inclui todos os assemblies com [AssemblyMetadata("IsTrimmable", "True")], que é o caso dos assemblies de runtime .NET. No .NET 5, os assemblies do pacote de runtime do netcoreapp são configurados para corte pelos metadados do MSBuild <IsTrimmable>. Outros SDKs podem definir padrões diferentes.

Essa configuração também habilita o analisador Roslyn de compatibilidade de corte e desabilita os recursos incompatíveis com o corte.

Granularidade da filtragem

Utilize a propriedade TrimMode para definir a granularidade do corte como partial ou full. A configuração padrão para aplicativos de console (e, a partir do .NET 8, aplicativos SDK da Web) é full:

<TrimMode>full</TrimMode>

Para cortar somente assemblies que optaram pelo corte, defina a propriedade como partial:

<TrimMode>partial</TrimMode>

Se o modo de corte for alterado para partial, você poderá optar pelo corte de assemblies individuais utilizando um item <TrimmableAssembly> do MSBuild.

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

Isso é equivalente à configuração [AssemblyMetadata("IsTrimmable", "True")] ao criar o assembly.

As configurações de granularidade a seguir controlam a agressividade com a qual um IL não utilizado é descartado. Isso pode ser definido como uma propriedade que afeta todos os assemblies de entrada do filtro ou como metadados em um assembly individual, substituindo a configuração da propriedade.

  • <TrimMode>link</TrimMode>

    Habilite o corte no nível do membro, que remove membros não utilizados dos tipos. Essa é a opção padrão no .NET 6+.

  • <TrimMode>copyused</TrimMode>

    Habilite o corte no nível do assembly, que mantém um assembly inteiro se qualquer parte dele for usada (de uma maneira estaticamente compreendida).

Assemblies com metadados <IsTrimmable>true</IsTrimmable>, mas nenhum TrimMode explícito usará a TrimMode global. O TrimMode padrão de Microsoft.NET.Sdk é link no .NET 6+ e copyused nas versões anteriores.

Assemblies adicionais de corte

No .NET 6+, PublishTrimmed corta assemblies com o seguinte atributo de nível de assembly:

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

As bibliotecas de estrutura têm esse atributo. No .NET 6+, você também pode cortar uma biblioteca sem esse atributo, especificando o assembly por nome (sem a extensão .dll).

Configurações de corte para assemblies individuais

Ao publicar um aplicativo cortado, o SDK calcula um ItemGroup chamado ManagedAssemblyToLink que representa o conjunto de arquivos a serem processados para corte. ManagedAssemblyToLink pode ter metadados que controlam o comportamento de corte por assembly. Para definir esses metadados, crie um destino que execute antes do destino PrepareForILLink interno. O exemplo a seguir mostra como habilitar o corte de MyAssembly.

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

Você também pode usar esse destino para substituir o comportamento de corte especificado pelo autor da biblioteca, definindo <IsTrimmable>false</IsTrimmable> um assembly com [AssemblyMetadata("IsTrimmable", "True"]).

Não adicione ou remova itens do ManagedAssemblyToLink, porque o SDK calcula esse conjunto durante a publicação e espera que ele não seja alterado. Os metadados com suporte são:

  • <IsTrimmable>true</IsTrimmable>

    Controlar se o assembly fornecido é cortado.

  • <TrimMode>copyused</TrimMode> ou <TrimMode>link</TrimMode>

    Controlar a granularidade de corte deste assembly. Esses metadados têm precedência sobre o global TrimMode. A configuração de TrimMode em um assembly implica <IsTrimmable>true</IsTrimmable>.

  • <TrimmerSingleWarn>True</TrimmerSingleWarn>

    Controlar se os avisos únicos devem ser mostrados para este assembly.

Assemblies raiz

Se um assembly não for cortado, ele será considerado "rooteado", o que significa que ele e todas as suas dependências compreendidas estaticamente serão mantidas. Assemblies adicionais podem ser "rooteados" pelo nome (sem a .dll extensão):

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

Descritores raiz

Outra maneira de especificar raízes para análise é usar um arquivo XML que usa o formato de descritor de filtro. Isso permite enraizar membros específicos em vez de um assembly inteiro.

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

Por exemplo, MyRoots.xml pode criar um método específico que é acessado dinamicamente pelo aplicativo:

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

Avisos da análise

  • <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>

    Habilite avisos de análise de corte.

O corte remove a IL que não é estaticamente alcançável. Aplicativos que usam reflexão ou outros padrões que criam dependências dinâmicas podem ser quebrados por corte. Para alertar sobre esses padrões, defina <SuppressTrimAnalysisWarnings> como false. Essa configuração exibirá avisos sobre todo o aplicativo, incluindo seu próprio código, código de biblioteca e código de estrutura.

Analisador Roslyn

A configuração PublishTrimmed no .NET 6+ também habilita um analisador Roslyn que mostra um conjunto limitado de avisos de análise. Você também pode habilitar ou desabilitar o analisador independentemente de PublishTrimmed.

  • <EnableTrimAnalyzer>true</EnableTrimAnalyzer>

    Habilite um analisador Roslyn para um subconjunto de avisos de análise de corte.

Suprimir avisos

Você pode suprimir códigos de aviso individuais usando as propriedades habituais do MSBuild respeitadas pela cadeia de ferramentas, incluindo NoWarn, WarningsAsErrors, WarningsNotAsErrors e TreatWarningsAsErrors. Há uma opção adicional que controla o comportamento de advertência como erro ILLink independentemente:

  • <ILLinkTreatWarningsAsErrors>false</ILLinkTreatWarningsAsErrors>

    Não trate os avisos do ILLink como erros. Isso pode ser útil para evitar transformar avisos de análise de corte em erros ao tratar avisos do compilador como erros globalmente.

Mostrar avisos detalhados

No .NET 6+, a análise de corte produz no máximo um aviso para cada assembly proveniente de um PackageReference, indicando que os internos do assembly não são compatíveis com o corte. Você também pode exibir avisos individuais para todos os assemblies:

  • <TrimmerSingleWarn>false</TrimmerSingleWarn>

    Exiba todos os avisos detalhados, em vez de recolhê-los em um único aviso por assembly.

Remover símbolos

Os símbolos geralmente são cortados para corresponder aos assemblies cortados. Você também pode remover todos os símbolos:

  • <TrimmerRemoveSymbols>true</TrimmerRemoveSymbols>

    Remova os símbolos do aplicativo cortado, incluindo PDBs inseridos e arquivos PDB separados. Isso se aplica ao código do aplicativo e a todas as dependências com símbolos.

O SDK também possibilita desabilitar o suporte ao depurador usando a propriedade DebuggerSupport. Quando o suporte ao depurador está desabilitado, o corte remove símbolos automaticamente (TrimmerRemoveSymbols o padrão será true).

Recursos da biblioteca de estrutura de corte

Diversas áreas de recursos das bibliotecas de estrutura possuem diretivas de filtro que possibilitam a remoção do código para recursos desabilitados.

  • <AutoreleasePoolSupport>false</AutoreleasePoolSupport> (padrão)

    Remova o código que cria pools de liberação automática em plataformas com suporte. Consulte AutoreleasePool para threads gerenciados. Esse é o padrão para o .NET SDK.

  • <DebuggerSupport>false</DebuggerSupport>

    Remova o código que permite melhores experiências de depuração. Essa configuração também remove símbolos.

  • <EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>

    Remova o suporte à serialização BinaryFormatter. Para obter mais informações, consulte Os métodos de serialização BinaryFormatter estão obsoletos.

  • <EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>

    Remova o código inseguro da codificação UTF-7. Para obter mais informações, consulte os Caminhos de código UTF-7 obsoletos.

  • <EventSourceSupport>false</EventSourceSupport>

    Remova o código ou a lógica relacionados ao EventSource.

  • <HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>

    Remova o código relacionado ao suporte de diagnóstico para System.Net.Http.

  • <InvariantGlobalization>true</InvariantGlobalization>

    Remova o código e os dados específicos da globalização. Para obter mais informações, confira o Modo invariável.

  • <MetadataUpdaterSupport>false</MetadataUpdaterSupport>

    Remova a lógica específica de atualização de metadados relacionada ao recarregamento frequente.

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

    Remova o suporte para gerar rastreamentos de pilha (por exemplo, Environment.StackTrace ou Exception.ToString) pelo runtime. A quantidade de informações que serão removidas das cadeias de caracteres de rastreamento de pilha pode depender de outras opções de implantação. Essa opção não afeta os rastreamentos de pilha gerados pelos depuradores.

  • <UseNativeHttpHandler>true</UseNativeHttpHandler>

    Use a implementação de plataforma padrão de HttpMessageHandler para Android/iOS e remova a implementação gerenciada.

  • <UseSystemResourceKeys>true</UseSystemResourceKeys>

    Remova mensagens de exceção para assemblies System.*. Quando uma exceção é lançada de um System.* assembly, a mensagem é uma ID de recurso simplificada em vez da mensagem completa.

Essas propriedades fazem com que o código relacionado seja cortado e também desabilite os recursos pelo arquivo runtimeconfig. Para obter mais informações sobre essas propriedades, incluindo as opções de runtimeconfig correspondentes, consulte as opções de recurso. Alguns SDKs podem ter valores padrão para essas propriedades.

Recursos da estrutura desabilitados no corte

Os recursos a seguir são incompatíveis com o corte porque exigem código que não é referenciado estaticamente. Esses recursos são desabilitados por padrão em aplicativos cortados.

Aviso

A habilitação desses recursos será por sua conta e risco. É provável que eles interrompa aplicativos cortados sem trabalho adicional para preservar o código referenciado dinamicamente.

  • <BuiltInComInteropSupport>

    O suporte interno para COM está desabilitado.

  • <CustomResourceTypesSupport>

    Não há suporte para o uso de tipos de recursos personalizados. Os caminhos de código do ResourceManager que usam reflexão para tipos de recursos personalizados são cortados.

  • <EnableCppCLIHostActivation>

    A ativação do host C++/CLI está desabilitada.

  • <EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization>

    O uso de DesigntimeLicenseContextSerializer da serialização BinaryFormatter está desabilitado.

  • <StartupHookSupport>

    Não há suporte para a execução de código antes Main de com DOTNET_STARTUP_HOOKS . Para obter mais informações, consulte gancho de inicialização do host.