Integrazione dell'estendibilità e del set di strumenti del sistema di progetto di Visual Studio C++
Il sistema di progetto Visual C++ viene usato per .vcxproj file. Si basa su Visual Studio Common Project System (CPS) e offre ulteriori punti di estendibilità specifici di C++ per semplificare l'integrazione di nuovi set di strumenti, architetture di compilazione e piattaforme di destinazione.
Struttura delle destinazioni MSBuild C++
Tutti i file .vcxproj importano questi file:
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
Questi file definiscono poco da soli. Importano invece altri file in base ai valori delle proprietà seguenti:
$(ApplicationType)
Esempi: Windows Store, Android, Linux
$(ApplicationTypeRevision)
Deve essere una stringa di versione valida, del formato major.minor[.build[.revision]].
Esempi: 1.0, 10.0.0.0
$(Platform)
Architettura di compilazione, denominata "Piattaforma" per motivi cronologici.
Esempi: Win32, x86, x64, ARM
$(PlatformToolset)
Esempi: v140, v141, v141_xp, llvm
Questi valori delle proprietà specificano i nomi delle cartelle nella $(VCTargetsPath)
cartella radice:
$(VCTargetsPath)
\
Tipo di applicazione\
$(ApplicationType)
\
$(ApplicationTypeRevision)
\
Piattaforme\
$(Platform)
\
PlatformToolsets\
$(PlatformToolset)
Piattaforme\
$(Platform)
\
PlatformToolsets\
$(PlatformToolset)
La $(VCTargetsPath)
\cartella Platforms\ viene usata quando $(ApplicationType)
è vuota per i progetti desktop di Windows.
Aggiungere un nuovo set di strumenti della piattaforma
Per aggiungere un nuovo set di strumenti, ad esempio "MyToolset" per la piattaforma Win32 esistente, creare una cartella MyToolset in $(VCTargetsPath)
\Platforms\Win32\PlatformToolsets\e creare file Toolset.props e Toolset.targets in esso contenuti.
Ogni nome di cartella in PlatformToolsets viene visualizzato nella finestra di dialogo Proprietà progetto come set di strumenti della piattaforma disponibile per la piattaforma specificata, come illustrato di seguito:
Creare cartelle MyToolset simili e file Toolset.props e Toolset.targets in ogni cartella della piattaforma esistente supportata da questo set di strumenti.
Aggiungere una nuova piattaforma
Per aggiungere una nuova piattaforma, ad esempio "MyPlatform", creare una cartella MyPlatform in$(VCTargetsPath)
\Platforms\e creare file Platform.default.props, Platform.props e Platform.targets in esso contenuti. Creare anche una $(VCTargetsPath)
cartella \Platforms\MyPlatform\PlatformToolsets\ e creare almeno un set di strumenti.
Tutti i nomi di cartella nella cartella Piattaforme per ognuno $(ApplicationType)
e $(ApplicationTypeRevision)
vengono visualizzati nell'IDE come opzioni di piattaforma disponibili per un progetto.
Aggiungere un nuovo tipo di applicazione
Per aggiungere un nuovo tipo di applicazione, creare una cartella MyApplicationType in$(VCTargetsPath)
\Application Type\ e crearvi un file Defaults.props. Per un tipo di applicazione è necessaria almeno una revisione, quindi creare anche una $(VCTargetsPath)
cartella \Application Type\MyApplicationType\1.0 e creare un file Defaults.props . È anche consigliabile creare una $(VCTargetsPath)
cartella \ApplicationType\MyApplicationType\1.0\Platforms e crearvi almeno una piattaforma.
$(ApplicationType)
le proprietà e $(ApplicationTypeRevision)
non sono visibili nell'interfaccia utente. Vengono definiti nei modelli di progetto e non possono essere modificati dopo la creazione del progetto.
Albero di importazione .vcxproj
Un albero semplificato delle importazioni per i file di proprietà e destinazioni di Microsoft C++ è simile al seguente:
$(VCTargetsPath)
\Microsoft.Cpp.Default.props
$(MSBuildExtensionsPath)
\$(MSBuildToolsVersion)
\Microsoft.Common.props
$(VCTargetsPath)
\ImportBefore\Default\*.trovarobe
$(VCTargetsPath)
\Tipo di\\$(ApplicationType)
applicazione Default.props
$(VCTargetsPath)
\Tipo di$(ApplicationTypeRevision)
\$(ApplicationType)
\\applicazione Default.props
$(VCTargetsPath)
\Platform.default.props\\$(Platform)
del tipo di applicazione\$(ApplicationType)
\$(ApplicationTypeRevision)
\
$(VCTargetsPath)
\ImportAfter\Default\*.trovarobe
I progetti desktop di Windows non definiscono $(ApplicationType)
, quindi importano solo
$(VCTargetsPath)
\Microsoft.Cpp.Default.props
$(MSBuildExtensionsPath)
\$(MSBuildToolsVersion)
\Microsoft.Common.props
$(VCTargetsPath)
\ImportBefore\Default\*.trovarobe
$(VCTargetsPath)
\Platform.default.props\$(Platform)
\
$(VCTargetsPath)
\ImportAfter\Default\*.trovarobe
Verrà usata la $(_PlatformFolder)
proprietà per contenere i percorsi delle cartelle della $(Platform)
piattaforma. Questa proprietà è
$(VCTargetsPath)
\Piattaforme\$(Platform)
per le app desktop di Windows e
$(VCTargetsPath)
\Piattaforme del tipo di$(ApplicationTypeRevision)
\$(ApplicationType)
\\applicazione\$(Platform)
per tutto il resto.
I file props vengono importati in questo ordine:
$(VCTargetsPath)
\Microsoft.Cpp.props
$(_PlatformFolder)
\Platform.props
$(VCTargetsPath)
\Microsoft.Cpp.Platform.props
$(_PlatformFolder)
\ImportBefore\*.trovarobe
$(_PlatformFolder)
\PlatformToolsets\\$(PlatformToolset)
Toolset.props
$(_PlatformFolder)
\ImportAfter\*.trovarobe
I file di destinazione vengono importati in questo ordine:
$(VCTargetsPath)
\Microsoft.Cpp.targets
$(VCTargetsPath)
\Microsoft.Cpp.Current.targets
$(_PlatformFolder)
\Platform.targets
$(VCTargetsPath)
\Microsoft.Cpp.Platform.targets
$(_PlatformFolder)
\ImportBefore\*.Obiettivi
$(_PlatformFolder)
\PlatformToolsets\\$(PlatformToolset)
Toolset.target
$(_PlatformFolder)
\ImportAfter\*.Obiettivi
Se è necessario definire alcune proprietà predefinite per il set di strumenti, è possibile aggiungere file alle cartelle ImportBefore e ImportAfter appropriate.
Creare file Toolset.props e Toolset.targets
I file Toolset.props e Toolset.targets hanno il controllo completo su cosa accade durante una compilazione quando viene usato questo set di strumenti. Possono anche controllare i debugger disponibili, alcune delle interfacce utente dell'IDE, ad esempio il contenuto nella finestra di dialogo Pagine delle proprietà e altri aspetti del comportamento del progetto.
Anche se un set di strumenti può eseguire l'override dell'intero processo di compilazione, in genere si vuole solo modificare o aggiungere alcuni passaggi di compilazione o usare strumenti di compilazione diversi, come parte di un processo di compilazione esistente. Per raggiungere questo obiettivo, è possibile importare numerosi file di oggetti visivi e destinazioni comuni che il set di strumenti può importare. A seconda di ciò che si vuole fare il set di strumenti, questi file possono essere utili da usare come importazioni o come esempi:
$(VCTargetsPath)
\Microsoft.CppCommon.targetsQuesto file definisce le parti principali del processo di compilazione nativo e importa anche:
$(VCTargetsPath)
\Microsoft.CppBuild.targets$(VCTargetsPath)
\Microsoft.BuildSteps.targets$(MSBuildToolsPath)
\Microsoft.Common.Targets
$(VCTargetsPath)
\Microsoft.Cpp.Common.propsImposta le impostazioni predefinite per i set di strumenti che usano i compilatori Microsoft e Windows di destinazione.
$(VCTargetsPath)
\Microsoft.Cpp.WindowsSDK.propsQuesto file determina il percorso di Windows SDK e definisce alcune proprietà importanti per le app destinate a Windows.
Integrare destinazioni specifiche del set di strumenti con il processo di compilazione C++ predefinito
Il processo di compilazione C++ predefinito è definito in Microsoft.CppCommon.targets. Le destinazioni non chiamano strumenti di compilazione specifici; specificano i passaggi di compilazione principali, l'ordine e le dipendenze.
La compilazione C++ include tre passaggi principali, rappresentati dalle destinazioni seguenti:
BuildGenerateSources
BuildCompile
BuildLink
Poiché ogni passaggio di compilazione può essere eseguito in modo indipendente, le destinazioni in esecuzione in un unico passaggio non possono basarsi sui gruppi di elementi e sulle proprietà definite nelle destinazioni eseguite come parte di un passaggio diverso. Questa divisione consente alcune ottimizzazioni delle prestazioni di compilazione. Anche se non viene usato per impostazione predefinita, è comunque consigliabile rispettare questa separazione.
Le destinazioni eseguite all'interno di ogni passaggio sono controllate da queste proprietà:
$(BuildGenerateSourcesTargets)
$(BuildCompileTargets)
$(BeforeBuildLinkTargets)
Ogni passaggio include anche le proprietà Before e After.
<Target
Name="_BuildGenerateSourcesAction"
DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildGenerateSourcesTargets);$(BuildGenerateSourcesTargets);$(AfterBuildGenerateSourcesTargets)" />
<Target
Name="\_BuildCompileAction"
DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildCompileTargets);$(BuildCompileTargets);$(AfterBuildCompileTargets)" />
<Target
Name="\_BuildLinkAction"
DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildLinkTargets);$(BuildLinkTargets);$(AfterBuildLinkTargets)" />
Per esempi delle destinazioni incluse in ogni passaggio, vedere il file Microsoft.CppBuild.targets :
<BuildCompileTargets Condition="'$(ConfigurationType)'\!='Utility'">
$(BuildCompileTargets);
_ClCompile;
_ResGen;
_ResourceCompile;
$(BuildLibTargets);
</BuildCompileTargets>
Se si esaminano le destinazioni, ad esempio _ClCompile
, si noterà che non eseguono alcuna operazione direttamente da soli, ma dipendono invece da altre destinazioni, tra cui ClCompile
:
<Target Name="_ClCompile"
DependsOnTargets="$(BeforeClCompileTargets);$(ComputeCompileInputsTargets);MakeDirsForCl;ClCompile;$(AfterClCompileTargets)" >
</Target>
ClCompile
e altre destinazioni specifiche dello strumento di compilazione sono definite come destinazioni vuote in Microsoft.CppBuild.targets:
<Target Name="ClCompile"/>
Poiché la ClCompile
destinazione è vuota, a meno che non venga sottoposta a override da un set di strumenti, non viene eseguita alcuna azione di compilazione reale. Le destinazioni del set di strumenti possono eseguire l'override della ClCompile
destinazione, ovvero possono contenere un'altra ClCompile
definizione dopo l'importazione di Microsoft.CppBuild.targets:
<Target Name="ClCompile"
Condition="'@(ClCompile)' != ''"
DependsOnTargets="SelectClCompile">
<!-- call some MSBuild tasks -->
</Target>
Nonostante il nome, creato prima che Visual Studio implementi il supporto multipiattaforma, la ClCompile
destinazione non deve chiamare CL.exe. Può anche chiamare Clang, gcc o altri compilatori usando le attività MSBuild appropriate.
La ClCompile
destinazione non deve avere dipendenze tranne la SelectClCompile
destinazione, necessaria per il corretto funzionamento del comando di compilazione del singolo file nell'IDE.
Attività di MSBuild da usare nelle destinazioni del set di strumenti
Per richiamare uno strumento di compilazione effettivo, la destinazione deve chiamare un'attività MSBuild. È disponibile un'attività Exec di base che consente di specificare una riga di comando da eseguire. Tuttavia, gli strumenti di compilazione in genere hanno molte opzioni, input e output per tenere traccia delle compilazioni incrementali, quindi è più opportuno avere attività speciali per loro. Ad esempio, l'attività CL
converte le proprietà di MSBuild in opzioni CL.exe, le scrive in un file di risposta e chiama CL.exe. Tiene inoltre traccia di tutti i file di input e output per le compilazioni incrementali successive. Per altre informazioni, vedere Compilazioni incrementali e controlli aggiornati.
Il Microsoft.Cpp.Common.Tasks.dll implementa queste attività:
BSCMake
CL
ClangCompile
(commutatori clang-gcc)LIB
LINK
MIDL
Mt
RC
XDCMake
CustomBuild
(ad esempio Exec, ma con il rilevamento di input e output)SetEnv
GetOutOfDateItems
Se si dispone di uno strumento che esegue la stessa azione di uno strumento esistente e che dispone di opzioni della riga di comando simili (come clang-cl e CL), è possibile usare la stessa attività per entrambi.
Se è necessario creare una nuova attività per uno strumento di compilazione, è possibile scegliere tra le opzioni seguenti:
Se si usa questa attività raramente o se alcuni secondi non sono importanti per la compilazione, è possibile usare le attività "inline" di MSBuild:
Attività Xaml (regola di compilazione personalizzata)
Per un esempio di dichiarazione di attività Xaml, vedi BuildCustomizations masm.xml e per il relativo utilizzo, vedi
$(VCTargetsPath)
\\$(VCTargetsPath)
BuildCustomizations\masm.targets.\
Se si desidera migliorare le prestazioni delle attività o se sono necessarie funzionalità più complesse, usare il normale processo di scrittura delle attività DI MSBuild.
Se non tutti gli input e gli output dello strumento vengono elencati nella riga di comando dello strumento, come nei
CL
casi ,MIDL
eRC
e se si desidera il rilevamento automatico dei file di input e output e la creazione di file con estensione tlog, derivare l'attività dallaMicrosoft.Build.CPPTasks.TrackedVCToolTask
classe . Attualmente, mentre è disponibile documentazione per la classe ToolTask di base, non sono disponibili esempi o documentazione per i dettagli dellaTrackedVCToolTask
classe. Se questo sarebbe di particolare interesse, aggiungere la voce a una richiesta nella community degli sviluppatori.
Compilazioni incrementali e controlli aggiornati
Le destinazioni di compilazione incrementali di MSBuild predefinite usano Inputs
attributi e Outputs
. Se vengono specificati, MSBuild chiama la destinazione solo se uno degli input ha un timestamp più recente rispetto a tutti gli output. Poiché i file di origine spesso includono o importano altri file e gli strumenti di compilazione producono output diversi a seconda delle opzioni dello strumento, è difficile specificare tutti gli input e gli output possibili nelle destinazioni MSBuild.
Per gestire questo problema, la compilazione C++ usa una tecnica diversa per supportare compilazioni incrementali. La maggior parte delle destinazioni non specifica input e output e, di conseguenza, viene sempre eseguita durante la compilazione. Le attività chiamate dalle destinazioni scrivono informazioni su tutti gli input e gli output in file tlog con estensione tlog. I file con estensione tlog vengono usati dalle compilazioni successive per verificare cosa è stato modificato e deve essere ricompilato e cosa è aggiornato. I file con estensione tlog sono anche l'unica origine per l'archiviazione predefinita di compilazione aggiornata nell'IDE.
Per determinare tutti gli input e gli output, le attività dello strumento nativo usano tracker.exe e la classe FileTracker fornita da MSBuild.
Microsoft.Build.CPPTasks.Common.dll definisce la TrackedVCToolTask
classe base astratta pubblica. La maggior parte delle attività dello strumento nativo è derivata da questa classe.
A partire da Visual Studio 2017 update 15.8, è possibile usare l'attività GetOutOfDateItems
implementata in Microsoft.Cpp.Common.Tasks.dll per produrre file con estensione tlog per destinazioni personalizzate con input e output noti.
In alternativa, è possibile crearli usando l'attività WriteLinesToFile
. Vedere la _WriteMasmTlogs
destinazione in $(VCTargetsPath)
\BuildCustomizations\masm.targets come esempio.
File con estensione tlog
Esistono tre tipi di file con estensione tlog: lettura, scrittura e riga di comando. I file con estensione tlog di lettura e scrittura vengono usati dalle compilazioni incrementali e dal controllo aggiornato nell'IDE. I file con estensione tlog della riga di comando vengono usati solo nelle compilazioni incrementali.
MSBuild fornisce queste classi helper per leggere e scrivere file con estensione tlog:
La classe FlatTrackingData può essere usata per accedere ai file con estensione tlog di lettura e scrittura e identificare gli input più recenti rispetto agli output oppure se manca un output. Viene usato nel controllo aggiornato.
I file con estensione tlog della riga di comando contengono informazioni sulle righe di comando usate nella compilazione. Vengono usati solo per le compilazioni incrementali, non per i controlli aggiornati, quindi il formato interno è determinato dall'attività MSBuild che li produce.
Leggere il formato tlog
Leggere i file con estensione tlog (*.read.*.tlog) contenenti informazioni sui file di origine e sulle relative dipendenze.
Un cursore (^) all'inizio di una riga indica una o più origini. Le origini che condividono le stesse dipendenze sono separate da una barra verticale (|).
I file di dipendenza vengono elencati dopo le origini, ognuna nella propria riga. Tutti i nomi di file sono percorsi completi.
Si supponga, ad esempio, che le origini del progetto siano disponibili in F:\test\ConsoleApplication1\ConsoleApplication1. Se il file di origine, Class1.cpp, include questi elementi,
#include "stdafx.h" //precompiled header
#include "Class1.h"
il file CL.read.1.tlog contiene quindi il file di origine seguito dalle due dipendenze seguenti:
^F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\CLASS1.CPP
F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.PCH
F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\CLASS1.H
Non è necessario scrivere nomi di file in lettere maiuscole, ma è una comodità per alcuni strumenti.
Scrivere il formato tlog
Scrivere file con estensione tlog (*.write.*.tlog) che connettono origini e output.
Un cursore (^) all'inizio di una riga indica una o più origini. Più origini sono separate da una barra verticale (|).
I file di output compilati dalle origini devono essere elencati dopo le origini, ognuna in base alla propria riga. Tutti i nomi di file devono essere percorsi completi.
Ad esempio, per un semplice progetto ConsoleApplication con un file di origine aggiuntivo Class1.cpp, il file link.write.1.tlog può contenere:
^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
Compilazione in fase di progettazione
Nell'IDE .vcxproj i progetti usano un set di destinazioni MSBuild per ottenere informazioni aggiuntive dal progetto e rigenerare i file di output. Alcune di queste destinazioni vengono usate solo nelle build in fase di progettazione, ma molte di esse vengono usate sia nelle compilazioni regolari che nelle build in fase di progettazione.
Per informazioni generali sulle compilazioni in fase di progettazione, vedere la documentazione cps per le compilazioni in fase di progettazione. Questa documentazione è applicabile solo parzialmente ai progetti Visual C++.
Le CompileDesignTime
destinazioni e Compile
indicate nella documentazione relativa alle compilazioni in fase di progettazione non vengono mai eseguite per i progetti .vcxproj. I progetti visual C++ .vcxproj usano destinazioni in fase di progettazione diverse per ottenere informazioni su IntelliSense.
Destinazioni in fase di progettazione per informazioni su IntelliSense
Le destinazioni in fase di progettazione usate nei progetti .vcxproj sono definite in $(VCTargetsPath)
\Microsoft.Cpp.DesignTime.targets.
La GetClCommandLines
destinazione raccoglie le opzioni del compilatore per IntelliSense:
<Target
Name="GetClCommandLines"
Returns="@(ClCommandLines)"
DependsOnTargets="$(DesignTimeBuildInitTargets);$(ComputeCompileInputsTargets)">
DesignTimeBuildInitTargets
: destinazioni solo in fase di progettazione, necessarie per l'inizializzazione della compilazione in fase di progettazione. Tra le altre cose, queste destinazioni disabilitano alcune delle normali funzionalità di compilazione per migliorare le prestazioni.ComputeCompileInputsTargets
: set di destinazioni che modifica le opzioni e gli elementi del compilatore. Queste destinazioni vengono eseguite sia in fase di progettazione che in compilazioni regolari.
La destinazione chiama l'attività CLCommandLine
per creare la riga di comando da usare per IntelliSense. Anche in questo caso, nonostante il nome, può gestire non solo le opzioni CL, ma anche le opzioni Clang e gcc. Il tipo di opzioni del compilatore è controllato dalla ClangMode
proprietà .
Attualmente, la riga di comando prodotta dall'attività CLCommandLine
usa sempre commutatori CL (anche in modalità Clang) perché sono più facili per il motore IntelliSense da analizzare.
Se si aggiunge una destinazione eseguita prima della compilazione, sia normale che in fase di progettazione, assicurarsi che non interrompa le compilazioni in fase di progettazione o influisca sulle prestazioni. Il modo più semplice per testare la destinazione consiste nell'aprire un prompt dei comandi per gli sviluppatori ed eseguire questo comando:
msbuild /p:SolutionDir=*solution-directory-with-trailing-backslash*;Configuration=Debug;Platform=Win32;BuildingInsideVisualStudio=true;DesignTimebuild=true /t:\_PerfIntellisenseInfo /v:d /fl /fileloggerparameters:PerformanceSummary \*.vcxproj
Questo comando genera un log di compilazione dettagliato, msbuild.log, con un riepilogo delle prestazioni per le destinazioni e le attività alla fine.
Assicurarsi di usare Condition ="'$(DesignTimeBuild)' != 'true'"
in tutte le operazioni che hanno senso solo per le compilazioni regolari e non per le compilazioni in fase di progettazione.
Destinazioni in fase di progettazione che generano origini
Questa funzionalità è disabilitata per impostazione predefinita per i progetti nativi desktop e non è attualmente supportata nei progetti memorizzati nella cache.
Se GeneratorTarget
i metadati sono definiti per un elemento di progetto, la destinazione viene eseguita automaticamente sia quando il progetto viene caricato che quando viene modificato il file di origine.
Ad esempio, per generare automaticamente file .cpp o h da file con estensione xaml, i $(VSInstallDir)
\file MSBuild\Microsoft\WindowsXaml\v16.0\*\Microsoft.Windows.UI.Xaml.CPP.Targets definiscono queste entità:
<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>
Per usare Task.HostObject
per ottenere il contenuto non salvato dei file di origine, le destinazioni e le attività devono essere registrate come MsbuildHostObjects per i progetti specificati in un pkgdef:
\[$RootKey$\\Projects\\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\\MSBuildHostObjects\]
\[$RootKey$\\Projects\\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\\MSBuildHostObjects\\DesignTimeMarkupCompilationCT;CompileXaml\]
@="{83046B3F-8984-444B-A5D2-8029DEE2DB70}"
Estendibilità del progetto Visual C++ nell'IDE di Visual Studio
Il sistema di progetto Visual C++ si basa sul sistema di progetto VS e usa i relativi punti di estendibilità. Tuttavia, l'implementazione della gerarchia del progetto è specifica di Visual C++ e non basata su CPS, quindi l'estendibilità della gerarchia è limitata agli elementi del progetto.
Pagina delle proprietà del progetto
Per informazioni generali sulla progettazione, vedere Framework multitargeting per progetti VC++.
In termini semplici, le pagine delle proprietà visualizzate nella finestra di dialogo Proprietà progetto per un progetto C++ sono definite dai file delle regole . Un file di regole specifica un set di proprietà da visualizzare in una pagina delle proprietà e come e dove devono essere salvati nel file di progetto. I file delle regole sono .xml file che usano il formato Xaml. I tipi usati per serializzarli sono descritti in Microsoft.Build.Framework.XamlTypes. Per altre informazioni sull'uso dei file di regole nei progetti, vedere File di regole XML della pagina delle proprietà.
I file delle regole devono essere aggiunti al gruppo di PropertyPageSchema
elementi:
<ItemGroup>
<PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\general.xml;"/>
<PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\general_file.xml">
<Context>File</Context>
</PropertyPageSchema>
</ItemGroup>
Context
la visibilità delle regole dei metadati, controllata anche dal tipo di regola, e può avere uno di questi valori:
Project
| File
| PropertySheet
CPS supporta altri valori per il tipo di contesto, ma non vengono usati nei progetti Visual C++.
Se la regola deve essere visibile in più contesti, usare punti e virgola (;) per separare i valori di contesto, come illustrato di seguito:
<PropertyPageSchema Include="$(MyFolder)\MyRule.xml">
<Context>Project;PropertySheet</Context>
</PropertyPageSchema>
Formato delle regole e tipi principali
Il formato della regola è semplice, quindi questa sezione descrive solo gli attributi che influiscono sull'aspetto della regola nell'interfaccia utente.
<Rule
Name="ConfigurationGeneral"
DisplayName="General"
PageTemplate="generic"
Description="General"
xmlns="http://schemas.microsoft.com/build/2009/properties">
L'attributo PageTemplate
definisce la modalità di visualizzazione della regola nella finestra di dialogo Pagine delle proprietà. L'attributo può avere uno dei valori seguenti:
Attributo | Descrizione |
---|---|
generic |
Tutte le proprietà vengono visualizzate in una pagina in Intestazioni categoria La regola può essere visibile per Project i contesti e PropertySheet , ma non File per .Esempio: $(VCTargetsPath) \1033\general.xml |
tool |
Le categorie vengono visualizzate come pagine secondarie. La regola può essere visibile in tutti i contesti: Project e PropertySheet File .La regola è visibile in Proprietà progetto solo se il progetto contiene elementi con l'oggetto ItemType definito in Rule.DataSource , a meno che il nome della regola non sia incluso nel ProjectTools gruppo di elementi.Esempio: $(VCTargetsPath) \1033\clang.xml |
debugger |
La pagina viene visualizzata come parte della pagina Debug. Le categorie vengono attualmente ignorate. Il nome della regola deve corrispondere all'attributo dell'oggetto MEF dell'utilità di avvio di ExportDebugger debug.Esempio: $(VCTargetsPath) \1033\debugger_local_windows.xml |
custom | Modello personalizzato. Il nome del modello deve corrispondere all'attributo ExportPropertyPageUIFactoryProvider dell'oggetto PropertyPageUIFactoryProvider MEF. Vedere Microsoft.VisualStudio.ProjectSystem.Designers.Properties.IPropertyPageUIFactoryProvider.Esempio: $(VCTargetsPath) \1033\userMacros.xml |
Se la regola usa uno dei modelli basati su Griglia di proprietà, può usare questi punti di estendibilità per le relative proprietà:
Estendere una regola
Se si vuole usare una regola esistente, ma è necessario aggiungere o rimuovere (ovvero nascondere) solo alcune proprietà, è possibile creare una regola di estensione.
Eseguire l'override di una regola
È possibile che il set di strumenti usi la maggior parte delle regole predefinite del progetto, ma per sostituire solo uno o pochi di essi. Si supponga, ad esempio, di voler modificare solo la regola C/C++ in modo da visualizzare opzioni del compilatore diverse. È possibile specificare una nuova regola con lo stesso nome e nome visualizzato della regola esistente e includerla nel PropertyPageSchema
gruppo di elementi dopo l'importazione di destinazioni cpp predefinite. Nel progetto viene usata una sola regola con un nome specificato e l'ultima inclusa nel PropertyPageSchema
gruppo di elementi prevale.
Articoli progetto
Il file ProjectItemsSchema.xml definisce i ContentType
valori e ItemType
per Items trattati come Elementi di progetto e definisce FileExtension
gli elementi per determinare il gruppo item a cui viene aggiunto un nuovo file.
Il file ProjectItemsSchema predefinito è disponibile in $(VCTargetsPath)
\1033\ProjectItemsSchema.xml. Per estenderlo, è necessario creare un file di schema con un nuovo nome, ad esempio 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>
Quindi, nel file di destinazioni aggiungere:
<ItemGroup>
<PropertyPageSchema Include="MyProjectItemsSchema.xml"/>
</ItemGroup>
Esempio: $(VCTargetsPath)
\BuildCustomizations\masm.xml
Debugger
Il servizio Debug in Visual Studio supporta l'estendibilità per il motore di debug. Per altre informazioni, vedere questi esempi:
Per specificare i motori di debug e altre proprietà per la sessione di debug, è necessario implementare un componente MEF di avvio del debug e aggiungere una debugger
regola. Per un esempio, vedere il $(VCTargetsPath)
file \1033\debugger_local_windows.xml.
Distribuzione
.vcxproj progetti usano l'estendibilità del sistema di progetto di Visual Studio per i provider di distribuzione.
Verifica aggiornata
Per impostazione predefinita, il controllo di aggiornamento della compilazione richiede la lettura di file con estensione tlog e la scrittura di file tlog nella cartella durante la $(TlogLocation)
compilazione per tutti gli input e gli output di compilazione.
Per usare un controllo personalizzato aggiornato:
Disabilitare il controllo predefinito aggiornato aggiungendo la
NoVCDefaultBuildUpToDateCheckProvider
funzionalità nel file Toolset.targets :<ItemGroup> <ProjectCapability Include="NoVCDefaultBuildUpToDateCheckProvider" /> </ItemGroup>
Implementare i propri IBuildUpToDateCheckProvider.
Aggiornamento del progetto
Aggiornamento predefinito .vcxproj progetto
L'aggiornamento del progetto predefinito .vcxproj modifica la versione del PlatformToolset
set di strumenti , ApplicationTypeRevision
, MSBuild e .NET Framework. Le ultime due vengono sempre modificate nelle impostazioni predefinite della versione di Visual Studio, ma PlatformToolset
possono ApplicationTypeRevision
essere controllate da proprietà MSBuild speciali.
L'aggiornamento usa questi criteri per decidere se un progetto può essere aggiornato o meno:
Per i progetti che definiscono
ApplicationType
eApplicationTypeRevision
, è presente una cartella con un numero di revisione superiore a quello corrente.La proprietà
_UpgradePlatformToolsetFor_<safe_toolset_name>
viene definita per il set di strumenti corrente e il relativo valore non è uguale al set di strumenti corrente.In questi nomi di proprietà safe_toolset_name <>rappresenta il nome del set di strumenti con tutti i caratteri non alfanumerici sostituiti da un carattere di sottolineatura (_).
Quando un progetto può essere aggiornato, partecipa a Retargeting della soluzione. Per altre informazioni, vedere IVsTrackProjectRetargeting2.
Se si desidera adornare i nomi di progetto in Esplora soluzioni quando i progetti usano un set di strumenti specifico, definire una _PlatformToolsetShortNameFor_<safe_toolset_name>
proprietà.
Per esempi di definizioni di _UpgradePlatformToolsetFor_<safe_toolset_name>
proprietà e _PlatformToolsetShortNameFor_<safe_toolset_name>
, vedere il file Microsoft.Cpp.Default.props . Per esempi di utilizzo, vedere il $(VCTargetPath)
\file Microsoft.Cpp.Platform.targets .
Aggiornamento del progetto personalizzato
Per usare un oggetto upgrader di progetto personalizzato, implementare un componente MEF, come illustrato di seguito:
/// </summary>
[Export("MyProjectUpgrader", typeof(IProjectRetargetHandler))]
[Export(typeof(IProjectRetargetHandler))]
[ExportMetadata("Name", "MyProjectUpgrader")]
[OrderPrecedence(20)]
[PartMetadata(ProjectCapabilities.Requires, ProjectCapabilities.VisualC)]
internal class MyProjectUpgrader: IProjectRetargetHandler
{
// ...
}
Il codice può importare e chiamare l'oggetto upgrader predefinito .vcxproj:
// ...
[Import("VCDefaultProjectUpgrader")]
// ...
IProjectRetargetHandler Lazy<IProjectRetargetHandler>
VCDefaultProjectUpgrader { get; set; }
// ...
IProjectRetargetHandler
è definito in Microsoft.VisualStudio.ProjectSystem.VS.dll ed è simile a IVsRetargetProjectAsync
.
Definire la VCProjectUpgraderObjectName
proprietà per indicare al sistema di progetto di usare l'oggetto upgrader personalizzato:
<PropertyGroup>
<VCProjectUpgraderObjectName>MyProjectUpgrader</VCProjectUpgraderObjectName>
</PropertyGroup>
Disabilitare l'aggiornamento del progetto
Per disabilitare gli aggiornamenti del progetto, usare un NoUpgrade
valore:
<PropertyGroup>
<VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>
</PropertyGroup>
Cache ed estendibilità del progetto
Per migliorare le prestazioni quando si lavora con soluzioni C++ di grandi dimensioni in Visual Studio 2017, è stata introdotta la cache del progetto. Viene implementato come database SQLite popolato con dati di progetto e quindi usato per caricare i progetti senza caricare progetti MSBuild o CPS in memoria.
Poiché non sono presenti oggetti CPS per i progetti .vcxproj caricati dalla cache, i componenti MEF dell'estensione che importano UnconfiguredProject
o ConfiguredProject
non possono essere creati. Per supportare l'estendibilità, la cache del progetto non viene usata quando Visual Studio rileva se un progetto usa (o è probabile che usi) estensioni MEF.
Questi tipi di progetto sono sempre completamente caricati e dispongono di oggetti CPS in memoria, quindi tutte le estensioni MEF vengono create per loro:
Progetti di avvio
I progetti che dispongono di un aggiornamento del progetto personalizzato, ovvero definiscono una
VCProjectUpgraderObjectName
proprietàI progetti che non hanno come destinazione Windows desktop, ovvero definiscono una
ApplicationType
proprietàProgetti di elementi condivisi (con estensione vcxitems) e tutti i progetti che vi fanno riferimento tramite importazione di progetti vcxitems.
Se nessuna di queste condizioni viene rilevata, viene creata una cache del progetto. La cache include tutti i dati del progetto MSBuild necessari per rispondere get
alle query sulle VCProjectEngine
interfacce. Ciò significa che tutte le modifiche a livello di file msBuild e di destinazione eseguite da un'estensione dovrebbero funzionare solo nei progetti caricati dalla cache.
Spedizione dell'estensione
Per informazioni su come creare file VSIX, vedere Shipping Visual Studio Extensions .For information on how to create VSIX files, see Shipping Visual Studio Extensions. Per informazioni su come aggiungere file a percorsi di installazione speciali, ad esempio per aggiungere file in $(VCTargetsPath)
, vedere Installazione all'esterno della cartella delle estensioni.
Risorse aggiuntive
Microsoft Build System (MSBuild) fornisce il motore di compilazione e il formato estensibile basato su XML per i file di progetto. È necessario avere familiarità con i concetti di base di MSBuild e con il funzionamento di MSBuild per Visual C++ per estendere il sistema di progetto Visual C++.
Managed Extensibility Framework (MEF) fornisce le API di estensione usate da CPS e dal sistema di progetto Visual C++. Per una panoramica del modo in cui MEF viene usato da CPS, vedere CPS e MEF nella panoramica di VSProjectSystem di MEF.
È possibile personalizzare il sistema di compilazione esistente per aggiungere passaggi di compilazione o nuovi tipi di file. Per altre informazioni, vedere Panoramica di MSBuild (Visual C++) e Uso delle proprietà del progetto.