Compartilhar via


Opções de corte

As propriedades e os itens do MSBuild descritos neste artigo influenciam o comportamento de implantações cortadas e independentes. 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 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 permite a análise de corte durante a compilação. Em aplicativos .NET 8 e posteriores, essa configuração também habilita a associação de configuração e os geradores de origem de representante de solicitação.

Observação

Se você especificar o corte como habilitado 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 permite o corte e o recorte de todas as montagens por padrão. No .NET 6, somente os assemblies que optaram por cortar via [AssemblyMetadata("IsTrimmable", "True")] (adicionados em projetos que definem <IsTrimmable>true</IsTrimmable>) 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> para um assembly com [AssemblyMetadata("IsTrimmable", "True"]).

Não adicione ou remova itens do ManagedAssemblyToLink, pois 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 .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 "enraizado", o que significa que ele e todas as suas dependências estaticamente compreendidas serão mantidos. Assemblies adicionais podem ser "enraizados" por 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 fazer root em 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 IL que não é estaticamente acessível. Os aplicativos que usam reflexão ou outros padrões que criam dependências dinâmicas podem ser interrompidos pelo 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 aviso como erro do ILLink de forma independente:

  • <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 os símbolos automaticamente (TrimmerRemoveSymbols o padrão será true).

Recursos da biblioteca da 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.

Propriedade do MSBuild Descrição
AutoreleasePoolSupport Quando definido como false, remove o código que cria pools de lançamento automático em plataformas com suporte. false é o padrão para o SDK do .NET.
DebuggerSupport Quando definido como false, remove o código que permite melhores experiências de depuração. Essa configuração também remove símbolos.
EnableUnsafeBinaryFormatterSerialization Quando definido como , remove o falsesuporte à serialização BinaryFormatter. Para obter mais informações, consulte Os métodos de serialização BinaryFormatter estão obsoletos e a implementação BinaryFormatter in-box foi removida e sempre é lançada.
EnableUnsafeUTF7Encoding Quando definido como , remove o falsecódigo de codificação UTF-7 inseguro. Para obter mais informações, consulte os Caminhos de código UTF-7 obsoletos.
EventSourceSupport Quando definido como false, remove o código e a lógica relacionados ao EventSource.
HttpActivityPropagationSupport Quando definido como false, remove o código relacionado ao suporte de diagnóstico para System.Net.Http.
InvariantGlobalization Quando definido como true, remove o código e os dados específicos da globalização. Para obter mais informações, confira o Modo invariável.
MetadataUpdaterSupport Quando definido como false, remove a lógica específica da atualização de metadados relacionada ao recarregamento dinâmico.
MetricsSupport Quando definido como false, remove o suporte para System.Diagnostics.Metrics instrumentação.
StackTraceSupport (.NET 8+) Quando definido como false, remove o suporte para gerar rastreamentos de pilha (por exemplo, Environment.StackTrace ou Exception.ToString) pelo tempo de execução. A quantidade de informações 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 Quando definido como true, usa a implementação de plataforma padrão para HttpMessageHandler Android e iOS e remove a implementação gerenciada.
UseSystemResourceKeys Quando definido como true, remove mensagens de exceção para System.* assemblies. Quando uma exceção é lançada de um System.* assembly, a mensagem é uma ID de recurso simplificada em vez da mensagem completa.
XmlResolverIsNetworkingEnabledByDefault (.NET 8+) Quando definido como false, remove o suporte para resolver URLs que não são de arquivo no System.Xml. Há suporte apenas para a resolução do sistema de arquivos.

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 desativados 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 with DOTNET_STARTUP_HOOKS . Para obter mais informações, consulte gancho de inicialização do host.