2013-03-28 9 views
5

Ho una regola di compilazione personalizzata in VS2010 per il mio progetto VC++. In questa regola, vorrei consentire agli utenti di aggiungere condizioni complesse sull'elaborazione del file.Come esporre le 'Condizioni' di MSBuild in VS2010 (per vC++)

Anche questo deve essere valutato al momento dell'esecuzione del target piuttosto che nella 'Condizione' dell'elemento 'stesso' (poiché solo il progetto 'applicazione' può elaborarlo e deve elaborarlo con le impostazioni del progetto 'applicazione' e non i progetti dipendenti).

Ho provato ad aggiungere un campo personalizzato all'oggetto e quindi a rimuovere gli elementi dal gruppo al momento dell'esecuzione. ad es.

<ItemGroup> 
    <MyItemType Remove="@(MyItemType)" Condition="!(%(MyItemType.IncludeCondition))" /> 
</ItemGroup> 

Purtroppo, questo mi dà l'errore:

errore MSB4113: "! (% (MyItemType.IncludeCondition))" condizione specificata restituisce " 'testfilename1' == 'testfilename2' o falso!" invece di un booleano.

(La condizione espressione originale in '% (MyItemType.IncludeCondition)' era '%(Filename)' == 'testfilename2' or $(TestBooleanFalse))

Sembra come se MSBuild non valuterà il contenuto dei metadati voce per un valore booleano (che sembra buona pratica in la maggior parte delle circostanze, solo non questa).

Esiste comunque la possibilità che MSbuild possa effettivamente valutare i metadati con un valore booleano oppure esiste un altro metodo che è possibile utilizzare per ottenere lo stesso risultato?


P.S. Ho avuto un breve sguardo attraverso il MSBuild Property Functions, ma non riuscivo a vedere nulla che possa eseguire il codice di valutazione booleana MSBuild sopra l'ingresso della funzione)


Un rifilato giù esempio di un progetto MSBuild che mostra il problema, per gentile concessione di Lanrokin:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build"> 
    <ItemGroup> 
     <MyItemType Include="item1.ext1" /> 
     <MyItemType Include="item1.ext2" /> 
    </ItemGroup> 

    <Target Name="SpecifyConditions"> 
     <ItemGroup> 
      <MyItemType> 
       <IncludeCondition>'%(Filename)%(Extension)' == 'item1.ext1'</IncludeCondition> 
      </MyItemType> 
     </ItemGroup> 
    </Target> 

    <Target Name="Build" DependsOnTargets="SpecifyConditions"> 
     <Message Importance="high" Text="@(MyItemType)" Condition="%(MyItemType.IncludeCondition)" /> 
    </Target> 
</Project> 
+0

tentato di modificare post, ma è stato respinto. Si prega di controllare se si tratta di qualcosa che si desidera fare lavoro http://pastebin.com/nkdz80y5 e prendere in considerazione l'inclusione di un campione nella domanda – Lanorkin

+0

@Lanorkin - Grazie, c'è stato un piccolo bug nell'esempio che hai fornito, ma mostra il problema I ' avendo (Si spera che le persone non rispondano e diano semplicemente la parola "ItemGroup" in "SpecifyConditions" in "Remove" con la condizione specificata come condizione della dichiarazione "MyItemType'" –

risposta

0

Provare a dichiarare le condizioni in linea al posto della voce di metadati:

<ItemGroup> 
    <MyItemType Remove="@(MyItemType)" Condition="('%(MyItemType.Filename)' == 'testfilename2')" /> 
    </ItemGroup> 

Oppure utilizzare Property Functions nella condizione di metadati:

<Target Name="SpecifyConditions"> 
    <ItemGroup> 
     <MyItemType> 
      <IncludeCondition>$([System.String]::Equals('%(Filename)%(Extension)', 'item1.ext1'))</IncludeCondition> 
     </MyItemType> 
    </ItemGroup> 
</Target> 

<Target Name="Build" DependsOnTargets="SpecifyConditions"> 
    <Message Importance="high" Text="@(MyItemType)" Condition="%(MyItemType.IncludeCondition)" /> 
</Target> 
+0

Non posso farlo perché le condizioni sono definito dall'utente per file (come indicato nella mia seconda frase nella domanda originale). –

+0

Funziona: 'Condition =" '(% (MyItemType.IncludeCondition))' == 'False' "' – KMoraz

+0

no, l'idea è che '% (MyItemType.IncludeCondition)' espansa come 'stringa' piuttosto che boolean, sebbene non è valutato – Lanorkin

0

penso che un piccolo ritocco della vostra istruzione condizionale da:

'%(Filename)' == 'testfilename2' or $(TestBooleanFalse) 

a

('%(Filename)' == 'testfilename2') or $(TestBooleanFalse) 

avvolgendo la prima condizione interna una staffa risolverà il problema.

+0

No, non lo farò. Puoi provare ad usare l'esempio qui http://pastebin.com/nkdz80y5 per controllare – Lanorkin

1

Questo ha a che fare con il modo in cui MSBuild valuta. Vedere il libro di Sayed per ulteriori informazioni: Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build

Spostando la posizione della condizione nel campione, è possibile ottenere ciò che penso si stia tentando di ottenere.

<Target Name="SpecifyConditions"> 
    <ItemGroup> 
     <MyItemType Condition="'%(Filename)%(Extension)' == 'item1.ext1'"> 
      <IncludeCondition>true</IncludeCondition> 
     </MyItemType> 
    </ItemGroup> 
</Target> 

<Target Name="Build" DependsOnTargets="SpecifyConditions"> 
    <Message Importance="high" Text="@(MyItemType)" Condition="%(MyItemType.IncludeCondition) == 'true'" /> 
</Target> 

+0

In tale soluzione eseguiamo ancora msbuild per calcolare la condizione nel task 'SpecifyConditions', mentre l'idea è di" passare "la condizione come parametro, in modo che essere calcolato nel task 'Build'. – Lanorkin

Problemi correlati