Partilhar via


Passo a passo: Importar bibliotecas STL como unidades de cabeçalho

Este guia passo a passo mostra como importar bibliotecas STL (Biblioteca de Modelos Padrão) do C++ como unidades de cabeçalho no Visual Studio. Para obter uma maneira ainda mais rápida e robusta de importar a biblioteca padrão, consulte Tutorial: Importar a biblioteca padrão C++ usando módulos.

Importar um cabeçalho STL como uma unidade de cabeçalho é mais simples do que usar arquivos de cabeçalho pré-compilados. As unidades de cabeçalho são mais fáceis de configurar e usar, são significativamente menores em disco, fornecem benefícios de desempenho semelhantes e são mais flexíveis que um PCH compartilhado.

Para obter informações mais detalhadas sobre o que são unidades de cabeçalho e os benefícios fornecidos, confira O que é uma unidade de cabeçalho? Para contrastar unidades de cabeçalho com outras maneiras de importar a biblioteca padrão, consulte Comparar unidades de cabeçalho, módulos e cabeçalhos pré-compilados.

Pré-requisitos

Para usar unidades de cabeçalho, use o Visual Studio 2022 ou posterior ou o Visual Studio 2019 versão 16.11 ou posterior. A opção /std:c++20 (ou posterior) é obrigatória para usar unidades de cabeçalho.

Duas abordagens para importar cabeçalhos STL como unidades de cabeçalho

Para importar um cabeçalho STL, compile-o em uma unidade de cabeçalho. Uma unidade de cabeçalho é uma representação binária de um arquivo de cabeçalho. Ele tem uma extensão .ifc.

A abordagem recomendada é criar uma biblioteca estática que contenha as unidades de cabeçalho criadas para os cabeçalhos STL que você deseja usar. Em seguida, faça referência a essa biblioteca import e suas unidades de cabeçalho. Essa abordagem pode resultar em builds mais rápidos e melhor reutilização. Para experimentar essa abordagem, confira Abordagem 1: Criar uma biblioteca estática de unidades de cabeçalho da biblioteca STL.

Outra abordagem é fazer com que o Visual Studio examine os cabeçalhos STL que você #include em seu projeto, compilá-los em unidades de cabeçalho e import em vez #include esses cabeçalhos. Essa abordagem é útil se você tiver uma base de código grande, pois não precisa alterar o código-fonte. Essa abordagem é menos flexível do que a abordagem de biblioteca estática porque não se presta à reutilização das unidades de cabeçalho criadas em outros projetos. Porém, você ainda obtém a vantagem de desempenho da importação de bibliotecas STL individuais como unidades de cabeçalho. Para experimentar essa abordagem, confira Abordagem 2: a verificação inclui cabeçalhos STL a serem importados.

Abordagem 1: Criar uma biblioteca estática de unidades de cabeçalho da biblioteca STL

A maneira recomendada de consumir bibliotecas STL como unidades de cabeçalho é criar um ou mais projetos de biblioteca estática. Esses projetos devem consistir nas unidades de cabeçalho da biblioteca STL que você deseja usar. Em seguida, faça referência ao projeto de biblioteca para consumir essas unidades de cabeçalho STL. É semelhante ao uso de cabeçalhos pré-compilados compartilhados, porém, mais fácil.

As unidades de cabeçalho (e módulos) criadas em um projeto de biblioteca estática estão automaticamente disponíveis para referenciar projetos porque o sistema de projeto adiciona de modo automático a opção de linha de comando apropriada /headerUnit ao compilador para que os projetos de referência possam importar as unidades de cabeçalho.

Essa abordagem garante que a unidade de cabeçalho de um cabeçalho específico seja criada apenas uma vez. Ela permite importar algumas ou todas as unidades de cabeçalho, o que não é possível com um PCH. Você pode incluir unidades de cabeçalho em qualquer ordem.

No exemplo a seguir, você cria um projeto de biblioteca estática que consiste nas unidades de cabeçalho <iostream> e <vector>. Depois que a solução for criada, você fará referência a esse projeto de unidade de cabeçalho compartilhado de outro projeto C++. Em qualquer lugar em que import <iostream>; ou import <vector>; for encontrado, a unidade de cabeçalho criada para essa biblioteca será usada em vez de converter o cabeçalho com o pré-processador. Isso melhora o desempenho da compilação, como fazem os arquivos PCH, quando o mesmo cabeçalho é incluído em vários arquivos. O cabeçalho não precisará ser processado repetidamente pelos arquivos que o incluem. Em vez disso, a unidade de cabeçalho compilada já processada é importada.

Para criar uma biblioteca estática que contenha as bibliotecas <iostream> STL e <vector>, siga estas etapas:

  1. Crie um projeto vazio do C++. Nomeie-o SharedPrj.
    Selecione Projeto Vazio para C++ nos tipos de projeto disponíveis na janela Criar um novo projeto: Captura de tela que mostra a criação de um novo projeto C++ vazio.

  2. Adicione um arquivo C++ ao projeto. Altere o conteúdo do arquivo para:

    import <iostream>;
    import <vector>;
    

Definir propriedades do projeto

Defina as propriedades do projeto para compartilhar as unidades de cabeçalho deste projeto:

  1. No menu principal do Visual Studio, selecione Project>Propriedades do SharedPrj para abrir o diálogo Páginas de Propriedades do projeto: Captura de tela que mostra as configurações do Tipo de Configuração e do Padrão de Linguagem C++.
  2. Selecione Todas as Configurações na lista suspensa Configuração e Todas as Plataformas na lista suspensa Plataforma. Essas configurações garantem que suas alterações se apliquem se você estiver criando para depuração ou versão.
  3. No painel esquerdo do diálogo de Páginas de Propriedades do projeto, selecione Propriedades de Configuração>Geral.
  4. Altere a opção Tipo de Configuração para Biblioteca Estática (.lib).
  5. Altere Padrão de Linguagem C++ para ISO C++20 Standard (/std:c++20) (ou posterior).
  6. No painel esquerdo do diálogo Páginas de Propriedades do projeto, selecione Propriedades de Configuração>C/C++>Geral.
  7. Na lista suspensa Verificar Fontes de Dependências do Módulo, selecione Sim. (Essa opção faz com que o compilador examine seu código em busca de dependências que podem ser incorporadas em unidades de cabeçalho): Captura de tela que mostra a configuração da propriedade de dependências do módulo de verificação.
  8. Escolha OK para fechar o diálogo de Páginas de Propriedades do projeto. Compile a solução selecionando Compilar>Compilar Solução no menu principal.

Referenciar a biblioteca de unidade de cabeçalho

Para importar <iostream> e <vector> como unidades de cabeçalho da biblioteca estática, crie um projeto que faça referência à biblioteca estática da seguinte maneira:

  1. Com a solução atual ainda aberta, no menu do Visual Studio selecione Arquivo>Adicionar>Novo Projeto.

  2. No assistente Criar um novo projeto, selecione o modelo C++ do Aplicativo de Console e escolha Avançar.

  3. Nomeie o novo projeto Walkthrough. Altere a lista suspensa da Solução para Adicionar à solução. Escolha Criar para criar o projeto e adicioná-lo à sua solução.

  4. Altere o conteúdo do arquivo de origem Walkthrough.cpp da seguinte maneira:

    import <iostream>;
    import <vector>;
    
    int main()
    {
        std::vector<int> numbers = {0, 1, 2};
        std::cout << numbers[1];
    }
    

As unidades de cabeçalho exigem a opção /std:c++20 (ou posterior). Defina o padrão de idioma seguindo estas etapas:

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto Walkthrough e selecione Propriedades para abrir o diálogo Páginas de Propriedades do projeto: Captura de tela que mostra a configuração do padrão de linguagem para a versão de visualização.
  2. No painel esquerdo do diálogo das Páginas de Propriedades do projeto Walkthrough, selecione Propriedades de Configuração>Geral.
  3. Na lista suspensa Padrão de linguagem C++ , selecione ISO C++20 Standard (/std:c++20) (ou posterior).
  4. Escolha OK para fechar o diálogo de Páginas de Propriedades do projeto.

No projeto Guia passo a passo, adicione uma referência ao projeto SharedPrj com as seguintes etapas:

  1. No projeto Guia passo a passo, selecione o nó Referências e selecione Adicionar Referência. Selecione SharedPrj na lista de projetos: Captura de tela que mostra o diálogo Adicionar Referência. Ele é usado para adicionar uma referência ao projeto Walkthrough. Adicionar essa referência faz com que o sistema de build use as unidades de cabeçalho criadas por SharedPrj sempre que um import no projeto Walkthrough corresponder a uma das unidades de cabeçalho internas em SharedPrj.
  2. Escolha OK para fechar o diálogo Adicionar Referência.
  3. Clique com o botão direito do mouse no projeto Guia passo a passo e selecione Definir como projeto de inicialização.
  4. Compile a solução. (Use Build>Solução de build no menu principal.) Execute-a para ver se ela produz a saída esperada: 1

A vantagem dessa abordagem é que você pode referenciar o projeto de biblioteca estática de qualquer projeto para reutilizar as unidades de cabeçalho nele. Neste exemplo, a biblioteca estática contém as unidades de cabeçalho <vector> e <iostream>.

Você pode criar um projeto de biblioteca estática monolítica que contém todos os cabeçalhos STL comumente usados que você deseja importar de seus vários projetos. Você também pode criar projetos de biblioteca compartilhada menores para os diferentes agrupamentos de bibliotecas STL que você deseja importar como unidades de cabeçalho. Então faça referência a esses projetos de unidade de cabeçalho compartilhado conforme necessário.

O resultado deve ser maior taxa de transferência de build porque importar uma unidade de cabeçalho reduz significativamente o trabalho que o compilador deve fazer.

Ao usar essa abordagem com seus projetos, crie o projeto de biblioteca estática com opções de compilador compatíveis com o projeto que o referencia. Por exemplo, os projetos STL devem ser criados com a opção do /EHsc compilador para ativar o tratamento de exceções, assim como os projetos que fazem referência ao projeto de biblioteca estática.

Use /translateInclude.

A opção do compilador /translateInclude (disponível no diálogo Páginas de Propriedades do projeto em C/C++>Geral>Traduzir Inclusões para Importações) facilita o uso de uma biblioteca de unidades de cabeçalho em projetos mais antigos que #include as bibliotecas STL. Isso torna desnecessário alterar as diretivas #include para import em seu projeto, ao mesmo tempo em que oferece a vantagem de importar as unidades de cabeçalho, em vez de incluí-las.

Por exemplo, se você tiver #include <vector> em seu projeto e fizer referência a uma biblioteca estática que contenha uma unidade de cabeçalho para <vector>, não será necessário alterar #include <vector> para import <vector>; manualmente no código-fonte. Em vez disso, o compilador trata automaticamente #include <vector> como import <vector>;. Para obter mais informações sobre essa abordagem, consulte Abordagem 2: a verificação inclui cabeçalhos STL para importação. Nem todos os arquivos de cabeçalho STL podem ser compilados em uma unidade de cabeçalho. O header-units.json fornecido com o Visual Studio lista os arquivos de cabeçalho STL que podem ser compilados em unidades de cabeçalho. Um cabeçalho que depende de macros para especificar seu comportamento geralmente não pode ser compilado em uma unidade de cabeçalho.

Uma instrução #include que não se refere a uma unidade de cabeçalho é tratada como #include normal.

Reutilizar unidades de cabeçalho entre projetos

As unidades de cabeçalho criadas por um projeto de biblioteca estática estão automaticamente disponíveis para todos os projetos de referência direta e indiretamente. Há configurações de projeto que permitem selecionar quais unidades de cabeçalho devem estar automaticamente disponíveis para todos os projetos de referência. As configurações estão nas configurações do projeto em Diretórios VC++.

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Propriedades para abrir o diálogo Páginas de Propriedades do projeto.
  2. No painel esquerdo do diálogo, selecione Propriedades de Configuração>Diretórios VC++: Captura de tela que mostra as propriedades de conteúdo do projeto público, como Diretórios de Inclusão Pública e Todos os Arquivos de Cabeçalho são Públicos.

As propriedades a seguir controlam a visibilidade das unidades de cabeçalho para o sistema de build:

  • Diretórios de Inclusão Pública especificam diretórios de projeto para unidades de cabeçalho que devem ser adicionadas automaticamente ao caminho de inclusão na referência a projetos.
  • Diretórios públicos do módulo C++ especificam quais diretórios de projeto contêm unidades de cabeçalho que devem estar disponíveis para referenciar projetos. Essa propriedade permite que você torne algumas unidades de cabeçalho públicas. Ela fica visível para outros projetos, portanto, é aqui que você coloca unidades de cabeçalho que deseja compartilhar. Se você usar essa configuração, por conveniência, especifique Diretórios de Inclusão Pública para adicionar automaticamente seus cabeçalhos públicos ao caminho Incluir em projetos de referência.
  • Todos os módulos são públicos: quando você usa unidades de cabeçalho criadas como parte de um projeto de DLL, os símbolos precisarão ser exportados da DLL. Para exportar símbolos de módulo automaticamente, defina essa propriedade como Sim.

Usar um arquivo de módulo predefinido

Normalmente, a maneira mais fácil de reutilizar unidades de cabeçalho entre soluções é referenciar um projeto de unidade de cabeçalho compartilhado de cada solução.

Se você precisar usar uma unidade de cabeçalho interna para a qual você não tem o projeto, poderá especificar em que local está o arquivo .ifc compilado para que possa importá-lo em sua solução. Para acessar essa configuração:

  1. No menu principal, selecione Project>Propriedades para abrir o diálogo Páginas de Propriedades do projeto.
  2. No painel esquerdo da caixa de diálogo, selecione Propriedades de Configuração>C/C++>Geral.
  3. Em Dependências de Módulo Adicionais, adicione os módulos a serem referenciados, separados por ponto e vírgula. Veja um exemplo do formato a ser usado para Dependências de Módulo Adicionais: ModuleName1=Path\To\ModuleName1.ifc; ModuleName2=Path\To\ModuleName2.ifcCaptura de tela mostrando as propriedades de Páginas de Propriedades do projeto em Propriedades de Configuração, C/C++, Geral, com Dependências do Módulo Adicionais selecionadas.

Selecione entre várias cópias de uma unidade de cabeçalho

Se você fizer referência a projetos que criam várias unidades de cabeçalho, com o mesmo nome ou para o mesmo arquivo de cabeçalho, especifique qual delas usar. Você pode ter versões diferentes da unidade de cabeçalho criadas com configurações de compilador diferentes, por exemplo, e deve especificar aquela que corresponde às configurações do projeto.

Use a propriedade Dependências de Unidade de Cabeçalho Adicionais do projeto para resolver colisões especificando qual unidade de cabeçalho usar. Caso contrário, não será possível prever qual será escolhida.

Para definir a propriedade Dependências de Unidade de Cabeçalho Adicionais:

  1. No menu principal, selecione Project>Propriedades para abrir o diálogo Páginas de Propriedades do projeto.
  2. No painel esquerdo da caixa de diálogo, selecione Propriedades de Configuração>C/C++>Geral.
  3. Especifique quais módulos ou arquivos de unidade de cabeçalho usar em Dependências de Unidade de Cabeçalho Adicionais para resolver colisões. Use esse formato para Dependências de Unidade de Cabeçalho Adicionais: Path\To\Header1.h= Path\To\HeaderUnit1.ifc;Path\To\Header2.h= Path\To\ HeaderUnit2.ifcCaptura de tela que mostra a configuração Dependências de Unidade de Cabeçalho Adicionais no diálogo Páginas de Propriedades do projeto.

Importante

Verifique se os projetos que compartilham unidades de cabeçalho são criados com opções de compilação compatíveis. Se você usar opções de compilação ao implementar a unidade de cabeçalho diferente daquela que você usou ao criá-la, o compilador emitirá avisos.

Observação

Para usar unidades de cabeçalho criadas como parte de um projeto de DLL, defina Todos os Módulos são Públicos como Sim.

Abordagem 2: a verificação inclui os cabeçalhos STL a serem importados

Outra maneira de importar bibliotecas STL é fazer com que o Visual Studio examine os cabeçalhos STL que você #include em seu projeto e compile-os em unidades de cabeçalho. O compilador então importa, em vez de incluir esses cabeçalhos.

Essa opção é conveniente quando seu projeto inclui muitos arquivos de cabeçalho STL em muitos arquivos ou quando a taxa de transferência de build não é crítica. Essa opção não garante que uma unidade de cabeçalho para um arquivo de cabeçalho específico seja criada apenas uma vez. No entanto, será útil se você tiver uma base de código grande: você não precisa alterar o código-fonte para aproveitar os benefícios das unidades de cabeçalho para muitas das bibliotecas STL que você usa.

Essa abordagem é menos flexível do que a abordagem de biblioteca estática porque não se presta à reutilização das unidades de cabeçalho criadas em outros projetos. Essa abordagem pode não ser apropriada para projetos maiores: ela não garante um tempo de build ideal, pois todas as fontes devem ser verificadas para instruções #include.

Nem todos os arquivos de cabeçalho podem ser convertidos automaticamente em unidades de cabeçalho. Por exemplo, cabeçalhos que dependem da compilação condicional por meio de macros não devem ser convertidos em unidades de cabeçalho. Há uma lista de permitidos na forma de um arquivo header-units.json para os cabeçalhos STL que o compilador usa quando /translateInclude é especificado. Ele determina quais cabeçalhos STL podem ser compilados em unidades de cabeçalho. O arquivo header-units.json está no diretório de instalação do Visual Studio. Por exemplo, %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json. Se o arquivo de cabeçalho STL não estiver na lista, ele será tratado como um #include normal, em vez de importá-lo como uma unidade de cabeçalho. Outra vantagem do arquivo header-units.json é que ele impede a duplicação de símbolo nas unidades de cabeçalho internas. Ou seja, se a compilação de uma unidade de cabeçalho trouxer outro cabeçalho de biblioteca várias vezes, os símbolos não serão duplicados.

Para experimentar essa abordagem, crie um projeto que inclua duas bibliotecas STL. Em seguida, altere as propriedades do projeto para que ele importe as bibliotecas como unidades de cabeçalho em vez de incluí-las, conforme descrito na próxima seção.

Criar um projeto de aplicativo de console C++

Siga estas etapas para criar um projeto que inclua duas bibliotecas STL: <iostream> e <vector>.

  1. No Visual Studio, crie um projeto de aplicativo de console do C++.

  2. Substitua o conteúdo do arquivo de origem da seguinte maneira:

    #include <iostream>;
    #include <vector>;
    
    int main()
    {
        std::vector<int> numbers = {0, 1, 2};
        std::cout << numbers[1];
    }
    

Definir opções de projeto e executar o projeto

As etapas a seguir definem a opção que faz com que o compilador examine os cabeçalhos incluídos para converter em unidades de cabeçalho. Elas também definem a opção que faz com que o compilador trate #include como se você tivesse gravado import para arquivos de cabeçalho que podem ser tratados como unidades de cabeçalho.

  1. No menu principal, selecione Project>Propriedades para abrir o diálogo Páginas de Propriedades do projeto.
  2. Selecione Todas as Configurações na lista suspensa Configuração e Todas as Plataformas na lista suspensa Plataforma. Essas configurações garantem que suas alterações se apliquem se você estiver criando para depuração ou versão e outras configurações.
  3. No painel esquerdo da caixa de diálogo, selecione Propriedades de Configuração>C/C++>Geral.
  4. Defina Verificar fontes de verificação em busca de dependências de módulo como Sim. Essa configuração garante que todos os arquivos de cabeçalho compatíveis sejam compilados em unidades de cabeçalho.
  5. Defina Traduzir Inclusões para Importações para Sim. Essa configuração compila os arquivos de cabeçalho STL listados no arquivo header-unit.json como unidades de cabeçalho e os importa em vez de usar o pré-processador para #include-los. Captura de tela que mostra a configuração da propriedade de dependências do módulo de verificação nas Páginas de Propriedades do projeto.
  6. Escolha OK para salvar suas alterações e fechar o diálogo Páginas de Propriedade.

A opção /std:c++20 ou posterior é obrigatória para usar unidades de cabeçalho. Para alterar o padrão de linguagem C++ usado pelo compilador:

  1. No menu principal, selecione Project>Propriedades para abrir o diálogo Páginas de Propriedades do projeto.
  2. Selecione Todas as Configurações na lista suspensa Configuração e Todas as Plataformas na lista suspensa Plataforma. Essas configurações garantem que suas alterações se apliquem se você estiver criando para depuração ou versão e outras configurações.
  3. No painel esquerdo do diálogo de Páginas de Propriedades do projeto, selecione Propriedades de Configuração>Geral.
  4. Na lista suspensa Padrão de linguagem C++ , selecione ISO C++20 Standard (/std:c++20) (ou posterior).
  5. Escolha OK para salvar suas alterações e fechar o diálogo Páginas de Propriedade.
  6. No menu principal, compile a solução selecionando Compilar>Compilar Solução.

Execute a solução para verificar se ela produz a saída esperada: 1

A principal consideração sobre se essa abordagem deve ser usada é o equilíbrio entre a conveniência e o custo da verificação de todos os arquivos para determinar quais arquivos de cabeçalho devem ser compilados como unidades de cabeçalho.

Confira também

Comparar unidades de cabeçalho, módulos e cabeçalhos pré-compilados
Tutorial: Importar a biblioteca padrão C++ usando módulos
Guia Passo a passo: compilar e importar unidades de cabeçalho em seus projetos do Visual C++
/translateInclude