2010-10-13 12 views
5

Ho letto sull'uso di "Custom.Before.Microsoft.Common.targets" e "Custom.After.Microsoft.Common.targets" "per eseguire un target personalizzato prima/dopo la creazione di ogni progetto e vorrei utilizzare questa tecnica per modificare le informazioni sulla versione mentre creo sul nostro server di build TeamCity.MSBuild: Custom.After.Microsoft.Common.targets per progetti C++ nativi in ​​VS2010

Il problema è che, sebbene funzioni per progetti C#, non sembra funzionare per progetti C++ nativi.

Dopo alcuni scavi nel file Microsoft.Cpp.targets ho scoperto che per i progetti nativi C++ questo sembra essere implementato attraverso l'impostazione $ (ForceImportBeforeCppTargets) e $ (ForceImportAfterCppTargets).

Non riesco a trovare un singolo pezzo di informazioni sul web su questa tecnica per le applicazioni native C++, quindi mi chiedo se sto cercando nella giusta direzione o no.

Qualsiasi aiuto è apprezzato.

+0

Perché non stai utilizzando le impostazioni Eventi evento + pre-build e post-build? –

+0

Non stiamo usando gli eventi di pre/post build perché sono sempre eseguiti, vogliamo qualcosa che viene eseguito solo quando si costruisce sul build server e si ottengono anche le informazioni sulla versione (e altre informazioni) dal server di build. Inoltre non vogliamo dipendere dal fatto che uno sviluppatore si dimentichi di inserire qualcosa in queste impostazioni degli eventi, deve essere automatico e 'Custom.Before.Microsoft.Common.targets' lo fornisce ma apparentemente non per codice nativo. – Halt

risposta

10

Per i progetti VC++ è un po 'diverso. Si definisce un file da importare all'inizio o alla fine del progetto. Per utilizzare questo approccio è necessario definire i valori per le proprietà ForceImportBeforeCppTargets o ForceImportAfterCppTargets. Ad esempio, se si desidera includere un file all'inizio del progetto, è possibile passare il valore nella riga di comando. Ad esempio ho appena creato un progetto VC++ fittizio denominato CppTets01. Quindi ho creato i due file di esempio qui sotto.

Before.proj

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 


    <Target Name="CustomTargetInBefore" AfterTargets="Build"> 
    <Message Text="From CustomTargetInBefore" Importance="high"/> 
    </Target> 

</Project> 

After.proj

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <Target Name="CustomTargetInAfter" AfterTargets="Build"> 
    <Message Text="From CustomTargetInAfter" Importance="high"/> 
    </Target> 

</Project> 

Poi ho eseguito il seguente comando:

msbuild CppTest01.vcxproj 
    /p:ForceImportBeforeCppTargets="C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\Before.proj"; 
    ForceImportAfterCppTargets="C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\After.proj" 

Il risultato è stato C: \ Temp_NET \ usa e getta \ CppTest01 \ CppTest01> msbuild CppTest01.vcxproj/p: ForceImportBeforeCppTargets = "C: \ Temp_NET \ usa e getta \ CppTest01 \ C ppTest01 \ Before.proj"; ForceImportAfterCppTargets = "C: \ Temp_NET \ usa e getta \ CppTest01 \ CppTest01 \ After.proj"

Microsoft (R) Build Engine Version 4.0.30319.1 
[Microsoft .NET Framework, Version 4.0.30319.1] 
Copyright (C) Microsoft Corporation 2007. All rights reserved. 

Build started 10/18/2010 8:32:55 AM. 
Project "C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\CppTest01.vcxproj" on node 1 (default targets). 
InitializeBuildStatus: 
    Creating "Debug\CppTest01.unsuccessfulbuild" because "AlwaysCreate" was specified. 
ClCompile: 
    All outputs are up-to-date. 
    All outputs are up-to-date. 
ManifestResourceCompile: 
    All outputs are up-to-date. 
Link: 
    All outputs are up-to-date. 
Manifest: 
    All outputs are up-to-date. 
FinalizeBuildStatus: 
    Deleting file "Debug\CppTest01.unsuccessfulbuild". 
    Touching "Debug\CppTest01.lastbuildstate". 
CustomTargetInBefore: 
    From CustomTargetInBefore 
CustomTargetInAfter: 
    From CustomTargetInAfter 
Done Building Project "C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\CppTest01.vcxproj" (default targets). 


Build succeeded. 
    0 Warning(s) 
    0 Error(s) 

Time Elapsed 00:00:00.21 

Come si può vedere dalla uscita gli obiettivi sono stati iniettati con successo nel processo di generazione. Se vuoi ricollegarlo a Custom.Before.Microsoft.Common.targets e Custom.Before.Microsoft.Common.targets allora dovresti sapere che la tecnica utilizzata è leggermente diversa. In particolare se si creano quei file vengono automaticamente importati in ogni progetto C#/VB.NET. In questo caso devi impostare questa proprietà. Avete davvero due opzioni qui:

  1. È possibile impostare questa proprietà come una variabile d'ambiente
  2. È possibile utilizzare un'altra tecnica, ImportBefore & ImportAfter che è specifico per VC++

Per # 1 lasciami spiegare un po '.In MSBuild quando si accede a una proprietà con la sintassi $ (PropName), se non esiste una proprietà con il nome PropName, MSBuild cercherà nelle variabili di ambiente per vedere se tale valore esiste, se lo fa allora viene restituito quel valore . Pertanto, se si dispone di un build server in cui si desidera includere un file per ogni build VC++, è sufficiente creare tali proprietà come variabili di ambiente. Ora per l'altra tecnica.

ImportazionePrima/ImportAfter In VC++ è stato introdotto un nuovo concetto. In Microsoft.Cpp.Win32.targets è possibile visualizzare la dichiarazione nella parte superiore del file .targets.

<Import Project="$(VCTargetsPath)\Platforms\Win32\ImportBefore\*.targets" 
Condition="Exists('$(VCTargetsPath)\Platforms\Win32\ImportBefore')" /> 

V'è poi una verso il fondo

<Import Project="$(VCTargetsPath)\Platforms\Win32\ImportAfter\*.targets" 
Condition="Exists('$(VCTargetsPath)\Platforms\Win32\ImportAfter')" /> 

presente una dichiarazione di importazione simile per le altre piattaforme di destinazione pure. Dai un'occhiata ai file a %ProgramFiles32%\MSBuild\Microsoft.Cpp\v4.0\Platforms\ per i nomi specifici.

Con questa tecnica se si desidera importare un file, è sufficiente creare un file che termina con .targets e inserirlo nella cartella appropriata. Il vantaggio di questo è che verrà importato in ogni build VC++ per quella piattaforma e che è possibile creare molti file diversi. Lo svantaggio è che devi metterli in quelle cartelle specifiche. Questa è la principale differenza tra entrambe le tecniche. Con questa prima tecnica è possibile specificare la posizione del file tramite proprietà e non è automaticamente inclusa per ogni build, ma per il secondo approccio è ma non è possibile modificare la posizione

+0

Mi dispiace, stavo dando le informazioni sbagliate. Ho guardato questo un po 'più a fondo e ho corretto il problema. Ho aggiornato la mia risposta per riflettere le mie scoperte. –

+0

Grazie, ottima risposta, hai confermato quello che ho iniziato a sospettare. Ora so che sono sulla strada giusta. – Halt

+0

OK, mi dispiace per il deragliamento iniziale. –

3

È inoltre possibile aggiungere il contenuto del progetto in uno dei file *.props da directory %LOCALAPPDATA%\Microsoft\MSBuild\v4.0\

Fa lo stesso effetto.

Problemi correlati