Compartilhar via


Estrutura dos arquivos .vcxproj e .props

O MSBuild é o sistema de projeto padrão no Visual Studio; quando você escolhe Arquivo>Novo Projeto no Visual C++ você está criando um projeto do MSBuild cujas configurações são armazenadas em um arquivo de projeto XML que tem a extensão .vcxproj. O arquivo de projeto também pode importar arquivos .props e .targets nos quais as configurações podem ser armazenadas.

Se você pretende manter as propriedades do projeto no IDE, recomendamos que você crie e modifique apenas seus .vcxproj projetos no IDE e evite edições manuais nos arquivos. Na maioria dos casos, você nunca precisa editar manualmente o arquivo de projeto. Edições manuais podem quebrar as conexões de projeto necessárias para modificar as configurações do projeto nas páginas de propriedades do Visual Studio e podem causar erros de compilação que são difíceis de depurar e reparar. Para obter mais informações sobre como usar as páginas de propriedades, consulte Definir o compilador C++ e as propriedades de compilação no Visual Studio.

Em escala, o gerenciamento de muitos projetos individuais no IDE torna-se tedioso e propenso a erros. É difícil manter a consistência ou impor a padronização em dezenas ou centenas de projetos. Nesses casos, vale a pena editar seus arquivos de projeto para usar arquivos personalizados .props ou .targets para propriedades comuns em muitos projetos. Você também pode usar esses arquivos quando precisar de personalizações que não são possíveis no IDE. Locais úteis para inserir personalizações são os arquivos Directory.Build.props e Directory.Build.targets, que são importados automaticamente em todos os projetos baseados em MSBuild.

Em alguns casos, arquivos personalizados .props ou .targets sozinhos podem não ser suficientes para suas necessidades de gerenciamento de projetos. Talvez ainda seja necessário modificar .vcxproj arquivos de projeto ou folhas de propriedades manualmente. A edição manual requer uma boa compreensão do MSBuild e deve seguir as diretrizes deste artigo. Para que o IDE carregue e atualize arquivos .vcxproj automaticamente, esses arquivos têm várias restrições que não se aplicam a outros arquivos de projeto do MSBuild. Erros podem fazer com que o IDE falhe ou se comporte de maneiras inesperadas.

Para cenários de edição manual, este artigo contém informações básicas sobre a estrutura de .vcxproj e arquivos relacionados.

Considerações importantes

Caso você opte por editar um arquivo .vcxproj manualmente, lembre-se destes fatos:

  • A estrutura do arquivo precisa seguir um formato prescrito, que é descrito neste artigo.

  • Atualmente, o sistema de projeto do Visual Studio C++ não dá suporte a curingas ou lista diretamente nos itens de projeto. Por exemplo, estes formulários não têm suporte:

    <ItemGroup>
       <None Include="*.txt"/>
       <ClCompile Include="a.cpp;b.cpp"/>
    </ItemGroup>
    

    Para obter mais informações sobre o suporte a caracteres curinga em projetos e possíveis soluções alternativas, consulte arquivos .vcxproj e caracteres curinga.

  • Atualmente, o sistema de projeto do Visual Studio C++ não dá suporte a macros em caminhos de itens de projeto. Por exemplo, este formulário não tem suporte:

    <ItemGroup>
       <ClCompile Include="$(IntDir)\generated.cpp"/>
    </ItemGroup>
    

    "Sem suporte" significa que não há garantia de que as macros funcionarão em todas as operações no IDE. Macros que não alteram seu valor em configurações diferentes devem funcionar, mas talvez não sejam preservadas caso um item seja movido para um projeto ou um filtro diferente. Macros que alteram seu valor para configurações diferentes causarão problemas. O IDE não espera que os caminhos de item de projeto sejam diferentes para configurações de projeto diferentes.

  • Para adicionar, remover ou modificar as propriedades do projeto corretamente ao editá-las na caixa de diálogo Propriedades do projeto, o arquivo deve conter grupos separados para cada configuração do projeto. As condições devem ser desta forma:

    Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"
    
  • Cada propriedade precisa ser especificada no grupo com o rótulo correto, conforme especificado no arquivo de regra de propriedade. Para obter mais informações, confira Arquivos de regras XML da página de propriedades.

Elementos do arquivo .vcxproj

Você pode inspecionar o conteúdo de um arquivo .vcxproj usando qualquer editor de texto ou de XML. Exiba-o no Visual Studio clicando com o botão direito do mouse no projeto no Gerenciador de Soluções, escolhendo Descarregar projeto e, em seguida, Editar Foo.vcxproj.

A primeira coisa a ser observada é que os elementos de nível superior são exibidos em uma ordem específica. Por exemplo:

  • A maioria dos grupos de propriedades e dos grupos de definição de item ocorre após a importação para Microsoft.Cpp.Default.props.

  • Todos os destinos são importados no final do arquivo.

  • Há vários grupos de propriedades, cada um com um rótulo exclusivo, e que ocorrem em uma ordem específica.

A ordem dos elementos no arquivo de projeto é de vital importância, pois o MSBuild se baseia em um modelo de avaliação sequencial. Se o arquivo de projeto, incluindo todos os arquivos .props e .targets importados, consiste em várias definições de uma propriedade, a última definição substitui as anteriores. No exemplo a seguir, o valor "xyz" será definido durante a compilação, porque o mecanismo MSBuild o encontra por último durante sua avaliação.

  <MyProperty>abc</MyProperty>
  <MyProperty>xyz</MyProperty>

O snippet a seguir mostra um arquivo .vcxproj mínimo. Qualquer arquivo .vcxproj gerado pelo Visual Studio conterá esses elementos MSBuild de nível superior. E eles aparecerão nessa ordem, embora possam conter várias cópias de cada elemento de nível superior. Quaisquer atributos Label são marcas arbitrárias somente usadas pelo Visual Studio como indicações para edição; eles não têm nenhuma outra função.

<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
  <ItemGroup Label="ProjectConfigurations" />
  <PropertyGroup Label="Globals" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props" />
  <PropertyGroup Label="Configuration" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings" />
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup />
  <ItemDefinitionGroup />
  <ItemGroup />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets" />
</Project>

As seguintes seções descrevem a finalidade de cada um desses elementos e o motivo pelo qual eles são ordenados dessa forma:

Elemento de projeto

<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >

Project é o nó raiz. Especifica a versão do MSBuild a ser usada e também o destino padrão a ser executado quando esse arquivo é passado para MSBuild.exe.

Elemento ProjectConfigurations ItemGroup

<ItemGroup Label="ProjectConfigurations" />

ProjectConfigurations contém a descrição da configuração de projeto. Alguns exemplos são Debug|Win32, Release|Win32, Debug|ARM e assim por diante. Muitas configurações de projeto são específicas a determinada configuração. Por exemplo, provavelmente, você desejará definir as propriedades de otimização para um build de versão, mas não para um build de depuração.

O grupo de itens ProjectConfigurations não é usado no momento do build. O IDE do Visual Studio precisa dele para carregar o projeto. Esse grupo de itens pode ser movido para um arquivo .props e importado para o arquivo .vcxproj. No entanto, nesse caso, se você precisar adicionar ou remover as configurações, precisará editar o arquivo .props manualmente; não poderá usar o IDE.

Elementos de ProjectConfiguration

O snippet a seguir mostra uma configuração de projeto. Neste exemplo, 'Debug|x64' é o nome da configuração. O nome da configuração de projeto precisa estar no formato $(Configuration)|$(Platform). Um nó ProjectConfiguration pode ter duas propriedades: Configuration e Platform. Essas propriedades serão definidas automaticamente com os valores especificados aqui quando a configuração estiver ativa.

<ProjectConfiguration Include="Debug|x64">
  <Configuration>Debug</Configuration>
  <Platform>x64</Platform>
</ProjectConfiguration>

O IDE espera encontrar uma configuração de projeto para qualquer combinação dos valores Configuration e Platform usados em todos os itens de ProjectConfiguration. Geralmente, isso significa que um projeto pode ter configurações de projeto sem sentido para atender a esse requisito. Por exemplo, se um projeto tiver essas configurações:

  • Debug|Win32

  • Retail|Win32

  • Special 32-bit Optimization|Win32

ele também precisará ter essas configurações, mesmo que "Otimização Especial de 32 bits" não tenha sentido para x64:

  • Debug|x64

  • Retail|x64

  • Special 32-bit Optimization|x64

Desabilite o build e implante comandos para qualquer configuração no Gerenciador de Configurações da Solução.

Elemento Globals PropertyGroup

<PropertyGroup Label="Globals" />

Globals contém configurações de nível de projeto, como ProjectGuid, RootNamespace e ApplicationType ou ApplicationTypeRevision. As duas últimas geralmente definem o sistema operacional de destino. Um projeto só pode ser direcionado a um sistema operacional pois, no momento, as referências e os itens de projeto não podem ter condições. Normalmente, essas propriedades não são substituídas em nenhum outro lugar do arquivo de projeto. Esse grupo não é dependente de configuração e, normalmente, há apenas um grupo Globals no arquivo de projeto.

Elemento Microsoft.Cpp.default.props Import

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props" />

A folha de propriedades Microsoft.Cpp.default.props é fornecida com o Visual Studio e não pode ser modificada. Ela contém as configurações padrão para o projeto. Os padrões podem variar dependendo do ApplicationType.

Elementos Configuration PropertyGroup

<PropertyGroup Label="Configuration" />

Um grupo de propriedades Configuration tem uma condição de configuração anexada (como Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'") e é fornecido em várias cópias, uma por configuração. Esse grupo de propriedades hospeda as propriedades que são definidas para uma configuração específica. As propriedades de configuração incluem PlatformToolset e também controlam a inclusão de folhas de propriedades do sistema em Microsoft.Cpp.props. Por exemplo, se você definir a propriedade <CharacterSet>Unicode</CharacterSet>, a folha de propriedades do sistema microsoft.Cpp.unicodesupport.Props será incluída. Se você inspecionar Microsoft.Cpp.props, verá a linha <Import Condition="'$(CharacterSet)' == 'Unicode'" Project="$(VCTargetsPath)\microsoft.Cpp.unicodesupport.props" />.

Elemento Microsoft.Cpp.props Import

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

A folha de propriedades Microsoft.Cpp.props (diretamente ou por meio de importações) define os valores padrão para muitas propriedades específicas da ferramenta. Os exemplos incluem as propriedades Otimização e Nível de Aviso do compilador, a propriedade TypeLibraryName da ferramenta MIDL e assim por diante. Ela também importa várias folhas de propriedades do sistema com base em quais propriedades de configuração são definidas no grupo de propriedades imediatamente anterior.

Elemento ExtensionSettings ImportGroup

<ImportGroup Label="ExtensionSettings" />

O grupo ExtensionSettings contém importações para as folhas de propriedades que fazem parte das Personalizações de Build. Uma Personalização de Build é definida por até três arquivos: um arquivo .targets, um arquivo .props e um arquivo .xml. Esse grupo de importações contém as importações para o arquivo .props.

Elementos PropertySheets ImportGroup

<ImportGroup Label="PropertySheets" />

O grupo PropertySheets contém as importações para as folhas de propriedades do usuário. Essas importações são as folhas de propriedades que podem ser adicionadas por meio da exibição do Gerenciador de Propriedades no Visual Studio. A ordem na qual essas importações são listadas é importante e é refletida no Gerenciador de Propriedades. Normalmente, o arquivo de projeto contém várias instâncias desse tipo de grupo de importação, uma para cada configuração de projeto.

Elemento UserMacros PropertyGroup

<PropertyGroup Label="UserMacros" />

UserMacros contém as propriedades criadas como variáveis que são usadas para personalizar o processo de build. Por exemplo, você pode definir uma macro de usuário para definir o caminho de saída personalizado como $(CustomOutputPath) e usá-lo para definir outras variáveis. Esse grupo de propriedades hospeda essas propriedades. No Visual Studio, esse grupo não é populado no arquivo de projeto porque o Visual C++ não dá suporte a macros de usuário para configurações. Há suporte para macros de usuário em folhas de propriedades.

Elementos PropertyGroup por configuração

<PropertyGroup />

Há várias instâncias desse grupo de propriedades, um por configuração para todas as configurações de projeto. Cada grupo de propriedades precisa ter uma condição de configuração anexada. Se as configurações estiverem ausentes, a caixa de diálogo Propriedades do Projeto não funcionará corretamente. Ao contrário dos grupos de propriedades listados anteriormente, esse não tem um rótulo. Esse grupo contém as configurações no nível de configuração do projeto. Essas configurações se aplicam a todos os arquivos que fazem parte do grupo de itens especificado. Os metadados de definição de item de personalização de build são inicializados aqui.

Esse PropertyGroup precisa vir após <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> e não deve haver nenhum outro PropertyGroup sem um Label antes dele (caso contrário, a edição de Propriedades do Projeto não funcionará corretamente).

Elementos ItemDefinitionGroup por configuração

<ItemDefinitionGroup />

Contém definições de item. Essas definições precisam seguir as mesmas regras de condições que os elementos PropertyGroup sem rótulo por configuração.

Elementos ItemGroup

<ItemGroup />

Os elementos ItemGroup contêm os itens (arquivos de origem e assim por diante) no projeto. Não há suporte para condições em itens de Projeto (ou seja, tipos de item que são tratados como itens de projeto pelas definições de regras).

Os metadados deverão ter condições de configuração para cada configuração, mesmo se forem os mesmos. Por exemplo:

<ItemGroup>
  <ClCompile Include="stdafx.cpp">
    <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</TreatWarningAsError>
    <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</TreatWarningAsError>
  </ClCompile>
</ItemGroup>

Atualmente, o sistema de projeto do Visual Studio C++ não dá suporte a curingas nos itens de projeto.

<ItemGroup>
  <ClCompile Include="*.cpp"> <!--Error-->
</ItemGroup>

Atualmente, o sistema de projeto do Visual Studio C++ não dá suporte a macros em itens de projeto.

<ItemGroup>
  <ClCompile Include="$(IntDir)\generated.cpp"> <!--not guaranteed to work in all scenarios-->
</ItemGroup>

As referências são especificadas em um ItemGroup e têm as seguintes limitações:

  • As referências não dão suporte a condições.

  • Os metadados de referências não dão suporte a condições.

Elemento Microsoft.Cpp.targets Import

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

Define (diretamente ou por meio de importações) destinos C++, como build, clean e assim por diante.

Elemento ExtensionTargets ImportGroup

<ImportGroup Label="ExtensionTargets" />

Esse grupo contém importações para os arquivos de destino de Personalização de Build.

Consequências da ordenação incorreta

O IDE do Visual Studio depende que o arquivo de projeto tenha a ordenação descrita anteriormente. Por exemplo, quando você definir um valor de propriedade nas páginas de propriedades, geralmente, o IDE colocará a definição de propriedade no grupo de propriedades com o rótulo vazio. Essa ordenação garante que os valores padrão trazidos nas folhas de propriedades do sistema sejam substituídos por valores definidos pelo usuário. Da mesma forma, os arquivos de destino são importados no final, pois consomem as propriedades definidas anteriormente e, geralmente, não definem as propriedades por conta própria. Da mesma forma, as folhas de propriedades do usuário são importadas após as folhas de propriedades do sistema (incluídas por meio de Microsoft.Cpp.props). Essa ordem garante que o usuário possa substituir os padrões trazidos pelas folhas de propriedades do sistema.

Se um arquivo .vcxproj não segue esse layout, os resultados do build podem não ser o esperado. Por exemplo, se, por engano, você importar uma folha de propriedades do sistema após as folhas de propriedades definidas pelo usuário, as configurações do usuário serão substituídas pelas folhas de propriedades do sistema.

Até mesmo a experiência em tempo de design do IDE depende, até certo ponto, da ordenação correta dos elementos. Por exemplo, se o arquivo .vcxproj não tem o grupo de importação PropertySheets, o IDE pode não conseguir determinar o local em que colocar uma nova folha de propriedades criada pelo usuário no Gerenciador de Propriedades. Isso pode resultar na substituição de uma folha do usuário por uma folha do sistema. Embora a heurística usada pelo IDE possa tolerar pequenas inconsistências no layout do arquivo .vcxproj, é altamente recomendável não se desviar da estrutura mostrada anteriormente neste artigo.

Como o IDE usa os rótulos de elementos

No IDE, quando você define a propriedade UseOfAtl na página de propriedades gerais, ela é gravada para o grupo de propriedades Configuração no arquivo de projeto. A propriedade TargetName na mesma página de propriedades é gravada no grupo de propriedades sem rótulo por configuração. O Visual Studio examina o arquivo XML da página de propriedades para obter as informações sobre o local em que gravar cada propriedade. Para a página de propriedades Geral (supondo que você tenha uma versão em inglês do Visual Studio 2019 Enterprise Edition), esse arquivo é %ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VC\VCTargets\1033\general.xml. O arquivo de regra XML da página de propriedades define as informações estáticas sobre uma Rule e todas as suas propriedades. Uma dessas informações é a posição preferencial de uma propriedade Rule no arquivo de destino (o arquivo no qual seu valor será gravado). A posição preferencial é especificada pelo atributo Label nos elementos do arquivo de projeto.

Layout da folha de propriedades

O snippet XML a seguir é um layout mínimo de um arquivo de folha de propriedades (.props). Ele é semelhante a um arquivo .vcxproj e a funcionalidade dos elementos .props pode ser inferida com base na discussão anterior.

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup />
  <ItemDefinitionGroup />
  <ItemGroup />
</Project>

Para criar sua própria folha de propriedades, copie um dos arquivos .props na pasta VCTargets e modifique-o conforme a finalidade. Para o Visual Studio 2019 Enterprise Edition, o caminho padrão de VCTargets é %ProgramFiles%\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VC\VCTargets.

Confira também

Definição das propriedades de compilação do C++ no Visual Studio
Arquivos XML de página de propriedade
.vcxproj arquivos e curingas