2016-05-21 22 views
2

Ich habe ein benutzerdefiniertes msbuild-Ziel und einen Task, der einen Wert berechnet. Der Task gibt den Wert als Eigenschaft aus. Diese Eigenschaft möchte ich als zusätzliche Option zum Compiler-Aufruf verwenden.Zusätzliche Compiler-Optionen, die in einem benutzerdefinierten Ziel berechnet wurden

Die Eigenschaft ist jedoch leer, wenn sie als zusätzliche Option verwendet wird.

Mein * .targets Datei sieht wie folgt aus:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <UsingTask TaskName="GetBranchName_TASK" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" > 
    <ParameterGroup> 
     <sPath ParameterType="System.String" Required="true" /> 
     <sBranchName ParameterType="System.String" Output="true" /> 
    </ParameterGroup> 
    <Task> 
     <Code Type="Fragment" Language="cs"> 
     <![CDATA[ 
      ... some Code ... 
     ]]> 
     </Code> 
    </Task> 
    </UsingTask> 

    <Target Name="GetBranchName_TARGET"> 
    <GetBranchName_TASK sPath="$(MSBuildThisFileDirectory)"> 
     <Output PropertyName="BranchName" TaskParameter="sBranchName" /> 
    </GetBranchName_TASK> 
    <Message Importance="High" Text="BranchName = $(BranchName)" /> 
    </Target> 

    <PropertyGroup> 
    <BuildDependsOn> 
     GetBranchName_TARGET; 
     $(BuildDependsOn); 
    </BuildDependsOn> 
    </PropertyGroup> 
</Project> 

Mein * .props Datei ist wie folgt:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup Label="Configuration"> 
    ... some Properties here ... 
    </PropertyGroup> 
    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 
    <Import Project="IRSGetBranchName.targets" /> 
    <ItemDefinitionGroup> 
    <ClCompile> 
     <AdditionalOptions>/DBRANCHNAME=$(BranchName) /DMORE=BAR</AdditionalOptions> 
    <ClCompile> 
    <ItemDefinitionGroup> 
</Project> 

dann importiert Dieser .props Datei in mehrere .vcxproj

Der Wert, der als Nachricht in meinem GetBranchName_TARGET gedruckt wird, ist wie erwartet korrekt (den richtigen TFS-Branch Name zeigend). Aber wenn bei Detaillierte Build-Ausgabe suchen, scheint der Wert leer:

1>ClCompile 
1> ..\FOO.cpp 
1>  AdditionalOptions = /DBRANCHNAME= /DMORE=BAR 

ich stundenlang versucht, aber keine Lösung gefunden, und ich wirklich hoffe, jemand helfen, was ist falsch hier ...

a) Ist die Eigenschaft BranchName global nicht verfügbar? Ich habe versucht, die Eigenschaft von anderen benutzerdefinierten Zielen zu drucken und es hat gut funktioniert!

b) Oder ist die ClCompile.AdditionalOptions ausgewertet/Build vor meinem Ziel wird ausgeführt? Wie kann ich in diesem Fall neu bewerten?

c) ...

Ich bin für jede Eingabe sehr dankbar.

+0

a) Ja, es ist b) Ja, weil es außerhalb eines Ziels global definiert ist, wird es ausgewertet, bevor Ihr Ziel ausgeführt wird, und das ist Ihr Problem. Ich bin nicht 100% sicher, aber setzen Sie die itemDefinitionGroup mit ClCompile * innerhalb * der GetBranchName_TARGET sollte funktionieren – stijn

+0

@stijn: Vielen Dank. Ihr Kommentar hat mich auf die perfekte Lösung ausgerichtet. Genau wie die Antwort von stukselbax. Danke! – mbusch

Antwort

0

Sie sollten mit dem msbuild Evaluierungsprozess vertraut sein, wie here beschrieben:

Wenn die MSBuild-Modul beginnt eine Build-Datei zu verarbeiten, ist es in einem Top-down-Verfahren in einer Multi-Pass-Weise ausgewertet wird . Diese Durchläufe werden der Reihe nach in der folgenden Reihenfolge beschrieben:

  1. Alle Umgebungseigenschaften, globalen Eigenschaften und Toolset-Eigenschaften laden. In Microsoft Visual Studio 2010 beispielsweise definiert C++ mehrere Eigenschaften im MSBuild 4.0-Toolset.
  2. auswerten Eigenschaften und Prozess Importe als
  3. auswerten Itemdefinitionen angetroffen
  4. Artikel Bewerten
  5. Bewerten Aufgaben
  6. starten bauen und Lese Ziele mit

Also, in Ihrem Fall die ItemDefinitionGroup für ClCompile wurde vor dem GetBranchName_TARGET ausgewertet wurde ausgeführt. Also, es ist leer von Design.

Um das gewünschte Verhalten zu erzielen, sollten Sie folgende hinzufügen:

<Target Name="GetBranchName_TARGET"> 
    <GetBranchName_TASK sPath="$(MSBuildThisFileDirectory)"> 
    <Output PropertyName="BranchName" TaskParameter="sBranchName" /> 
    </GetBranchName_TASK> 
    <Message Importance="High" Text="BranchName = $(BranchName)" /> 
    <ItemGroup> 
    <ClCompile> 
     <AdditionalOptions>/DBRANCHNAME=$(BranchName) /DMORE=BAR</AdditionalOptions> 
    </ClCompile> 
    </ItemGroup> 
</Target> 

Sie ein Condition Attribut in der ClCompile, um Ihre Quellen nur enthalten kann, zum Beispiel. Eigentlich, was Sie suchen, ist die Funktion zum Ändern item metadata after it was declared.