Bagikan melalui


Ekstensibilitas sistem Visual Studio C++ Project dan integrasi toolset

Sistem proyek Visual C++ digunakan untuk file .vcxproj. Ini didasarkan pada Visual Studio Common Project System (CPS) dan menyediakan titik ekstensibilitas khusus C++ tambahan untuk memudahkan integrasi toolset baru, arsitektur build, dan platform target.

Struktur target C++ MSBuild

Semua file .vcxproj mengimpor file-file ini:

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

File-file ini mendefinisikan sedikit sendiri. Sebagai gantinya, mereka mengimpor file lain berdasarkan nilai properti ini:

  • $(ApplicationType)

    Contoh: Windows Store, Android, Linux

  • $(ApplicationTypeRevision)

    Ini harus berupa string versi yang valid, dari formulir major.minor[.build[.revision]].

    Contoh: 1.0, 10.0.0.0

  • $(Platform)

    Arsitektur build, bernama "Platform" karena alasan historis.

    Contoh: Win32, x86, x64, ARM

  • $(PlatformToolset)

    Contoh: v140, v141, v141_xp, llvm

Nilai properti ini menentukan nama folder di $(VCTargetsPath) bawah folder akar:

$(VCTargetsPath)\
     Jenis Aplikasi\
        $(ApplicationType)\
            $(ApplicationTypeRevision)\
                 Platform\
                    $(Platform)\
                         PlatformToolsets\
                            $(PlatformToolset)
     Platform\
        $(Platform)\
             PlatformToolsets\
                $(PlatformToolset)

Folder $(VCTargetsPath)\Platforms\ digunakan ketika $(ApplicationType) kosong, untuk proyek Windows Desktop.

Menambahkan toolset platform baru

Untuk menambahkan toolset baru, misalnya, "MyToolset" untuk platform Win32 yang ada, buat folder MyToolset di bawah $(VCTargetsPath)\Platforms\Win32\PlatformToolsets\, dan buat toolset.props dan Toolset.targets file di dalamnya.

Setiap nama folder di bawah PlatformToolsets muncul dalam dialog Properti Proyek sebagai Platform Toolset yang tersedia untuk platform yang ditentukan, seperti yang ditunjukkan di sini:

Properti Platform Toolset dalam dialog Halaman Properti proyek

Buat folder MyToolset serupa dan file Toolset.props dan Toolset.targets di setiap folder platform yang ada yang didukung toolset ini.

Menambahkan platform baru

Untuk menambahkan platform baru, misalnya, "MyPlatform", buat folder MyPlatform di bawah $(VCTargetsPath)\Platforms\, dan buat file Platform.default.props, Platform.props, dan Platform.targets di dalamnya. $(VCTargetsPath) Buat juga folder \Platforms\MyPlatform\PlatformToolsets\, dan buat setidaknya satu toolset di dalamnya.

Semua nama folder di bawah folder Platform untuk masing-masing $(ApplicationType) dan $(ApplicationTypeRevision) muncul di IDE sebagai pilihan Platform yang tersedia untuk proyek.

Pilihan platform Baru dalam dialog Platform Proyek Baru

Menambahkan Jenis Aplikasi baru

Untuk menambahkan jenis aplikasi baru, buat folder MyApplicationType di bawah $(VCTargetsPath)\Application Type\ dan buat file Defaults.props di dalamnya. Setidaknya satu revisi diperlukan untuk jenis aplikasi, jadi buat $(VCTargetsPath)juga folder \Application Type\MyApplicationType\1.0 , dan buat file Defaults.props di dalamnya. Anda juga harus membuat $(VCTargetsPath)folder \ApplicationType\MyApplicationType\1.0\Platforms dan membuat setidaknya satu platform di dalamnya.

$(ApplicationType) properti dan $(ApplicationTypeRevision) tidak terlihat di antarmuka pengguna. Mereka didefinisikan dalam templat proyek dan tidak dapat diubah setelah proyek dibuat.

Pohon impor .vcxproj

Pohon impor yang disederhanakan untuk props Microsoft C++ dan file target terlihat seperti:

$(VCTargetsPath) \ Microsoft.Cpp.Default.props
     $(MSBuildExtensionsPath) \ $(MSBuildToolsVersion) \ Microsoft.Common.props
     $(VCTargetsPath) \ ImportBefore\Default\*.Alat peraga
     $(VCTargetsPath) \ Jenis\$(ApplicationType)\Aplikasi Default.props
     $(VCTargetsPath) \ Jenis\$(ApplicationType)\$(ApplicationTypeRevision)\Aplikasi Default.props
     $(VCTargetsPath) \ Platform Jenis\$(ApplicationType)\$(ApplicationTypeRevision)\Aplikasi Platform.default.props\$(Platform)\
     $(VCTargetsPath) \ ImportAfter\Default\*.Alat peraga

Proyek Windows Desktop tidak menentukan $(ApplicationType), sehingga hanya mengimpor

$(VCTargetsPath) \ Microsoft.Cpp.Default.props
     $(MSBuildExtensionsPath) \ $(MSBuildToolsVersion) \ Microsoft.Common.props
     $(VCTargetsPath) \ ImportBefore\Default\*.Alat peraga
     $(VCTargetsPath) \ Platform\$(Platform)\Platform.default.props
     $(VCTargetsPath) \ ImportAfter\Default\*.Alat peraga

Kami akan menggunakan $(_PlatformFolder) properti untuk menahan $(Platform) lokasi folder platform. Properti ini adalah

$(VCTargetsPath) \ Platform\$(Platform)

untuk aplikasi Windows Desktop, dan

$(VCTargetsPath) \ Platform Jenis\$(ApplicationType)\$(ApplicationTypeRevision)\Aplikasi\$(Platform)

untuk segala sesuatu yang lain.

File alat peraga diimpor dalam urutan ini:

$(VCTargetsPath) \ Microsoft.Cpp.props
     $(_PlatformFolder) \ Platform.props
         $(VCTargetsPath) \ Microsoft.Cpp.Platform.props
             $(_PlatformFolder) \ ImporBefore\*.Alat peraga
             $(_PlatformFolder) \ PlatformToolsets\$(PlatformToolset)\Toolset.props
             $(_PlatformFolder) \ ImportAfter\*.Alat peraga

File target diimpor dalam urutan ini:

$(VCTargetsPath) \ Microsoft.Cpp.targets
     $(VCTargetsPath) \ Microsoft.Cpp.Current.targets
         $(_PlatformFolder) \ Platform.targets
             $(VCTargetsPath) \ Microsoft.Cpp.Platform.targets
                 $(_PlatformFolder) \ ImporBefore\*.Target
                 $(_PlatformFolder) \ PlatformToolsets\$(PlatformToolset)\Toolset.target
                 $(_PlatformFolder) \ ImportAfter\*.Target

Jika Anda perlu menentukan beberapa properti default untuk kumpulan alat, Anda dapat menambahkan file ke folder ImportBefore dan ImportAfter yang sesuai.

File Toolset.props dan Toolset.targets penulis

File Toolset.props dan Toolset.targets memiliki kontrol penuh atas apa yang terjadi selama build saat toolset ini digunakan. Mereka juga dapat mengontrol debugger yang tersedia, beberapa antarmuka pengguna IDE, seperti konten dalam dialog Halaman Properti, dan beberapa aspek perilaku proyek lainnya.

Meskipun kumpulan alat dapat mengambil alih seluruh proses build, biasanya Anda hanya ingin set alat Anda memodifikasi atau menambahkan beberapa langkah build, atau menggunakan alat build yang berbeda, sebagai bagian dari proses build yang ada. Untuk mencapai tujuan ini, ada sejumlah alat peraga umum dan menargetkan file yang dapat diimpor set alat Anda. Bergantung pada apa yang Anda inginkan untuk dilakukan set alat Anda, file-file ini mungkin berguna untuk digunakan sebagai impor atau sebagai contoh:

  • $(VCTargetsPath) \ Microsoft.CppCommon.targets

    File ini mendefinisikan bagian utama dari proses build asli, dan juga mengimpor:

    • $(VCTargetsPath) \ Microsoft.CppBuild.targets

    • $(VCTargetsPath) \ Microsoft.BuildSteps.targets

    • $(MSBuildToolsPath) \ Microsoft.Common.Targets

  • $(VCTargetsPath) \ Microsoft.Cpp.Common.props

    Mengatur default untuk toolset yang menggunakan pengkompilasi Microsoft dan target Windows.

  • $(VCTargetsPath) \ Microsoft.Cpp.WindowsSDK.props

    File ini menentukan lokasi Windows SDK, dan menentukan beberapa properti penting untuk aplikasi yang menargetkan Windows.

Mengintegrasikan target khusus toolset dengan proses build C++ default

Proses build C++ default ditentukan dalam Microsoft.CppCommon.targets. Target di sana tidak memanggil alat build tertentu; mereka menentukan langkah-langkah build utama, urutan dan dependensinya.

Build C++ memiliki tiga langkah utama, yang diwakili oleh target berikut:

  • BuildGenerateSources

  • BuildCompile

  • BuildLink

Karena setiap langkah build dapat dijalankan secara independen, target yang berjalan dalam satu langkah tidak dapat mengandalkan grup item dan properti yang ditentukan dalam target yang berjalan sebagai bagian dari langkah yang berbeda. Divisi ini memungkinkan pengoptimalan performa build tertentu. Meskipun tidak digunakan secara default, Anda masih dianjurkan untuk menghormati pemisahan ini.

Target yang dijalankan di dalam setiap langkah dikontrol oleh properti ini:

  • $(BuildGenerateSourcesTargets)

  • $(BuildCompileTargets)

  • $(BeforeBuildLinkTargets)

Setiap langkah juga memiliki properti Sebelum dan Sesudah.

<Target
  Name="_BuildGenerateSourcesAction"
  DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildGenerateSourcesTargets);$(BuildGenerateSourcesTargets);$(AfterBuildGenerateSourcesTargets)" />

<Target
  Name="\_BuildCompileAction"
  DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildCompileTargets);$(BuildCompileTargets);$(AfterBuildCompileTargets)" />

<Target
  Name="\_BuildLinkAction"
  DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildLinkTargets);$(BuildLinkTargets);$(AfterBuildLinkTargets)" />

Lihat file Microsoft.CppBuild.targets untuk contoh target yang disertakan dalam setiap langkah:

<BuildCompileTargets Condition="'$(ConfigurationType)'\!='Utility'">
  $(BuildCompileTargets);
  _ClCompile;
  _ResGen;
  _ResourceCompile;
  $(BuildLibTargets);
</BuildCompileTargets>

Jika Anda melihat target, seperti _ClCompile, Anda akan melihat mereka tidak melakukan apa pun secara langsung sendiri, tetapi sebaliknya bergantung pada target lain, termasuk ClCompile:

<Target Name="_ClCompile"
  DependsOnTargets="$(BeforeClCompileTargets);$(ComputeCompileInputsTargets);MakeDirsForCl;ClCompile;$(AfterClCompileTargets)" >
</Target>

ClCompile dan target khusus alat build lainnya didefinisikan sebagai target kosong di Microsoft.CppBuild.targets:

<Target Name="ClCompile"/>

ClCompile Karena target kosong, kecuali jika ditimpa oleh set alat, tidak ada tindakan build nyata yang dilakukan. Target toolset dapat mengambil ClCompile alih target, yaitu, mereka dapat berisi definisi lain ClCompile setelah mengimpor Microsoft.CppBuild.targets:

<Target Name="ClCompile"
  Condition="'@(ClCompile)' != ''"
  DependsOnTargets="SelectClCompile">
  <!-- call some MSBuild tasks -->
</Target>

Terlepas dari namanya, yang dibuat sebelum Visual Studio menerapkan dukungan lintas platform, ClCompile target tidak perlu memanggil CL.exe. Ini juga dapat memanggil Clang, gcc, atau kompilator lainnya dengan menggunakan tugas MSBuild yang sesuai.

Target ClCompile tidak boleh memiliki dependensi apa pun kecuali SelectClCompile target, yang diperlukan agar perintah kompilasi file tunggal berfungsi di IDE.

Tugas MSBuild untuk digunakan dalam target toolset

Untuk memanggil alat build aktual, target perlu memanggil tugas MSBuild. Ada tugas Exec dasar yang memungkinkan Anda menentukan baris perintah untuk dijalankan. Namun, alat build biasanya memiliki banyak opsi, input, dan output untuk dilacak untuk build bertahap, sehingga lebih masuk akal untuk memiliki tugas khusus untuk mereka. Misalnya, tugas menerjemahkan CL properti MSBuild ke dalam sakelar CL.exe, menulisnya ke dalam file respons, dan memanggil CL.exe. Ini juga melacak semua file input dan output untuk build inkremental nanti. Untuk informasi selengkapnya, lihat Build bertahap dan pemeriksaan terbaru.

Microsoft.Cpp.Common.Tasks.dll mengimplementasikan tugas-tugas ini:

  • BSCMake

  • CL

  • ClangCompile (sakelar clang-gcc)

  • LIB

  • LINK

  • MIDL

  • Mt

  • RC

  • XDCMake

  • CustomBuild (seperti Exec tetapi dengan pelacakan input dan output)

  • SetEnv

  • GetOutOfDateItems

Jika Anda memiliki alat yang melakukan tindakan yang sama dengan alat yang ada, dan yang memiliki sakelar baris perintah serupa (seperti clang-cl dan CL lakukan), Anda dapat menggunakan tugas yang sama untuk keduanya.

Jika Anda perlu membuat tugas baru untuk alat build, Anda dapat memilih dari opsi berikut:

  1. Jika Anda jarang menggunakan tugas ini, atau jika beberapa detik tidak penting untuk build Anda, Anda dapat menggunakan tugas MSBuild 'sebaris':

    • Tugas Xaml (aturan build kustom)

      Untuk salah satu contoh deklarasi tugas Xaml, lihat $(VCTargetsPath)\masm.xml, dan untuk penggunaannya, lihat \$(VCTargetsPath)

    • Tugas kode

  2. Jika Anda menginginkan performa tugas yang lebih baik atau hanya memerlukan fungsionalitas yang lebih kompleks, gunakan proses penulisan tugas MSBuild reguler.

    Jika tidak semua input dan output alat tercantum di baris perintah alat, seperti dalam CLkasus , MIDL, dan RC , dan jika Anda menginginkan pelacakan file input dan output otomatis dan pembuatan file .tlog, dapatkan tugas Anda dari Microsoft.Build.CPPTasks.TrackedVCToolTask kelas . Saat ini, sementara ada dokumentasi untuk kelas ToolTask dasar, tidak ada contoh atau dokumentasi untuk detail TrackedVCToolTask kelas. Jika ini menarik, tambahkan suara Anda ke permintaan di Komunitas Pengembang.

Build inkremental dan pemeriksaan terbaru

Target build inkremental MSBuild default menggunakan Inputs atribut dan Outputs . Jika Anda menentukannya, MSBuild memanggil target hanya jika salah satu input memiliki tanda waktu yang lebih baru daripada semua output. Karena file sumber sering menyertakan atau mengimpor file lain, dan alat build menghasilkan output yang berbeda tergantung pada opsi alat, sulit untuk menentukan semua kemungkinan input dan output dalam target MSBuild.

Untuk mengelola masalah ini, build C++ menggunakan teknik yang berbeda untuk mendukung build inkremental. Sebagian besar target tidak menentukan input dan output, dan sebagai hasilnya, selalu berjalan selama build. Tugas yang dipanggil oleh target menulis informasi tentang semua input dan output ke dalam file tlog yang memiliki ekstensi .tlog. File .tlog digunakan oleh build nanti untuk memeriksa apa yang telah berubah dan perlu dibangun kembali, dan apa yang terbaru. File .tlog juga merupakan satu-satunya sumber untuk pemeriksaan terbaru build default di IDE.

Untuk menentukan semua input dan output, tugas alat asli menggunakan tracker.exe dan kelas FileTracker yang disediakan oleh MSBuild.

Microsoft.Build.CPPTasks.Common.dll mendefinisikan TrackedVCToolTask kelas dasar abstrak publik. Sebagian besar tugas alat asli berasal dari kelas ini.

Mulai pembaruan Visual Studio 2017 15.8, Anda dapat menggunakan tugas yang GetOutOfDateItems diterapkan di Microsoft.Cpp.Common.Tasks.dll untuk menghasilkan file .tlog untuk target kustom dengan input dan output yang diketahui. Atau, Anda dapat membuatnya dengan menggunakan WriteLinesToFile tugas. _WriteMasmTlogs Lihat target dalam$(VCTargetsPath)\\ sebagai contoh.

File .tlog

Ada tiga jenis file .tlog: baca, tulis, dan baris perintah. File .tlog baca dan tulis digunakan oleh build inkremental dan oleh pemeriksaan terbaru di IDE. File .tlog baris perintah hanya digunakan dalam build inkremental.

MSBuild menyediakan kelas pembantu ini untuk membaca dan menulis file .tlog:

Kelas FlatTrackingData dapat digunakan untuk mengakses file baca dan tulis .tlog dan mengidentifikasi input yang lebih baru dari output, atau jika output hilang. Ini digunakan dalam pemeriksaan terbaru.

File .tlog baris perintah berisi informasi tentang baris perintah yang digunakan dalam build. Mereka hanya digunakan untuk build inkremental, bukan pemeriksaan terbaru, sehingga format internal ditentukan oleh tugas MSBuild yang menghasilkannya.

Membaca format .tlog

Baca file .tlog (*.read.*.tlog) berisi informasi tentang file sumber dan dependensinya.

Tanda sisipan (^) di awal baris menunjukkan satu atau beberapa sumber. Sumber yang berbagi dependensi yang sama dipisahkan oleh bilah vertikal (|).

File dependensi dicantumkan setelah sumber, masing-masing pada barisnya sendiri. Semua nama file adalah jalur lengkap.

Misalnya, asumsikan sumber proyek Anda ditemukan di F:\test\ConsoleApplication1\ConsoleApplication1. Jika file sumber Anda, Class1.cpp, memiliki ini termasuk,

#include "stdafx.h" //precompiled header
#include "Class1.h"

kemudian file CL.read.1.tlog berisi file sumber diikuti dengan dua dependensinya:

^F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\CLASS1.CPP
F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.PCH
F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\CLASS1.H

Tidak diperlukan untuk menulis nama file dalam huruf besar, tetapi ini adalah kenyamanan untuk beberapa alat.

Menulis format .tlog

Tulis file .tlog (*.write.*.tlog) sambungkan sumber dan output.

Tanda sisipan (^) di awal baris menunjukkan satu atau beberapa sumber. Beberapa sumber dipisahkan oleh bilah vertikal (|).

File output yang dibangun dari sumber harus dicantumkan setelah sumber, masing-masing pada barisnya sendiri. Semua nama file harus jalur lengkap.

Misalnya, untuk proyek ConsoleApplication sederhana yang memiliki file sumber tambahan Class1.cpp, file link.write.1.tlog mungkin berisi:

^F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\CLASS1.OBJ|F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.OBJ|F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\STDAFX.OBJ
F:\TEST\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.ILK
F:\TEST\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.EXE
F:\TEST\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.PDB

Build waktu desain

Dalam IDE, .vcxproj proyek menggunakan sekumpulan target MSBuild untuk mendapatkan informasi tambahan dari proyek dan untuk meregenerasi file output. Beberapa target ini hanya digunakan dalam build waktu desain, tetapi banyak dari mereka digunakan dalam build reguler dan build waktu desain.

Untuk informasi umum tentang build waktu desain, lihat dokumentasi CPS untuk build Design-time. Dokumentasi ini hanya sebagian berlaku untuk proyek Visual C++.

Target CompileDesignTime dan Compile yang disebutkan dalam dokumentasi build waktu desain tidak pernah berjalan untuk proyek .vcxproj. Proyek .vcxproj Visual C++ menggunakan target waktu desain yang berbeda untuk mendapatkan informasi IntelliSense.

Target waktu desain untuk informasi IntelliSense

Target waktu desain yang digunakan dalam proyek .vcxproj ditentukan dalam $(VCTargetsPath)\Microsoft.Cpp.DesignTime.targets.

Target GetClCommandLines mengumpulkan opsi pengkompilasi untuk IntelliSense:

<Target
  Name="GetClCommandLines"
  Returns="@(ClCommandLines)"
  DependsOnTargets="$(DesignTimeBuildInitTargets);$(ComputeCompileInputsTargets)">
  • DesignTimeBuildInitTargets – target khusus waktu desain, diperlukan untuk inisialisasi build waktu desain. Antara lain, target ini menonaktifkan beberapa fungsionalitas build reguler untuk meningkatkan performa.

  • ComputeCompileInputsTargets – sekumpulan target yang memodifikasi opsi dan item pengkompilasi. Target ini berjalan dalam build desain dan reguler.

Target memanggil CLCommandLine tugas untuk membuat baris perintah yang akan digunakan untuk IntelliSense. Sekali lagi, terlepas dari namanya, ia dapat menangani tidak hanya opsi CL, tetapi juga opsi Clang dan gcc. Jenis sakelar pengkompilasi dikontrol oleh ClangMode properti .

Saat ini, baris perintah yang dihasilkan oleh CLCommandLine tugas selalu menggunakan sakelar CL (bahkan dalam mode Clang) karena lebih mudah diurai oleh mesin IntelliSense.

Jika Anda menambahkan target yang berjalan sebelum kompilasi, baik reguler atau waktu desain, pastikan target tersebut tidak merusak build waktu desain atau memengaruhi performa. Cara paling sederhana untuk menguji target Anda adalah dengan membuka perintah Pengembang dan menjalankan perintah ini:

msbuild /p:SolutionDir=*solution-directory-with-trailing-backslash*;Configuration=Debug;Platform=Win32;BuildingInsideVisualStudio=true;DesignTimebuild=true /t:\_PerfIntellisenseInfo /v:d /fl /fileloggerparameters:PerformanceSummary \*.vcxproj

Perintah ini menghasilkan log build terperinci, msbuild.log, yang memiliki ringkasan performa untuk target dan tugas di akhir.

Pastikan untuk menggunakan Condition ="'$(DesignTimeBuild)' != 'true'" di semua operasi yang hanya masuk akal untuk build reguler dan bukan untuk build waktu desain.

Target waktu desain yang menghasilkan sumber

Fitur ini dinonaktifkan secara default untuk proyek asli Desktop dan saat ini tidak didukung pada proyek yang di-cache.

Jika GeneratorTarget metadata didefinisikan untuk item proyek, target dijalankan secara otomatis baik saat proyek dimuat dan ketika file sumber diubah.

Misalnya, untuk secara otomatis menghasilkan file .cpp atau .h dari file .xaml, $(VSInstallDir)\file MSBuild\Microsoft\WindowsXaml\Microsoft.Windows.UI.Xaml.CPP.Targets menentukan entitas ini:

<ItemDefinitionGroup>
  <Page>
    <GeneratorTarget>DesignTimeMarkupCompilation</GeneratorTarget>
  </Page>
  <ApplicationDefinition>
    <GeneratorTarget>DesignTimeMarkupCompilation</GeneratorTarget>
  </ApplicationDefinition>
</ItemDefinitionGroup>
<Target Name="DesignTimeMarkupCompilation">
  <!-- BuildingProject is used in Managed builds (always true in Native) -->
  <!-- DesignTimeBuild is used in Native builds (always false in Managed) -->
  <CallTarget Condition="'$(BuildingProject)' != 'true' Or $(DesignTimeBuild) == 'true'" Targets="DesignTimeMarkupCompilationCT" />
</Target>

Untuk digunakan Task.HostObject untuk mendapatkan konten file sumber yang tidak disimpan, target dan tugas harus didaftarkan sebagai MsbuildHostObjects untuk proyek yang diberikan dalam pkgdef:

\[$RootKey$\\Projects\\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\\MSBuildHostObjects\]
\[$RootKey$\\Projects\\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\\MSBuildHostObjects\\DesignTimeMarkupCompilationCT;CompileXaml\]
@="{83046B3F-8984-444B-A5D2-8029DEE2DB70}"

Ekstensibilitas proyek Visual C++ di IDE Visual Studio

Sistem proyek Visual C++ didasarkan pada Sistem Proyek VS, dan menggunakan titik ekstensibilitasnya. Namun, implementasi hierarki proyek khusus untuk Visual C++ dan bukan berdasarkan CPS, sehingga ekstensibilitas hierarki terbatas pada item proyek.

Halaman properti proyek

Untuk informasi desain umum, lihat Kerangka Kerja Multi-Penargetan untuk Proyek VC++.

Dalam istilah sederhana, halaman properti yang Anda lihat dalam dialog Properti Proyek untuk proyek C++ ditentukan oleh file aturan . File aturan menentukan sekumpulan properti untuk ditampilkan di halaman properti, dan bagaimana dan di mana mereka harus disimpan dalam file proyek. File aturan adalah file .xml yang menggunakan format Xaml. Jenis yang digunakan untuk menserialisasikannya dijelaskan dalam Microsoft.Build.Framework.XamlTypes. Untuk informasi selengkapnya tentang penggunaan file aturan dalam proyek, lihat File aturan XML Halaman Properti.

File aturan harus ditambahkan ke PropertyPageSchema grup item:

<ItemGroup>
  <PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\general.xml;"/>
  <PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\general_file.xml">
    <Context>File</Context>
  </PropertyPageSchema>
</ItemGroup>

Context metadata membatasi visibilitas aturan, yang juga dikontrol oleh jenis aturan, dan dapat memiliki salah satu nilai ini:

Project | File | PropertySheet

CPS mendukung nilai lain untuk jenis konteks, tetapi tidak digunakan dalam proyek Visual C++.

Jika aturan harus terlihat dalam lebih dari satu konteks, gunakan titik koma (;) untuk memisahkan nilai konteks, seperti yang ditunjukkan di sini:

<PropertyPageSchema Include="$(MyFolder)\MyRule.xml">
  <Context>Project;PropertySheet</Context>
</PropertyPageSchema>

Format aturan dan jenis utama

Format aturan mudah, jadi bagian ini hanya menjelaskan atribut yang memengaruhi tampilan aturan di antarmuka pengguna.

<Rule
  Name="ConfigurationGeneral"
  DisplayName="General"
  PageTemplate="generic"
  Description="General"
  xmlns="http://schemas.microsoft.com/build/2009/properties">

Atribut PageTemplate menentukan bagaimana aturan ditampilkan dalam dialog Halaman Properti. Atribut dapat memiliki salah satu nilai ini:

Karakteristik Deskripsi
generic Semua properti ditampilkan pada satu halaman di bawah Judul kategori
Aturan dapat terlihat untuk Project konteks dan PropertySheet , tetapi tidak File.

Contoh: $(VCTargetsPath)\1033\general.xml
tool Kategori ditampilkan sebagai sub-halaman.
Aturan dapat terlihat dalam semua konteks: Project, PropertySheet dan File.
Aturan terlihat di Properti Proyek hanya jika proyek memiliki item dengan ItemType yang ditentukan dalam Rule.DataSource, kecuali nama aturan disertakan dalam ProjectTools grup item.

Contoh: $(VCTargetsPath)\1033\clang.xml
debugger Halaman ditampilkan sebagai bagian dari halaman Penelusuran Kesalahan.
Kategori saat ini diabaikan.
Nama aturan harus cocok dengan atribut objek ExportDebugger MEF Peluncur Debug.

Contoh: $(VCTargetsPath)\1033\debugger_local_windows.xml
kustom Templat kustom. Nama templat harus cocok dengan ExportPropertyPageUIFactoryProvider atribut PropertyPageUIFactoryProvider objek MEF. Lihat Microsoft.VisualStudio.ProjectSystem.Designers.Properties.IPropertyPageUIFactoryProvider.

Contoh: $(VCTargetsPath)\1033\userMacros.xml

Jika aturan menggunakan salah satu templat berbasis Property Grid, aturan tersebut dapat menggunakan titik ekstensibilitas ini untuk propertinya:

Memperluas aturan

Jika Anda ingin menggunakan aturan yang sudah ada, tetapi perlu menambahkan atau menghapus (yaitu, menyembunyikan) hanya beberapa properti, Anda dapat membuat aturan Ekstensi.

Mengambil alih aturan

Mungkin Anda ingin set alat Anda menggunakan sebagian besar aturan default proyek, tetapi untuk mengganti hanya satu atau beberapa dari mereka. Misalnya, Anda hanya ingin mengubah aturan C/C++ untuk menampilkan sakelar pengkompilasi yang berbeda. Anda dapat memberikan aturan baru dengan nama dan nama tampilan yang sama dengan aturan yang ada, dan menyertakannya dalam PropertyPageSchema grup item setelah impor target cpp default. Hanya satu aturan dengan nama tertentu yang digunakan dalam proyek, dan yang terakhir disertakan ke dalam PropertyPageSchema grup item menang.

Item proyek

File ProjectItemsSchema.xml menentukan ContentType nilai dan ItemType untuk Item yang diperlakukan sebagai Item Proyek, dan menentukan FileExtension elemen untuk menentukan grup Item mana file baru ditambahkan.

File ProjectItemsSchema default ditemukan di $(VCTargetsPath)\\ Untuk memperluasnya, Anda harus membuat file skema dengan nama baru, seperti MyProjectItemsSchema.xml:

<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties">

  <ItemType Name="MyItemType" DisplayName="C/C++ compiler"/>

  <ContentType
    Name="MyItems"
    DisplayName="My items"
    ItemType=" MyItemType ">
  </ContentType>

  <FileExtension Name=".abc" ContentType=" MyItems"/>

</ProjectSchemaDefinitions>

Kemudian dalam file target, tambahkan:

<ItemGroup>
  <PropertyPageSchema Include="MyProjectItemsSchema.xml"/>
</ItemGroup>

Contoh: $(VCTargetsPath)\BuildCustomizations\masm.xml

Debugger

Layanan Debug di Visual Studio mendukung ekstensibilitas untuk mesin Debug. Untuk informasi selengkapnya, lihat sampel ini:

Untuk menentukan mesin Debug dan properti lain untuk sesi debug, Anda harus menerapkan komponen MEF Peluncur Debug, dan menambahkan debugger aturan. Misalnya, lihat $(VCTargetsPath)file \1033\debugger_local_windows.xml.

Terapkan

.vcxproj proyek menggunakan ekstensibilitas Sistem Proyek Visual Studio untuk Penyedia Penyebaran.

Buat pemeriksaan terbaru

Secara default, pemeriksaan build up-to-date memerlukan file .tlog baca dan tulis .tlog untuk dibuat di $(TlogLocation) folder selama build untuk semua input dan output build.

Untuk menggunakan pemeriksaan terbaru kustom:

  1. Nonaktifkan pemeriksaan default terbaru dengan menambahkan NoVCDefaultBuildUpToDateCheckProvider kemampuan dalam file Toolset.targets :

    <ItemGroup>
      <ProjectCapability Include="NoVCDefaultBuildUpToDateCheckProvider" />
    </ItemGroup>
    
  2. Terapkan IBuildUpToDateCheckProvider Anda sendiri.

Peningkatan proyek

Peningkatan proyek .vcxproj default

Peningkatan proyek .vcxproj default mengubah PlatformToolsetversi toolset , ApplicationTypeRevision, MSBuild dan .NET Framework. Dua terakhir selalu diubah ke default versi Visual Studio, tetapi PlatformToolset dan ApplicationTypeRevision dapat dikontrol oleh properti MSBuild khusus.

Peningkatan menggunakan kriteria ini untuk memutuskan apakah proyek dapat ditingkatkan atau tidak:

  1. Untuk proyek yang menentukan ApplicationType dan ApplicationTypeRevision, ada folder dengan nomor revisi yang lebih tinggi daripada yang saat ini.

  2. Properti _UpgradePlatformToolsetFor_<safe_toolset_name> didefinisikan untuk toolset saat ini, dan nilainya tidak sama dengan toolset saat ini.

    Dalam nama properti ini, <safe_toolset_name> mewakili nama toolset dengan semua karakter non-alfanumerik yang digantikan oleh garis bawah (_).

Ketika proyek dapat ditingkatkan, proyek tersebut berpartisipasi dalam Penargetan Ulang Solusi. Untuk informasi selengkapnya, lihat IVsTrackProjectRetargeting2.

Jika Anda ingin menghiasi nama proyek di Penjelajah Solusi saat proyek menggunakan toolset tertentu, tentukan _PlatformToolsetShortNameFor_<safe_toolset_name> properti .

Untuk contoh _UpgradePlatformToolsetFor_<safe_toolset_name> definisi properti dan _PlatformToolsetShortNameFor_<safe_toolset_name> , lihat file Microsoft.Cpp.Default.props . Untuk contoh penggunaan, lihat $(VCTargetPath)\file Microsoft.Cpp.Platform.targets.

Peningkatan proyek kustom

Untuk menggunakan objek peningkatan proyek kustom, terapkan komponen MEF, seperti yang ditunjukkan di sini:

/// </summary>
[Export("MyProjectUpgrader", typeof(IProjectRetargetHandler))]
[Export(typeof(IProjectRetargetHandler))]
[ExportMetadata("Name", "MyProjectUpgrader")]
[OrderPrecedence(20)]
[PartMetadata(ProjectCapabilities.Requires, ProjectCapabilities.VisualC)]

internal class MyProjectUpgrader: IProjectRetargetHandler
{
    // ...
}

Kode Anda dapat mengimpor dan memanggil objek peningkatan .vcxproj default:

// ...
[Import("VCDefaultProjectUpgrader")]
// ...
    IProjectRetargetHandler Lazy<IProjectRetargetHandler>
    VCDefaultProjectUpgrader { get; set; }
// ...

IProjectRetargetHandler didefinisikan dalam Microsoft.VisualStudio.ProjectSystem.VS.dll dan mirip IVsRetargetProjectAsyncdengan .

VCProjectUpgraderObjectName Tentukan properti untuk memberi tahu sistem proyek untuk menggunakan objek peningkatan kustom Anda:

<PropertyGroup>
  <VCProjectUpgraderObjectName>MyProjectUpgrader</VCProjectUpgraderObjectName>
</PropertyGroup>

Menonaktifkan peningkatan proyek

Untuk menonaktifkan peningkatan proyek, gunakan NoUpgrade nilai:

<PropertyGroup>
  <VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>
</PropertyGroup>

Cache proyek dan ekstensibilitas

Untuk meningkatkan performa saat bekerja dengan solusi C++ besar di Visual Studio 2017, cache proyek diperkenalkan. Ini diimplementasikan sebagai database SQLite yang diisi dengan data proyek, lalu digunakan untuk memuat proyek tanpa memuat proyek MSBuild atau CPS ke dalam memori.

Karena tidak ada objek CPS yang ada untuk proyek .vcxproj yang dimuat dari cache, komponen MEF ekstensi yang mengimpor UnconfiguredProject atau ConfiguredProject tidak dapat dibuat. Untuk mendukung ekstensibilitas, cache proyek tidak digunakan saat Visual Studio mendeteksi apakah proyek menggunakan (atau kemungkinan akan menggunakan) ekstensi MEF.

Jenis proyek ini selalu dimuat sepenuhnya dan memiliki objek CPS dalam memori, sehingga semua ekstensi MEF dibuat untuk mereka:

  • Proyek startup

  • Proyek yang memiliki peningkatan proyek kustom, yaitu, mereka menentukan VCProjectUpgraderObjectName properti

  • Proyek yang tidak menargetkan Windows Desktop, yaitu, mereka menentukan ApplicationType properti

  • Proyek Item Bersama (.vcxitems) dan proyek apa pun yang mereferensikannya dengan mengimpor proyek .vcxitems.

Jika tidak ada kondisi ini yang terdeteksi, cache proyek dibuat. Cache mencakup semua data dari proyek MSBuild yang diperlukan untuk menjawab get kueri pada VCProjectEngine antarmuka. Ini berarti semua modifikasi di alat peraga MSBuild dan menargetkan tingkat file yang dilakukan oleh ekstensi hanya boleh bekerja dalam proyek yang dimuat dari cache.

Mengirim ekstensi Anda

Untuk informasi tentang cara membuat file VSIX, lihat Mengirim Ekstensi Visual Studio. Untuk informasi tentang cara menambahkan file ke lokasi penginstalan khusus, misalnya, untuk menambahkan file di bawah $(VCTargetsPath), lihat Menginstal di luar folder ekstensi.

Sumber daya tambahan

Microsoft Build System (MSBuild) menyediakan mesin build dan format berbasis XML yang dapat diperluas untuk file proyek. Anda harus terbiasa dengan konsep MSBuild dasar dan dengan cara kerja MSBuild untuk Visual C++ untuk memperluas sistem proyek Visual C++.

Managed Extensibility Framework (MEF) menyediakan API ekstensi yang digunakan oleh CPS dan sistem proyek Visual C++. Untuk gambaran umum tentang bagaimana MEF digunakan oleh CPS, lihat CPS dan MEF dalam gambaran umum VSProjectSystem MEF.

Anda dapat menyesuaikan sistem build yang ada untuk menambahkan langkah build atau jenis file baru. Untuk informasi selengkapnya, lihat Gambaran Umum MSBuild (Visual C++) dan Bekerja dengan properti proyek.