.vcxproj.props 檔案結構

MSBuild 是 Visual Studio 中的預設專案系統;當您在 Visual C++ 中選擇 [檔案 > 新專案 ] 時,您要建立 MSBuild 專案,其設定會儲存在副檔名 .vcxproj 為 的 XML 專案檔中。 專案檔也可以匯 .props 入可儲存設定的檔案和 .targets 檔案。

如果您想要在 IDE 中維護專案屬性,建議您只在 IDE 中建立和修改專案 .vcxproj ,並避免手動編輯檔案。 在大部分情況下,您永遠不需要手動編輯專案檔。 手動編輯可能會中斷在 Visual Studio 屬性頁中修改專案設定所需的專案連線,而且可能會導致難以偵錯和修復的建置錯誤。 如需使用屬性頁的詳細資訊,請參閱 在 Visual Studio 中設定 C++ 編譯器和建置屬性。

大規模地管理 IDE 中的許多個別專案變得乏味且容易出錯。 很難維持一致性,或跨數百個專案強制執行標準化。 在這些情況下,請務必編輯您的專案檔,以針對許多專案上的通用屬性使用自訂 .props.targets 檔案。 當您需要 IDE 中無法進行自訂時,您也可以使用這些檔案。 插入自訂專案方便的地方是 Directory.Build.propsDirectory.Build.targets 檔案,這些檔案會自動匯入所有 MSBuild 型專案中。

在某些情況下,自訂 .props.targets 檔案可能不足以滿足您的專案管理需求。 您仍然需要手動修改 .vcxproj 專案檔或屬性工作表。 手動編輯需要充分瞭解 MSBuild,而且必須遵循本文中的指導方針。 為了讓 IDE 自動載入和更新 .vcxproj 檔案,這些檔案有數個不適用於其他 MSBuild 專案檔的限制。 錯誤可能會導致 IDE 損毀或以非預期的方式運作。

針對手動編輯案例,本文包含與相關檔案結構 .vcxproj 的基本資訊。

重要考量

如果您選擇手動編輯 .vcxproj 檔案,請注意下列事實:

  • 檔案的結構必須遵循指定格式,如本文所述。

  • Visual Studio C++ 專案系統目前不支援專案專案中的萬用字元或清單。 例如,不支援這些表單:

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

    如需專案中萬用字元支援和可能因應措施的詳細資訊,請參閱 .vcxproj 檔案和萬用字元

  • Visual Studio C++ 專案系統目前不支援專案專案路徑中的宏。 例如,不支援此表單:

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

    「不支援」表示宏不保證適用于 IDE 中的所有作業。 在不同組態中不變更其值的宏應該可以運作,但如果專案移至不同的篩選或專案,則可能不會保留。 變更不同組態值的宏會造成問題。 IDE 不會預期不同專案專案路徑會因不同的專案組態而有所不同。

  • 若要在 [專案屬性] 對話方塊中編輯專案 屬性 時正確新增、移除或修改專案屬性,檔案必須包含每個專案組態的個別群組。 條件的格式必須如下:

    Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"
    
  • 每個屬性都必須在群組中指定其正確的標籤,如屬性規則檔中所指定。 如需詳細資訊,請參閱屬性頁 XML 規則檔

.vcxproj file 元素

您可以使用任何文字或 XML 編輯器來檢查檔案的內容 .vcxproj 。 若要在 Visual Studio 中檢視,請以滑鼠右鍵按一下 [方案總管] 中的專案,然後依序選擇 [卸載專案] 和 [編輯 Foo.vcxproj]

首先需要注意的是,最上層項目會依特定順序顯示。 例如:

  • 大多數屬性群組和和項目定義群組會在匯入 Microsoft.Cpp.Default.props 之後出現。

  • 所有目標都會匯入檔案結尾。

  • 有多個屬性群組,各有唯一的標籤,而且會依特定順序出現。

專案檔中的專案順序非常重要,因為 MSBuild 是以循序評估模型為基礎。 如果您的專案檔包含所有匯入 .props 的 和 .targets 檔案,是由屬性的多個定義所組成,則最後一個定義會覆寫上述定義。 在下列範例中,會在編譯期間設定 「xyz」 值,因為 MSBUild 引擎在評估期間最後遇到該值。

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

下列程式碼片段顯示最少 .vcxproj 的檔案。 Visual Studio 所產生的任何 .vcxproj 檔案都會包含這些最上層 MSBuild 元素。 而且,它們會依這個順序顯示,不過它們可能包含每個這類最上層元素的多個複本。 任何 Label 屬性都是 Visual Studio 僅用來作為編輯標誌的任意標籤;它們沒有其他功能。

<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>

下列各節說明每個元素的用途,以及它們以這種方式排序的原因:

Project 項目

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

Project 是根節點。 它會指定要使用的 MSBuild 版本,以及當這個檔案傳遞至 MSBuild.exe 時要執行的預設目標。

ProjectConfigurations ItemGroup 項目

<ItemGroup Label="ProjectConfigurations" />

ProjectConfigurations 包含專案組態描述。 例如,Debug|Win32、Release|Win32、Debug|ARM 等。 許多專案設定會專屬於某個組態。 例如,您可能想要設定發行組建的優化屬性,但不要設定偵錯組建。

專案 ProjectConfigurations 群組不會在建置階段使用。 Visual Studio IDE 需要載入專案。 此專案群組可以移至 .props 檔案並匯入檔案 .vcxproj 。 不過,在此情況下,如果您需要新增或移除組態,您必須手動編輯 .props 檔案;您無法使用 IDE。

ProjectConfiguration 項目

下列程式碼片段顯示專案組態。 在此範例中,'Debug|x64' 是組態名稱。 專案組態名稱的格式 $(Configuration)|$(Platform) 必須為 。 節點可以有兩個 ProjectConfiguration 屬性: ConfigurationPlatform 。 當組態為使用中時,這些屬性會自動設定此處指定的值。

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

IDE 預期會尋找所有 ProjectConfiguration 專案中使用的和 Platform 值組合 Configuration 的專案組態。 通常,這表示專案可能有毫無意義的專案組態來滿足此需求。 例如,如果專案具有下列組態:

  • Debug|Win32

  • Retail|Win32

  • Special 32-bit Optimization|Win32

則必須同時具有下列組態,即使 "Special 32-bit Optimization" 對 x64 無意義也一樣:

  • Debug|x64

  • Retail|x64

  • Special 32-bit Optimization|x64

您可以在 [方案組態管理員] 中,停用任何組態的建置和部署命令。

Globals PropertyGroup 項目

<PropertyGroup Label="Globals" />

Globals 包含專案層級設定,例如 ProjectGuidRootNamespaceApplicationTypeApplicationTypeRevision 。 最後兩項通常會定義目標 OS。 專案只能以單一 OS 為目標,因為目前參考和專案專案沒有條件。 這些屬性通常不會在專案檔中的其他位置覆寫。 此群組與組態無關,而且通常只有一個 Globals 群組存在於專案檔中。

Microsoft.Cpp.default.props Import 項目

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

Microsoft.Cpp.default.props 屬性工作表隨附于 Visual Studio,無法修改。 它包含專案的預設設定。 視 ApplicationType 而定,預設值可能會有所不同。

Configuration PropertyGroup 項目

<PropertyGroup Label="Configuration" />

Configuration 屬性群組具有附加的組態條件 (例如 Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'") 和多個複本,每個組態各一個。 此屬性群組會裝載專為特定組態設定的屬性。 組態屬性包含 PlatformToolset,同時也會控制 Microsoft.Cpp.props 中是否包含系統屬性工作表。 例如,如果您定義屬性 <CharacterSet>Unicode</CharacterSet>,則會包含系統屬性工作表 microsoft.Cpp.unicodesupport.props。 如果您檢查 Microsoft.Cpp.props ,您會看到這一行: <Import Condition="'$(CharacterSet)' == 'Unicode'" Project="$(VCTargetsPath)\microsoft.Cpp.unicodesupport.props" />

Microsoft.Cpp.props Import 項目

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

Microsoft.Cpp.props 屬性工作表(直接或透過匯入)會定義許多工具特定屬性的預設值。 範例包括編譯器的優化和警告層級屬性、MIDL 工具的 TypeLibraryName 屬性等等。 它也會根據屬性群組中緊接在屬性群組中定義的設定屬性,匯入各種系統屬性表。

ExtensionSettings ImportGroup 項目

<ImportGroup Label="ExtensionSettings" />

ExtensionSettings 群組包含屬於組建自訂一部分之屬性工作表的匯入。 組建自訂是由最多三個 .props 檔案所定義:檔案 .targets 、檔案和檔案 .xml 。 這個匯入群組包含檔案的 .props 匯入。

PropertySheets ImportGroup 項目

<ImportGroup Label="PropertySheets" />

PropertySheets 群組包含使用者屬性工作表的匯入。 這些匯入是您在 Visual Studio 中透過屬性管理員檢視新增的屬性工作表。 這些匯入的列出順序很重要,而且會反映在 [屬性管理員] 中。 專案檔通常會包含這種匯入群組的多個執行個體,每個專案組態各一個。

UserMacros PropertyGroup 項目

<PropertyGroup Label="UserMacros" />

UserMacros 包含您建立為變數以用來自訂建置程序的屬性。 例如,您可以定義使用者巨集,將您的自訂輸出路徑定義為 $(CustomOutputPath) 並使用它來定義其他變數。 此屬性群組會裝載這類屬性。 在 Visual Studio 中,此群組不會填入專案檔中,因為 Visual C++ 不支援設定的使用者宏。 屬性工作表支援使用者巨集。

各個組態的 PropertyGroup 項目

<PropertyGroup />

此屬性群組有多個執行個體,所有專案組態的每個組態各有一個。 每個屬性群組都必須附加一個組態條件。 如有任何組態遺失,[專案屬性] 對話方塊將無法正常運作。 不同于之前列出的屬性群組,此群組沒有標籤。 此群組包含專案組態層級設定。 這些設定會套用至屬於指定項目群組一部分的所有檔案。 組建自訂項目定義中繼資料會在此初始化。

這個 PropertyGroup 必須之後, <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> 而且在它之前沒有其他 PropertyGroup(否則專案屬性編輯將無法正常運作)。

各個組態的 ItemDefinitionGroup 項目

<ItemDefinitionGroup />

包含項目定義。 這些定義必須遵循與無標籤個別組態 PropertyGroup 元素相同的條件規則。

ItemGroup 項目

<ItemGroup />

ItemGroup 專案包含專案中的專案(原始程式檔等等)。 專案專案不支援條件(也就是依規則定義視為專案專案的專案類型)。

中繼資料應該具有每個組態的組態條件,即使它們都相同也一樣。 例如:

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

Visual Studio C++ 專案系統目前不支援專案專案中的萬用字元。

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

Visual Studio C++ 專案系統目前不支援專案專案中的宏。

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

ItemGroup 中會指定參考,而且具有下列限制:

  • 參考不支援條件。

  • 參考中繼資料不支援條件。

Microsoft.Cpp.targets Import 項目

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

定義(直接或透過匯入)C++ 目標,例如建置、清除等等。

ExtensionTargets ImportGroup 項目

<ImportGroup Label="ExtensionTargets" />

此群組包含組建自訂目標檔案的匯入。

排序不正確的後果

Visual Studio IDE 取決於專案檔先前所述的順序。 例如,當您定義屬性頁中的屬性值時,IDE 通常會將屬性定義放在具有空白標籤的屬性群組中。 此順序可確保系統屬性表中帶來的預設值會由使用者定義的值覆寫。 同樣地,目標檔案會匯入結尾,因為它們會取用之前定義的屬性,而且它們通常不會自行定義屬性。 同樣地,系統會在系統屬性表之後匯入使用者屬性工作表(包括 )。 Microsoft.Cpp.props 此順序可確保使用者可以覆寫系統屬性表所引進的任何預設值。

.vcxproj如果檔案未遵循此配置,則組建結果可能不是您預期的結果。 例如,如果您在使用者定義的屬性工作表之後錯誤地匯入系統屬性表,系統屬性表就會覆寫使用者設定。

即使是 IDE 設計階段體驗,也視元素的正確順序而定。 例如,如果您的 .vcxproj 檔案沒有 PropertySheets 匯入群組,IDE 可能無法判斷將使用者建立的新屬性工作表放在屬性管理員 的位置 。 這可能會導致系統工作表覆寫使用者工作表。 雖然 IDE 所使用的啟發學習法可以容忍檔案配置中的 .vcxproj 輕微不一致,但我們強烈建議您不要偏離本文稍早所示的結構。

IDE 如何使用項目標籤

在 IDE 中,當您在一般屬性頁面中設定 UseOfAtl 屬性時,它會寫入專案檔中的 Configuration 屬性群組。 相同屬性頁中的 TargetName 屬性會寫入每個組態屬性群組的無標籤。 Visual Studio 會查看屬性頁的 XML 檔案,以了解每個屬性寫入位置的相關資訊。 針對 [ 一般 ] 屬性頁,假設您有 Visual Studio 2019 Enterprise Edition 的英文版本,該檔案為 %ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VC\VCTargets\1033\general.xml 。 屬性頁 XML 規則檔會定義 Rule 及其所有屬性的靜態資訊。 這類資訊之一是目的檔案 (寫入其值的檔案) 中 Rule 屬性的慣用位置。 專案檔項目上的 Label 屬性會指定慣用位置。

屬性工作表配置

下列 XML 程式碼片段是屬性工作表 (.props) 檔案的最小配置。 這與檔案 .vcxproj 類似,而且可以從先前的討論推斷元素的功能 .props

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

若要製作您自己的屬性工作表,請複製資料夾中的 .props 其中一個檔案 VCTargets ,並根據您的目的加以修改。 針對 Visual Studio 2019 Enterprise 版本,預設 VCTargets 路徑為 %ProgramFiles%\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VC\VCTargets

另請參閱

在 Visual Studio 中設定 C ++ 編譯器和組建屬性
屬性頁面 XML 檔案
.vcxproj 檔案和萬用字元