59

Ho sempre utilizzato Visual Studio integrato nel supporto della GUI per configurare i miei progetti, spesso usando i fogli delle proprietà in modo che diversi progetti utilizzino un set comune.Utilizzo efficace delle proprietà del progetto Visual Studio per più progetti e configurazioni

Uno dei miei problemi principali è la gestione di più progetti, configurazioni e piattaforme. Se fai semplicemente tutto con la GUI principale (fai clic con il tasto destro del mouse sul progetto -> Proprietà) diventa rapidamente un disastro, difficile da mantenere e soggetto a bug (come non riuscire a definire correttamente una macro, o usare la libreria runtime sbagliata, ecc.). Affrontare il fatto che diverse persone mettono lì le librerie di dipendenza in luoghi diversi (ad esempio, tutte le mie vivono in "C: \ Libs \ [C, C++] \ [lib-name] \") e quindi gestiscono spesso le diverse versioni di quelle librerie anche in modo diverso (rilascio, debug, x86, x64, ecc.) è anche un grosso problema poiché complica enormemente il tempo di installarlo su un nuovo sistema, e quindi ci sono problemi con il controllo della versione e tenere separati i percorsi di ognuno.

Le schede delle proprietà rendono questo un po 'meglio, ma non posso avere un foglio con impostazioni separate per diverse configurazioni e piattaforme (le caselle a discesa di un grigio), con conseguente me avendo molti fogli che se ereditato nell'ordine corretto fai quello che voglio ("x86", "x64", "debug", "release", "common", "directories" (si occupa del problema delle dipendenze precedentemente citato definendo macro utente come BoostX86LibDir), ecc. d nell'ordine sbagliato (ad esempio "comune" prima di "x64" e "debug") portano a problemi come provare a collegare una versione errata della libreria, o nominare erroneamente l'output ...

Quello che voglio è un modo di trattare tutte queste dipendenze sparse e impostare un insieme di "regole" che sono utilizzate da tutti i miei progetti nella soluzione, come nominare una libreria di output come "mylib- [vc90, vc100] - [x86, x64] [- d] .lib ", senza dover fare tutto questo per ogni singolo progetto, configurazione e combinazione di piattaforme, e quindi tenerli tutti correttamente sincronizzati.

Sono consapevole di passare a sistemi completamente diversi come CMake che creano i file necessari, tuttavia questo complica le cose altrove rendendolo così anche semplici attività come l'aggiunta di un nuovo file al progetto, quindi richiede ulteriori cambiamenti altrove, che è Non sono affatto soddisfatto di entrambi, a meno che non ci sia un po 'di integrazione con VS2010 che possa tenere traccia di questo tipo di cambiamenti.

+1

Mi sento male: abbiamo oltre 600 vcproj nel nostro prodotto al lavoro. :( –

risposta

67

Ho appena scoperto qualcosa che non pensavo fosse possibile (non è esposto dalla GUI) che aiuta a rendere la finestra delle proprietà molto più utile. L'attributo "Condizioni" di molti dei tag nei file di proprietà del progetto e può essere utilizzato anche nei file .props!

Ho appena messo insieme quanto segue come test e ha funzionato benissimo e ha svolto il compito di 5 (comuni, x64, x86, debug, release) fogli di proprietà separati!

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup Label="UserMacros"> 
    <!--debug suffix--> 
    <DebugSuffix Condition="'$(Configuration)'=='Debug'">-d</DebugSuffix> 
    <DebugSuffix Condition="'$(Configuration)'!='Debug'"></DebugSuffix> 
    <!--platform--> 
    <ShortPlatform Condition="'$(Platform)' == 'Win32'">x86</ShortPlatform> 
    <ShortPlatform Condition="'$(Platform)' == 'x64'">x64</ShortPlatform> 
    <!--toolset--> 
    <Toolset Condition="'$(PlatformToolset)' == 'v90'">vc90</Toolset> 
    <Toolset Condition="'$(PlatformToolset)' == 'v100'">vc100</Toolset> 
    </PropertyGroup> 
    <!--target--> 
    <PropertyGroup> 
    <TargetName>$(ProjectName)-$(Toolset)-$(ShortPlatform)$(DebugSuffix)</TargetName> 
    </PropertyGroup> 
</Project> 

L'unico problema è la proprietà GUI sopraelevazione gestirlo, un progetto che utilizza la finestra delle proprietà di cui sopra riporta solo difetto ereditato valori come "$ (Nome progetto)" per il target.

+0

Bella tecnica! – Mordachai

+0

+1 questo è molto simile a quello che uso – AJG85

+0

Sì, i fogli delle proprietà sono molto più potenti in VS2k10. Peccato che nulla di tutto ciò sia esposto attraverso l'IDE. Ho fatto qualcosa di simile e semplifica davvero le cose. – jalf

4

Per quanto riguarda la biblioteca uscita va, è possibile selezionare tutti i vostri progetti, poi far apparire le pagine delle proprietà, selezionare Tutte le configurazioni, tutte le piattaforme e quindi impostare il nome di destinazione a:

$(ProjectName)-$(PlatformToolset)-$(PlatformShortName)-$(Configuration)

che darebbe un output come mylib-v100-x86-Debug.lib

facciamo qualcosa di simile a questo per ulteriori directory di libreria e, utilizzando $(PlatformName) e #(Configuration) di individuare i percorsi della libreria di destra, anche se vuol dire un po 'di guai con la configurazione iniziale di li braries. Ad esempio, abbiamo potenziare l'installazione delle librerie su boost/lib.Win32 o boost/lib.x64.


Per quanto riguarda le librerie e le persone che le installano in luoghi diversi, ci sono un paio di opzioni. Se si dispone di un sistema di controllo del codice sorgente molto solido, è possibile semplicemente mettere tutto nel controllo del codice sorgente, vivendo in una cartella libs accanto alla propria fonte. Probabilmente non funzionerà se usi più di qualche libreria, o se sono particolarmente grandi.

L'altra opzione che viene in mente è impostare una variabile di ambiente su ogni macchina utente che punta alla radice della loro cartella librerie, ad esempio LIB_ROOT=c:\libraries, e quindi è possibile accedervi in ​​Visual Studio come $(LIB_ROOT).

+0

Ho già fatto alcuni bit in questo modo, ma poi ci sono librerie che usano qualcos'altro nei loro nomi (ad esempio opt invece di release, -d invece di -Debug) ecc, che richiede ancora un sacco di regole speciali (i miei debug.props e release.props impostano macro utente per aiutare in questo modo con common.props in realtà impostando i percorsi include/lib). Non l'avevo considerato con boost, buona idea (essere ancora più bello se includesse l'auto-linking) _non_ usando gli stessi nomi per le build x86 e x64 ma le persone boost.build non sembrano pensare che sia un problema) –

+0

Immagino che il tuo PlatformShortName provenga da un x86.props e x64.props che devono essere ereditati correttamente o qualcosa o è solo non documentato? –

+0

@Fire Lancer: ad essere onesti non sono sicuro di dove PlatformShortName provenga. Penso che debba essere un built-in, perché non abbiamo nulla di speciale nelle nostre schede delle proprietà – ngoozeff

7

Ho avuto lo stesso dolore per il prodotto della mia azienda (oltre 200 progetti) prima. Il modo in cui ho risolto è quello di costruire una bella gerarchia dei fogli di proprietà.

I progetti ereditano la finestra delle proprietà in base al tipo di output, ad esempio x64.Debug.Dynamic.Library.vsprops. Questo vsprops file di eredita semplicemente altre finestre delle proprietà utilizzando i InheritedPropertySheets attribuiscono

<VisualStudioPropertySheet 
    ProjectType="Visual C++" 
    Version="8.00" 
    Name="x64.Debug.Dynamic.Binary" 
    InheritedPropertySheets=".\Common.vsprops;.\x64.vsprops;.\Debug.vsprops;.\Runtime.Debug.Dynamic.vsprops;.\Output.x64.Library.vsprops" 
    > 

È inoltre possibile utilizzare le variabili (cioè UserMacro, il cui valore può essere variabili assolute o anche ambientali) in fogli di proprietà per personalizzare un sacco di cose, sulla base di bisogno. Ad esempio, la definizione di una variabile BIN in Debug.vsprops

<UserMacro name="BIN" Value="Debug" /> 

poi, quando si imposta il nome di output di una serie di vsprops, diciamo, Output.x64.Library.vsprops

<VisualStudioPropertySheet 
    ProjectType="Visual C++" 
    Version="8.00" 
    OutputDirectory="$(BIN)" 
> 

I $ (BIN) sarà espansa su ciò che è stato impostato (in questo caso, Debug). Usa questa tecnica per costruire facilmente una bella gerarchia di schede delle proprietà per soddisfare la tua richiesta.

Ora c'è ancora una cosa che potresti voler fare: creare i tuoi modelli di progetto che utilizzano il set di proprietà. La parte più difficile consiste nell'imporre il corretto utilizzo dei modelli e dei fogli di proprietà. La mia esperienza personale è che, anche se tutto è impostato, qualcuno dimenticherà ancora di usare il modello per creare nuovi progetti ...

0

Sembra che valga la pena controllare uno strumento di costruzione - a casa mia usiamo un costume strumento reso che controlla file e progetti per modifiche e calcola le dipendenze e l'ordine di compilazione. Aggiungere un nuovo file non è un grosso problema - la compilazione è fatta con msbuild.

Se dovessi compilare più di un mucchio di progetti Vorrei usare qualcosa di simile a Nant: http://nant.sourceforge.net/

20

ho fatto alcuni miglioramenti, può essere utile per qualcuno

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup Label="UserMacros"> 
    <!--IsDebug: search for 'Debug' in Configuration--> 
    <IsDebug>$([System.Convert]::ToString($([System.Text.RegularExpressions.Regex]::IsMatch($(Configuration), '[Dd]ebug'))))</IsDebug> 

    <!--ShortPlatform--> 
    <ShortPlatform Condition="'$(Platform)' == 'Win32'">x86</ShortPlatform> 
    <ShortPlatform Condition="'$(Platform)' == 'x64'">x64</ShortPlatform> 

    <!--build parameters--> 
    <BUILD_DIR>$(registry:HKEY_CURRENT_USER\Software\MyCompany\@BUILD_DIR)</BUILD_DIR> 
    </PropertyGroup> 

    <Choose> 
    <When Condition="$([System.Convert]::ToBoolean($(IsDebug)))"> 
     <!-- debug macroses --> 
     <PropertyGroup Label="UserMacros"> 
     <MyOutDirBase>Debug</MyOutDirBase> 
     <DebugSuffix>-d</DebugSuffix> 
     </PropertyGroup> 
    </When> 
    <Otherwise> 
     <!-- other/release macroses --> 
     <PropertyGroup Label="UserMacros"> 
     <MyOutDirBase>Release</MyOutDirBase> 
     <DebugSuffix></DebugSuffix> 
     </PropertyGroup> 
    </Otherwise> 
    </Choose> 

    <Choose> 
    <When Condition="Exists($(BUILD_DIR))"> 
     <PropertyGroup Label="UserMacros"> 
     <MyOutDir>$(BUILD_DIR)\Bin\$(MyOutDirBase)_$(ShortPlatform)\</MyOutDir> 
     <MyIntDir>$(BUILD_DIR)\Build\$(Configuration)_$(ShortPlatform)_$(PlatformToolset)\$(ProjectGuid)\</MyIntDir> 
     </PropertyGroup> 
    </When> 
    <Otherwise> 
     <PropertyGroup Label="UserMacros"> 
     <MyOutDir>$(SolutionDir)\Bin\$(MyOutDirBase)_$(ShortPlatform)\</MyOutDir> 
     <MyIntDir>$(SolutionDir)\Build\$(Configuration)_$(ShortPlatform)_$(PlatformToolset)\$(ProjectGuid)\</MyIntDir> 
     </PropertyGroup> 
    </Otherwise> 
    </Choose> 

    <PropertyGroup> 
    <OutDir>$(MyOutDir)</OutDir> 
    <IntDir>$(MyIntDir)</IntDir> 
<!-- some common for projects 
    <CharacterSet>Unicode</CharacterSet> 
    <LinkIncremental>false</LinkIncremental> 
--> 
    </PropertyGroup> 
</Project> 

buon divertimento!

+2

Sei ... pazzo. Ma in senso positivo :) –

+0

Quando verrà valutato? Durante il caricamento del progetto? Vorrei aggiungere regole di copia post-compilazione personalizzate a una finestra delle proprietà per copiare solo DLL che sono state effettivamente collegate al progetto. Pensi che questo sarebbe possibile? – Bim

+0

Bim, penso che sia stato valutato prima della compilazione, in quanto legge le variabili dal registro (vedi $ (registro: chiave)). – lunicon

4

È possibile creare una finestra delle proprietà separata per ciascuna configurazione.Per fare questo:

  1. Creare una finestra delle proprietà specifiche di configurazione
  2. Aprire Gestione Proprietà
  3. clic destro la configurazione (non il progetto) che si desidera modificare
  4. Fare clic su "Aggiungi Foglio di proprietà esistente "e aggiungi il tuo foglio

Questo ti solleva dall'inserire le condizioni in un singolo foglio per più configurazioni. Se si dispone di alcuni attributi comuni che si desidera condividere tra le configurazioni, quindi creare una gerarchia. Il foglio superiore può essere utilizzato in tutte le configurazioni e il foglio annidato conterrà solo l'attributo specifico della configurazione

+0

PERFETTO! Grazie. Quindi è anche possibile creare nuove pagine in ciascun nodo di configurazione. È facile cadere nella trappola di modificare la pagina condivisa che influisce su tutte le configurazioni anche se è accessibile da ogni nodo di configurazione. – Justin