Compartilhar 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 substancialmente menores em disco, oferecem benefícios de desempenho semelhantes e são mais flexíveis do que um PCH compartilhado.

Para obter informações mais detalhadas sobre o que são unidades de cabeçalho e os benefícios que elas oferecem, consulte 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 /std:c++20 opção (ou posterior) é necessá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 compilações mais rápidas 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, porque você não precisa alterar seu código-fonte. Essa abordagem é menos flexível do que a abordagem de biblioteca estática, porque não se presta a reutilizar as unidades de cabeçalho criadas em outros projetos. Mas, você ainda obtém a vantagem de desempenho de importar 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 aos projetos 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. Ele melhora o desempenho da compilação, como 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 : Screenshot that shows creating a new empty C++ project.

  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 Propriedades SharedPrj do projeto para abrir a caixa de diálogo Páginas de propriedades do projeto>:Screenshot that shows settings for Configuration Type and C++ Language Standard.
  2. Selecione Todas as configurações na lista suspensa Configuração e, em seguida, selecione Todas asplataformas na lista suspensa Plataforma. Essas configurações garantem que suas alterações se apliquem se você estiver criando para depuração ou lançamento.
  3. No painel esquerdo da caixa de diálogo 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 o C++ Language Standard para ISO C++20 Standard (/std:c++20) (ou posterior).
  6. No painel esquerdo da caixa de diálogo Páginas de propriedades do projeto, selecione Propriedades>de configuração C/C++>General.
  7. Na lista suspensa Verificar fontes de dependências de módulo, selecione Sim. (Essa opção faz com que o compilador verifique seu código em busca de dependências que podem ser criadas em unidades de cabeçalho): Screenshot that shows the scan module dependencies property setting.
  8. Escolha OK para fechar a caixa de diálogo 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 Aplicativo de Console C++ e escolha Avançar.

  3. Nomeie o novo projeto como Passo a passo. Altere o menu suspenso 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 Passo a passo.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 requerem a /std:c++20 opção (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 Passo a passo e selecione Propriedades para abrir a caixa de diálogo Páginas de Propriedades do projeto:Screenshot that shows setting the language standard to the preview version.
  2. No painel esquerdo da caixa de diálogo Páginas de propriedades do projeto passo a passo, selecione Propriedades>gerais de configuração.
  3. Na lista suspensa Padrão de linguagem C++, selecione ISO C++20 Standard (/std:c++20) (ou posterior).
  4. Escolha OK para fechar a caixa de diálogo 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: Screenshot that shows the Add Reference dialog. It's used to add a reference to the Walkthrough project.Adicionar essa referência faz com que o sistema de compilação use as unidades de cabeçalho criadas por SharedPrj sempre que um import no projeto Passo a passo corresponder a uma das unidades de cabeçalho construídas em SharedPrj.
  2. Escolha OK para fechar a caixa de 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. (Utilização Build>Build Solution no menu principal.) Execute-o para ver se ele 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 /translateInclude opção do compilador (disponível na caixa de diálogo Páginas de propriedades do projeto em C/C++>General>Translate Includes to Imports) 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 #include <vector> automaticamente como import <vector>;. Para obter mais informações detalhadas sobre essa abordagem, consulte Abordagem 2: a varredura inclui cabeçalhos STL a serem importados. 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 a caixa de diálogo Páginas de Propriedades do projeto.
  2. No painel esquerdo da caixa de diálogo, selecione Propriedades>de configuração Diretórios VC++:Screenshot that shows public project content properties, like Public Include Directories and All Header Files are Public.

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

  • 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. Ele é visível para outros projetos, então coloque as unidades de cabeçalho que você deseja compartilhar aqui. 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 Propriedades do projeto para abrir a caixa de diálogo Páginas de propriedades do projeto>.
  2. No painel esquerdo da caixa de diálogo, selecione Propriedades>de configuração C/C++>General.
  3. Em Dependências de módulo adicionais, adicione os módulos à referência, separados por ponto-e-vírgula. Aqui está um exemplo do formato a ser usado para dependências de módulo adicionais: ModuleName1=Path\To\ModuleName1.ifc; ModuleName2=Path\To\ModuleName2.ifcScreenshot showing project Property Pages properties under Configuration Properties, C/C++, General, with Additional Module Dependencies selected.

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, deverá especificar qual usar. Você pode ter versões diferentes da unidade de cabeçalho criadas com diferentes configurações do compilador, por exemplo, e deve especificar aquela que corresponde às configurações do projeto.

Use a propriedade Dependências de Unidade de Cabeçalho Adicional 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 Adicional:

  1. No menu principal, selecione Propriedades do projeto para abrir a caixa de diálogo Páginas de propriedades do projeto>.
  2. No painel esquerdo da caixa de diálogo, selecione Propriedades>de configuração C/C++>General.
  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 este 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.ifcScreenshot that shows the Additional Header Unit Dependencies setting in the project Property Pages dialog.

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, é útil se você tiver uma base de código grande: você não precisa alterar seu 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 a reutilizar as 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 compilação ideal, já que todas as fontes devem ser verificadas em busca #include de instruções.

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 header-units.jsonarquivo 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 Propriedades do projeto para abrir a caixa de diálogo Páginas de propriedades do projeto>.
  2. Selecione Todas as configurações na lista suspensa Configuração e, em seguida, selecione Todas asplataformas na lista suspensa Plataforma. Essas configurações garantem que suas alterações se apliquem se você estiver criando para depuração ou lançamento e outras configurações.
  3. No painel esquerdo da caixa de diálogo, selecione Propriedades>de configuração C/C++>General.
  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 Translate Includes to Imports para Sim. Essa configuração compila os arquivos de cabeçalho STL listados no arquivo como unidades de cabeçalho e, em seguida, os importa em header-unit.json vez de usar o pré-processador para #include eles. Screenshot that shows the scan module dependencies property setting in the project Property Pages.
  6. Escolha OK para salvar as alterações e fechar a caixa de diálogo Páginas de propriedades do projeto.

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

  1. No menu principal, selecione Propriedades do projeto para abrir a caixa de diálogo Páginas de propriedades do projeto>.
  2. Selecione Todas as configurações na lista suspensa Configuração e, em seguida, selecione Todas asplataformas na lista suspensa Plataforma. Essas configurações garantem que suas alterações se apliquem se você estiver criando para depuração ou lançamento e outras configurações.
  3. No painel esquerdo da caixa de diálogo 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 as alterações e fechar a caixa de diálogo Páginas de propriedades do projeto.
  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 do C++ usando módulos
Guia Passo a passo: compilar e importar unidades de cabeçalho em seus projetos do Visual C++
/translateInclude