Dela via


Visual Studio C++ Projektsystemsextensibilitet och verktygsuppsättningsintegrering

Visual C++-projektsystemet används för .vcxproj filer. Den baseras på Visual Studio Common Project System (CPS) och tillhandahåller ytterligare, C++ specifika utökningspunkter för enkel integrering av nya verktygsuppsättningar, byggarkitekturer och målplattformar.

C++ MSBuild-målstruktur

Alla .vcxproj filer importerar dessa filer:

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

Dessa filer definierar inte mycket av sig själva. I stället importerar de andra filer baserat på dessa egenskapsvärden:

  • $(ApplicationType)

    Exempel: Windows Store, Android, Linux

  • $(ApplicationTypeRevision)

    Detta måste vara en giltig versionssträng av formatet major.minor[.build[.revision]].

    Exempel: 1.0, 10.0.0.0

  • $(Platform)

    Byggarkitekturen med namnet "Plattform" av historiska skäl.

    Exempel: Win32, x86, x64, ARM

  • $(PlatformToolset)

    Exempel: v140, v141, v141_xp, llvm

Dessa egenskapsvärden anger mappnamn under rotmappen $(VCTargetsPath):

$(VCTargetsPath)\
     programtyp\
        $(ApplicationType)\
            $(ApplicationTypeRevision)\
                 Plattformar\
                    $(Platform)\
                         PlatformToolsets\
                            $(PlatformToolset)
     Plattformar\
        $(Platform)\
             PlatformToolsets\
                $(PlatformToolset)

Mappen $(VCTargetsPath)\Platforms\ används när $(ApplicationType) är tom för Windows Desktop-projekt.

Lägga till en ny plattformsverktyguppsättning

Om du vill lägga till en ny verktygsuppsättning, till exempel "MyToolset" för den befintliga Win32-plattformen, skapar du en MyToolset-mapp under $(VCTargetsPath)\Platforms\Win32\PlatformToolsets\och skapar Toolset.props och Toolset.targets filer i den.

Varje mappnamn under PlatformToolsets visas i dialogrutan Project Properties som en tillgänglig Platform Toolset för den angivna plattformen, som du ser här:

Egenskapen Plattformsverktyg i dialogrutan för projektegenskapssidor

Skapa liknande MyToolset mappar och Toolset.props och Toolset.targets filer i varje befintlig plattformsmapp som den här verktygsuppsättningen stöder.

Lägga till en ny plattform

Om du vill lägga till en ny plattform, till exempel "MyPlatform", skapar du en MyPlatform- mapp under $(VCTargetsPath)\Platforms\och skapar Platform.default.props, Platform.propsoch Platform.targets filer i den. Skapa även en $(VCTargetsPath)\Platforms\MyPlatform\PlatformToolsets\ mapp och skapa minst en verktygsuppsättning i den.

Alla mappnamn under mappen Plattformar för varje $(ApplicationType) och $(ApplicationTypeRevision) visas i IDE som tillgängliga Plattform alternativ för ett projekt.

Det nya plattformsalternativet i dialogrutan Ny projektplattform

Lägga till en ny programtyp

Om du vill lägga till en ny programtyp skapar du mappen MyApplicationType under $(VCTargetsPath)\Application Type\ och skapar en Defaults.props- fil i den. Minst en revision krävs för en programtyp, så skapa även mappen $(VCTargetsPath)\Application Type\MyApplicationType\1.0 och skapa en Defaults.props fil i den. Du bör också skapa en $(VCTargetsPath)\ApplicationType\MyApplicationType\1.0\Platforms mapp och skapa minst en plattform i den.

$(ApplicationType) och $(ApplicationTypeRevision) egenskaper visas inte i användargränssnittet. De definieras i projektmallarna och kan inte ändras när projektet har skapats.

Importträdet för .vcxproj

Ett förenklat importträd för Microsoft C++ props och målfiler ser ut så här:

$(VCTargetsPath) \ Microsoft.Cpp.Default.props
     $(MSBuildExtensionsPath) \ $(MSBuildToolsVersion) \ Microsoft.Common.props
     $(VCTargetsPath) \ ImportFör\standard\*.rekvisita
     $(VCTargetsPath) \ Programtyp\$(ApplicationType)\Default.props
     $(VCTargetsPath) \ Programtyp\$(ApplicationType)\$(ApplicationTypeRevision)\Default.props
     $(VCTargetsPath) \ Programtyp\$(ApplicationType)\$(ApplicationTypeRevision)\Plattformar\$(Platform)\Platform.default.props
     $(VCTargetsPath) \ ImportAfter\Default\*.rekvisita

Windows Desktop-projekt definierar inte $(ApplicationType), så de importerar bara

$(VCTargetsPath) \ Microsoft.Cpp.Default.props
     $(MSBuildExtensionsPath) \ $(MSBuildToolsVersion) \ Microsoft.Common.props
     $(VCTargetsPath) \ ImporteraFöre\Standardinställning\*.egenskaper
     $(VCTargetsPath) \ Platforms\$(Platform)\Platform.default.props
     $(VCTargetsPath) \ ImportAfter\Default\*.rekvisita

Vi använder egenskapen $(_PlatformFolder) för att lagra $(Platform) plattformsmappplatser. Den här egenskapen är

$(VCTargetsPath) \ Plattformar\$(Platform)

för Windows Desktop-appar och

$(VCTargetsPath) \ programtyp\$(ApplicationType)\$(ApplicationTypeRevision)\plattformar\$(Platform)

för allt annat.

Props-filerna importeras i följande ordning:

$(VCTargetsPath) \ Microsoft.Cpp.props
     $(_PlatformFolder) \ Platform.props
         $(VCTargetsPath) \ Microsoft.Cpp.Platform.props
             $(_PlatformFolder) \ ImportBefore\*.rekvisita
             $(_PlatformFolder) \ PlatformToolsets\$(PlatformToolset)\Toolset.props
             $(_PlatformFolder) \ ImportAfter\*.rekvisita

Målfilerna importeras i följande ordning:

$(VCTargetsPath) \ Microsoft.Cpp.targets
     $(VCTargetsPath) \ Microsoft.Cpp.Current.targets
         $(_PlatformFolder) \ Platform.targets
             $(VCTargetsPath) \ Microsoft.Cpp.Platform.targets
                 $(_PlatformFolder) \ ImportBefore\*.mål
                 $(_PlatformFolder) \ PlatformToolsets\$(PlatformToolset)\Toolset.target
                 $(_PlatformFolder) \ ImportAfter\*.mål

Om du behöver definiera några standardegenskaper för din verktygsuppsättning kan du lägga till filer i lämpliga ImportBefore- och ImportAfter-mappar.

Author Toolset.props och Toolset.targets-filer

Toolset.props och Toolset.targets filer har fullständig kontroll över vad som händer under en version när den här verktygsuppsättningen används. De kan också styra tillgängliga felsökningsprogram, en del av IDE-användargränssnittet, till exempel innehållet i dialogrutan egenskapssidor och vissa andra aspekter av projektbeteendet.

Även om en verktygsuppsättning kan åsidosätta hela byggprocessen vill du vanligtvis bara att din verktygsuppsättning ska ändra eller lägga till några byggsteg eller använda olika byggverktyg som en del av en befintlig byggprocess. För att uppnå det här målet finns det ett antal vanliga rekvisita- och målfiler som din verktygsuppsättning kan importera. Beroende på vad du vill att din verktygsuppsättning ska göra kan dessa filer vara användbara att använda som importer eller som exempel:

  • $(VCTargetsPath) \ Microsoft.CppCommon.targets

    Den här filen definierar de viktigaste delarna i den interna byggprocessen och importerar även:

    • $(VCTargetsPath) \ Microsoft.CppBuild.targets

    • $(VCTargetsPath) \ Microsoft.BuildSteps.targets

    • $(MSBuildToolsPath) \ Microsoft.Common.Targets

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

    Anger standardvärden för verktygsuppsättningar som använder Microsoft-kompilatorerna och mål-Windows.

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

    Den här filen bestämmer Platsen för Windows SDK och definierar några viktiga egenskaper för appar som riktar sig till Windows.

Integrera verktygsuppsättningsspecifika mål med standardprocessen för C++-kompilering

Standardprocessen för C++-kompilering definieras i Microsoft.CppCommon.targets. Målen där anropar inte några specifika byggverktyg. de anger de viktigaste byggstegen, deras ordning och beroenden.

C++-versionen har tre huvudsteg som representeras av följande mål:

  • BuildGenerateSources

  • BuildCompile

  • BuildLink

Eftersom varje byggsteg kan köras oberoende av varandra kan mål som körs i ett steg inte förlita sig på de objektgrupper och egenskaper som definieras i de mål som körs som en del av ett annat steg. Den här divisionen tillåter vissa optimeringar av byggprestanda. Även om den inte används som standard uppmuntras du fortfarande att respektera den här separationen.

De mål som körs i varje steg styrs av följande egenskaper:

  • $(BuildGenerateSourcesTargets)

  • $(BuildCompileTargets)

  • $(BeforeBuildLinkTargets)

Varje steg har också egenskaper för Före och Efter.

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

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

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

Se filen Microsoft.CppBuild.targets för exempel på de mål som ingår i varje steg:

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

Om du tittar på målen, till exempel _ClCompile, ser du att de inte gör något direkt själva, utan i stället är beroende av andra mål, inklusive ClCompile:

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

ClCompile och andra byggverktygsspecifika mål definieras som tomma mål i Microsoft.CppBuild.targets:

<Target Name="ClCompile"/>

Eftersom ClCompile-målet är tomt, om det inte åsidosätts av en verktygsuppsättning, utförs ingen verklig byggåtgärd. Verktygsuppsättningsmålen kan åsidosätta det ClCompile målet, dvs. de kan innehålla en annan ClCompile definition efter att ha importerat Microsoft.CppBuild.targets:

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

Trots namnet, som skapades innan Visual Studio implementerade plattformsoberoende stöd, behöver ClCompile-målet inte anropa CL.exe. Den kan också anropa Clang, gcc eller andra kompilatorer med hjälp av lämpliga MSBuild-uppgifter.

Det ClCompile målet bör inte ha några beroenden förutom det SelectClCompile målet, vilket krävs för att kompileringskommandot för en enskild fil ska fungera i IDE.

MSBuild-uppgifter som ska användas i verktygssatsmål

Om du vill anropa ett verkligt byggverktyg måste målet anropa en MSBuild-uppgift. Det finns en grundläggande Exec-uppgift som gör att du kan ange en kommandorad som ska köras. Men byggverktyg har vanligtvis många alternativ, indata och utdata att spåra för inkrementella versioner, så det är mer meningsfullt att ha särskilda uppgifter för dem. Till exempel översätter CL-uppgiften MSBuild-egenskaper till CL.exe växlar, skriver dem till en svarsfil och anropar CL.exe. Den spårar även alla in- och utdatafiler för senare inkrementella versioner. För mer information, se Stegvisa byggnationer och up-todatumkontroller.

Microsoft.Cpp.Common.Tasks.dll implementerar följande uppgifter:

  • BSCMake

  • CL

  • ClangCompile (clang-gcc-växlar)

  • LIB

  • LINK

  • MIDL

  • Mt

  • RC

  • XDCMake

  • CustomBuild (till exempel Exec men med indata- och utdataspårning)

  • SetEnv

  • GetOutOfDateItems

Om du har ett verktyg som utför samma åtgärd som ett befintligt verktyg och som har liknande kommandoradsväxlar (som clang-cl och CL) kan du använda samma uppgift för båda.

Om du behöver skapa en ny uppgift för ett byggverktyg kan du välja bland följande alternativ:

  1. Om du använder den här uppgiften sällan, eller om några sekunder inte spelar någon roll för din version, kan du använda MSBuild-aktiviteter som är infogade:

    • Xaml-uppgift (en anpassad byggregel)

      Ett exempel på en Xaml-aktivitetsdeklaration finns i $(VCTargetsPath)\BuildCustomizations\masm.xml, och för dess användning, se $(VCTargetsPath)\BuildCustomizations\masm.targets.

    • Koduppgift

  2. Om du vill ha bättre aktivitetsprestanda eller bara behöver mer komplexa funktioner använder du den vanliga MSBuild-uppgiftsskrivning process.

    Om inte alla indata och utdata för verktyget visas på kommandoraden för verktyget, som i CL, MIDLoch RC fall, och om du vill ha automatisk indata- och utdatafilspårning och .tlog-filskapande, härleder du din uppgift från klassen Microsoft.Build.CPPTasks.TrackedVCToolTask. För närvarande finns det dokumentation för ToolTask-klassen, men det finns inga exempel eller dokumentation för detaljer för klassen TrackedVCToolTask. Om detta skulle vara av särskilt intresse lägger du till din röst i en begäran på Developer Community.

Inkrementella kompileringar och up-to-datumkontroller

Standardmålen för MSBuild-inkrementellt bygge använder Inputs- och Outputs-attribut. Om du anger dem anropar MSBuild endast målet om någon av indata har en nyare tidsstämpel än alla utdata. Eftersom källfiler ofta inkluderar eller importerar andra filer och byggverktyg producerar olika utdata beroende på verktygsalternativen är det svårt att ange alla möjliga indata och utdata i MSBuild-mål.

För att hantera det här problemet använder C++-versionen en annan teknik för att stödja inkrementella versioner. De flesta mål anger inte indata och utdata, och därför körs alltid under bygget. De uppgifter som anropas av målen skriver information om alla indata och utdata i tlog-filer som har tillägget .tlog. .tlog-filerna används av senare versioner för att kontrollera vad som har ändrats och måste återskapas och vad som är up-to-date. .tlog-filerna är också den enda källan för standardversionen up-todatumkontroll i IDE.

För att fastställa alla indata och utdata använder interna verktygsuppgifter tracker.exe och FileTracker klass som tillhandahålls av MSBuild.

Microsoft.Build.CPPTasks.Common.dll definierar den offentliga abstrakta basklassen TrackedVCToolTask. De flesta av de interna verktygsuppgifterna härleds från den här klassen.

Från och med Visual Studio 2017 uppdatering 15.8 kan du använda den GetOutOfDateItems uppgift som implementerats i Microsoft.Cpp.Common.Tasks.dll för att skapa .tlog-filer för anpassade mål med kända indata och utdata. Du kan också skapa dem med hjälp av WriteLinesToFile uppgift. Se målet _WriteMasmTlogs i $(VCTargetsPath)\BuildCustomizations\masm.targets som ett exempel.

.tlog-filer

Det finns tre typer av .tlog-filer: läsa, skrivaoch kommandorad. Att läsa och skriva .tlog-filer används i inkrementella byggen och av datumkontrollen up-toi den integrerade utvecklingsmiljön. Kommandoradsfiler för .tlog används endast i inkrementella versioner.

MSBuild tillhandahåller dessa hjälpklasser för att läsa och skriva .tlog-filer:

Klassen FlatTrackingData kan användas för att komma åt både läsa och skriva .tlog-filer och identifiera indata som är nyare än utdata, eller om utdata saknas. Den används i datumkontrollen up-to.

Kommandoradsfiler för .tlog innehåller information om kommandorader som används i bygget. De används endast för inkrementella versioner, inte up-to-date-kontroller, så det interna formatet bestäms av den MSBuild-uppgift som genererar dem.

Läs .tlog-format

Read .tlog files (*.read.*.tlog) innehåller information om källfiler och deras beroenden.

En caret (^) i början av en rad anger en eller flera källor. Källor som delar samma beroenden avgränsas med en lodrät stapel (|).

Beroendefiler visas efter källorna, var och en på en självständig rad. Alla filnamn är fullständiga sökvägar.

Anta till exempel att dina projektkällor finns i F:\test\ConsoleApplication1\ConsoleApplication1. Om källfilen, Class1.cpp, innehåller dessa,

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

sedan innehåller filen CL.read.1.tlog källfilen följt av dess två beroenden:

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

Det krävs inte att skriva filnamn i versaler, men det är praktiskt för vissa verktyg.

Skriv .tlog-formatet

Skriv .tlog-filer (*.write.*.tlog) ansluter källor och utdata.

En caret (^) i början av en rad anger en eller flera källor. Flera källor separeras med en lodrät linje (|).

Utdatafilerna som skapats från källorna bör visas efter källorna, var och en på sin egen rad. Alla filnamn måste vara fullständiga sökvägar.

För ett enkelt ConsoleApplication-projekt som har ytterligare en källfil Class1.cppkan link.write.1.tlog fil innehålla:

^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

Designtidsversion

I IDE använder .vcxproj projekt en uppsättning MSBuild-mål för att hämta ytterligare information från projektet och återskapa utdatafiler. Vissa av dessa mål används bara i designtidsversioner, men många av dem används i både vanliga versioner och designtidsversioner.

Allmän information om designtidsversioner finns i CPS-dokumentationen för Design-time-versioner. Den här dokumentationen gäller endast delvis för Visual C++-projekt.

De CompileDesignTime- och Compile-mål, som nämns i dokumentationen för designtidsversioner, körs aldrig för .vcxproj-projekt. Visual C++ .vcxproj-projekt använder olika designtidsmål för att hämta IntelliSense-information.

Designtidsmål för IntelliSense-information

Designtidsmål som används i .vcxproj projekt definieras i $(VCTargetsPath)\Microsoft.Cpp.DesignTime.targets.

Målet GetClCommandLines samlar in kompilatoralternativ för IntelliSense:

<Target
  Name="GetClCommandLines"
  Returns="@(ClCommandLines)"
  DependsOnTargets="$(DesignTimeBuildInitTargets);$(ComputeCompileInputsTargets)">
  • DesignTimeBuildInitTargets – mål enbart för designtid, krävs för bygginitiering under designtid. Dessa mål inaktiverar bland annat några av de vanliga byggfunktionerna för att förbättra prestanda.

  • ComputeCompileInputsTargets – en uppsättning mål som ändrar kompilatoralternativ och -objekt. Dessa mål körs i både designtid och vanliga versioner.

Målet anropar CLCommandLine-tasken för att skapa kommandoraden som ska användas för IntelliSense. Återigen, trots sitt namn, kan det hantera inte bara CL alternativ, men Clang och gcc alternativ också. Typen av kompilatorväxlar styrs av egenskapen ClangMode.

För närvarande använder kommandoraden som skapas av CLCommandLine uppgift alltid CL-växlar (även i Clang-läge) eftersom de är enklare för IntelliSense-motorn att parsa.

Om du lägger till ett kompileringsmål som körs före kompilering, oavsett om det är vanligt eller designtid, säkerställ att det inte stör designtiduppbyggnader eller påverkar prestanda. Det enklaste sättet att testa målet är att öppna en kommandotolk för utvecklare och köra det här kommandot:

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

Det här kommandot skapar en detaljerad bygglogg, msbuild.log, som har en prestandasammanfattning för målen och aktiviteterna i slutet.

Se till att använda Condition ="'$(DesignTimeBuild)' != 'true'" i alla åtgärder som bara är meningsfulla för vanliga versioner och inte för designtidsversioner.

Designtidsmål som genererar källor

Den här funktionen är inaktiverad som standard för inbyggda skrivbordsprojekt och stöds för närvarande inte i cachelagrade projekt.

Om GeneratorTarget metadata definieras för ett projektobjekt körs målet automatiskt både när projektet läses in och när källfilen ändras.

För att till exempel automatiskt generera .cpp- eller .h-filer från .xaml-filer definierar $(VSInstallDir)\MSBuild\Microsoft\WindowsXaml\v16.0\*\Microsoft.Windows.UI.Xaml.CPP.Targets-filer dessa entiteter:

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

Om du vill använda Task.HostObject för att hämta innehåll som inte har sparats i källfiler bör målen och uppgiften registreras som MsbuildHostObjects för de angivna projekten i en pkgdef:

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

Utökningsbarhet för Visual C++-projekt i Visual Studio IDE

Visual C++-projektsystemet baseras på VS Project Systemoch använder dess utökningspunkter. Implementeringen av projekthierarkin är dock specifik för Visual C++ och baseras inte på CPS, så hierarkins utökningsbarhet är begränsad till projektobjekt.

Projektegenskapssidor

Allmän designinformation finns i Framework Multi-Targeting for VC++ Projects.

Enkelt uttryckt definieras de egenskapssidor som visas i dialogrutan Projektegenskaper för ett C++-projekt av regel filer. En regelfil anger en uppsättning egenskaper som ska visas på en egenskapssida och hur och var de ska sparas i projektfilen. Regelfiler är .xml filer som använder Xaml-format. De typer som används för att serialisera dem beskrivs i Microsoft.Build.Framework.XamlTypes. För mer information om användningen av XML-regelfiler för egenskapssidan i projekt, se .

Regelfilerna måste läggas till i objektgruppen PropertyPageSchema:

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

Context metadata begränsar regelns synlighet, som också styrs av regeltyp, och kan ha något av följande värden:

Project | File | PropertySheet

CPS stöder andra värden för kontexttyp, men de används inte i Visual C++-projekt.

Om regeln ska vara synlig i mer än en kontext använder du semikolon (;) för att avgränsa kontextvärdena, som du ser här:

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

Regelformat och huvudtyper

Regelformatet är enkelt, så det här avsnittet beskriver bara de attribut som påverkar hur regeln ser ut i användargränssnittet.

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

Attributet PageTemplate definierar hur regeln visas i dialogrutan egenskapssidor. Attributet kan ha något av följande värden:

Attribut Beskrivning
generic Alla egenskaper visas på en sida under Kategorirubriker
Regeln kan vara synlig för Project och PropertySheet kontexter, men inte File.

Exempel: $(VCTargetsPath)\1033\general.xml
tool Kategorier visas som undersidor.
Regeln kan visas i alla kontexter: Project, PropertySheet och File.
Regeln visas endast i Projektegenskaper om projektet har objekt med ItemType som definierats i Rule.DataSource, såvida inte regelnamnet ingår i den ProjectTools objektgruppen.

Exempel: $(VCTargetsPath)\1033\clang.xml
debugger Sidan visas som en del av felsökningssidan.
Kategorier ignoreras för närvarande.
Regelnamnet ska matcha Debug Launcher MEF-objektets ExportDebugger-attribut.

Exempel: $(VCTargetsPath)\1033\debugger_local_windows.xml
anpassade Anpassad mall. Namnet på mallen ska matcha attributet ExportPropertyPageUIFactoryProvider för det PropertyPageUIFactoryProvider MEF-objektet. Se Microsoft.VisualStudio.ProjectSystem.Designers.Properties.IPropertyPageUIFactoryProvider.

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

Om regeln använder en av de Property Grid-baserade mallarna kan den använda dessa utökningspunkter för sina egenskaper:

Utöka en regel

Om du vill använda en befintlig regel, men behöver lägga till eller ta bort (dvs. dölja) bara några egenskaper, kan du skapa en -tilläggsregel.

Åsidosätt en regel

Du kanske vill att din verktygsuppsättning ska använda de flesta standardreglerna för projektet, men bara ersätta en eller några av dem. Anta till exempel att du bara vill ändra C/C++-regeln för att visa olika kompilatorväxlar. Du kan ange en ny regel med samma namn och visningsnamn som den befintliga regeln och inkludera den i den PropertyPageSchema objektgruppen efter importen av standard-cpp-mål. Endast en regel med ett angivet namn används i projektet och den sista som ingår i PropertyPageSchema objektgruppen vinner.

Projektobjekt

Filen ProjectItemsSchema.xml definierar värdena ContentType och ItemType för Objekt som behandlas som Projektobjekt och definierar FileExtension element för att avgöra vilken objektgrupp en ny fil läggs till i.

Standardfilen ProjectItemsSchema finns i $(VCTargetsPath)\1033\ProjectItemsSchema.xml. Om du vill utöka den måste du skapa en schemafil med ett nytt namn, till exempel 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>

Lägg sedan till i målfilen:

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

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

Felsökare

Felsökningstjänsten i Visual Studio stöder utökningsbarhet för felsökningsmotorn. Mer information finns i följande exempel:

Om du vill ange felsökningsmotorer och andra egenskaper för felsökningssessionen måste du implementera Felsökningsstartare MEF-komponent och lägga till en debugger regel. Ett exempel finns i filen $(VCTargetsPath)\1033\debugger_local_windows.xml.

Gruppera

.vcxproj-projekt använder Visual Studio Project System-utbyggbarhet för Deploy Providers.

Version up-To- datumkontroll

Som standard kräver bygg-up-to-date-kontrollen att .tlog-filer skapas för att läsa och skriva i mappen $(TlogLocation) under bygget för alla indata och utdata.

För att använda en anpassad up-to-datumkontroll:

  1. Inaktivera standardkontrollen up-to-date genom att lägga till funktionen NoVCDefaultBuildUpToDateCheckProvider i filen Toolset.targets:

    <ItemGroup>
      <ProjectCapability Include="NoVCDefaultBuildUpToDateCheckProvider" />
    </ItemGroup>
    
  2. Implementera din egen IBuildUpToDateCheckProvider.

Projektuppgradering

Förvald .vcxproj projektuppgraderare

Som standard ändrar .vcxproj-projektuppgraderaren PlatformToolset, ApplicationTypeRevision, MSBuild-verktygsuppsättningsversionen och .NET Framework. De två sista ändras alltid till standardinställningarna för Visual Studio-versionen, men PlatformToolset och ApplicationTypeRevision kan styras av särskilda MSBuild-egenskaper.

Uppgraderaren använder dessa kriterier för att avgöra om ett projekt kan uppgraderas eller inte:

  1. För projekt som definierar ApplicationType och ApplicationTypeRevisionfinns det en mapp med ett högre revisionsnummer än det aktuella.

  2. Egenskapen _UpgradePlatformToolsetFor_<safe_toolset_name> definieras för den aktuella verktygsuppsättningen och dess värde är inte lika med den aktuella verktygsuppsättningen.

    I dessa egenskapsnamn representerar <safe_toolset_name> verktygsuppsättningens namn med alla icke-alfanumeriska tecken ersatta med ett understreck (_).

När ett projekt kan uppgraderas deltar det i Solution Retargeting. Mer information finns i IVsTrackProjectRetargeting2.

Om du vill pryda projektnamn i Solution Explorer när projekt använder en specifik verktygsuppsättning definierar du en egenskap för _PlatformToolsetShortNameFor_<safe_toolset_name>.

Exempel på _UpgradePlatformToolsetFor_<safe_toolset_name>- och _PlatformToolsetShortNameFor_<safe_toolset_name> egenskapsdefinitioner finns i filen Microsoft.Cpp.Default.props. Exempel på användning finns i filen $(VCTargetPath)\Microsoft.Cpp.Platform.targets.

Anpassad projektuppgraderare

Om du vill använda ett anpassat projektuppgraderingsobjekt implementerar du en MEF-komponent, som du ser här:

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

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

Koden kan importera och anropa standardobjektet .vcxproj upgrader:

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

IProjectRetargetHandler definieras i Microsoft.VisualStudio.ProjectSystem.VS.dll och liknar IVsRetargetProjectAsync.

Definiera egenskapen VCProjectUpgraderObjectName för att instruera projektsystemet att använda ditt anpassade uppgraderingsobjekt:

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

Inaktivera projektuppgradering

Om du vill inaktivera projektuppgraderingar använder du ett NoUpgrade värde:

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

Projektcache och utökningsbarhet

För att förbättra prestanda när du arbetar med stora C++-lösningar i Visual Studio 2017 introducerades projektcachen. Den implementeras som en SQLite-databas ifylld med projektdata och används sedan för att läsa in projekt utan att läsa in MSBuild- eller CPS-projekt i minnet.

Eftersom det inte finns några CPS-objekt för .vcxproj projekt som läses in från cacheminnet kan tilläggets MEF-komponenter som importerar UnconfiguredProject eller ConfiguredProject inte skapas. För att stödja utökningsbarhet används inte projektcacheminnet när Visual Studio identifierar om ett projekt använder (eller sannolikt kommer att använda) MEF-tillägg.

Dessa projekttyper är alltid helt inlästa och har CPS-objekt i minnet, så alla MEF-tillägg skapas för dem:

  • Startprojekt

  • Projekt som har en anpassad projektuppgraderare, d.ex. definierar de en VCProjectUpgraderObjectName egenskap

  • Projekt som inte riktar sig mot Desktop Windows, det vill säga att de definierar en ApplicationType-egenskap

  • Projekt med delade objekt (.vcxitems) och alla projekt som refererar till dem genom import av .vcxitems-projekt.

Om inget av dessa villkor identifieras skapas en projektcachen. Cachen innehåller alla data från MSBuild-projektet som krävs för att besvara get frågor på VCProjectEngine gränssnitt. Det innebär att alla ändringar på MSBuild-rekvisita- och målfilnivån som utförs av ett tillägg bara ska fungera i projekt som läses in från cacheminnet.

Skicka ditt tillägg

Information om hur du skapar VSIX-filer finns i Shipping Visual Studio Extensions. Information om hur du lägger till filer på särskilda installationsplatser, till exempel för att lägga till filer under $(VCTargetsPath), finns i Installera utanför mappen extensions.

Ytterligare resurser

Microsoft Build System (MSBuild) tillhandahåller byggmotorn och det utökningsbara XML-baserade formatet för projektfiler. Du bör känna till grundläggande MSBuild-begrepp och hur MSBuild för Visual C++ fungerar för att utöka Visual C++-projektsystemet.

Managed Extensibility Framework (MEF) innehåller tilläggs-API:er som används av CPS och Visual C++-projektsystemet. En översikt över hur MEF används av CPS finns i CPS och MEF i VSProjectSystem-översikten över MEF.

Du kan anpassa det befintliga byggsystemet för att lägga till byggsteg eller nya filtyper. Mer information finns i MSBuild (Visual C++) Översikt och Arbeta med projektegenskaper.