2009-09-03 7 views
11

Come mantenere i valori definiti in un target di compilazione attivo in altri target? Se PropertyGroup non è l'entità di MsBuild di scrittura che dovrei usare qui, che cos'è? ReleaseDir viene stampato ok in target "pacchetto", ma è vuota in "DoPackage"Passaggio del valore del gruppo di proprietà da un'attività di MsBuild a un altro

<Target Name="Package"> 
    <PropertyGroup> 
    <ReleasesDir>c:\tmp</ReleasesDirBase> 
    </PropertyGroup> 
    <Message Text="$(ReleaseDir)"/> 
    <CallTarget Targets="DoPackage" Condition="!Exists('$(ReleaseDir)')"/> 
</Target> 

<!-- Do the acutal packaging --> 
<Target Name="DoPackage"> 
    <Message Text="Creating package in '$(ReleaseDir)'"/> 
    <Error Condition="'$(ReleaseDir)' == ''" Text="No ReleaseDir defined"/> 
    <MakeDir Directories="$(ReleaseDir)"/> 
    ... 
</Target> 

risposta

21

C'è un well known issue con proprietà e il compito CallTarget. Invece dovresti usare DependsOnTargets.

<Target Name="Package"> 
    <PropertyGroup> 
    <ReleasesDir>c:\tmp</ReleasesDir> 
    </PropertyGroup> 
    <Message Text="$(ReleasesDir)"/> 
</Target> 

<Target Name="PrePackage" DependsOnTargets="Package"> 
    <CallTarget Targets="DoPackage" Condition="!Exists('$(ReleasesDir)')"/> 
</Target> 

<!-- Do the actual packaging --> 
<Target Name="DoPackage" DependsOnTargets="Package"> 
    <Message Text="Creating package in '$(ReleasesDir)'"/> 
    <Error Condition="'$(ReleasesDir)' == ''" Text="No ReleaseDir defined"/> 
    <MakeDir Directories="$(ReleasesDir)"/> 
</Target> 
+0

Desidero che DoPackage venga eseguito solo se ReleaseDir esiste (ho utilizzato la condizione in CallTarget per ottenere ciò). Posso raggiungere questo obiettivo utilizzando DependsOnTarget? – ripper234

+0

Ora che ho effettivamente letto il link che hai postato, la soluzione è semplice: ho scritto un'attività separata chiamata "DefineProperties" e, al termine, le proprietà sono ... definite. Grazie. – ripper234

+0

Sì, questa è la soluzione, ho aggiornato il campione. –

1

Se si vuole passare una proprietà ad un target, il compito MSBuild può essere utile. Questo è l'unico modo per chiamare una destinazione più volte con valori di proprietà diversi, ma non consente il passaggio di elementi o gruppi di articoli. Vedi questo comment nel thread a cui Julien collega.

... [C] tutto il target MSBuild su di esso nuovamente, questa volta passando nelle proprietà richieste. Ciò ignora la costruzione incrementale ..., ma ha molte limitazioni, vale a dire che non puoi passare articoli e devi specificare quali proprietà devono essere superate.

Ecco ciò che il frammento di codice sarà simile utilizzando l'attività MSBuild:

<Target Name="Package"> 
    <PropertyGroup> 
    <ReleasesDir>c:\tmp</ReleasesDir> 
    </PropertyGroup> 
    <Message Text="$(ReleaseDir)"/> 
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="DoPackage" Properties="ReleaseDir=$(ReleaseDir)" /> 
</Target> 

<!-- Do the acutal packaging --> 
<Target Name="DoPackage"> 
    <Message Text="Creating package in '$(ReleaseDir)'"/> 
    <Error Condition="'$(ReleaseDir)' == ''" Text="No ReleaseDir defined"/> 
    <MakeDir Directories="$(ReleaseDir)"/> 
    ... 
</Target> 

Questa tecnica è utile se si desidera utilizzare l'obiettivo come una subroutine, che è possibile chiamare più volte con diversi valori dei parametri. Ad esempio, per chiamare un processo di compilazione per diverse configurazioni di prodotto.

1

Potrebbe non essere il modo più pulito per risolvere questo problema, ma se qualcuno vuole ancora utilizzare CallTarget sul file di build, lui/lei deve definire il PropertyGroup in un altro bersaglio, il seguente è la soluzione a questo strano problema

<Target Name="DebugBuild" DependsOnTargets="DebugBuildProp"> 
    <CallTarget Targets="CompileSolution"/> 
</Target> 
<Target Name="DebugBuildProp"> 
    <PropertyGroup> 
    <Configuration>Debug</Configuration> 
    </PropertyGroup> 
</Target> 
<Target Name="CompileSolution"> 
    <Message Text="$(Configuration)" /> 
</Target> 
+0

Se 'DeugBuild' aggiorna il valore di' Configurazione', ' CompileSolution' ancora non utilizzerà il nuovo valore. – makhdumi

+0

@ Al-Muhandis In realtà, non so perché, ma se si definisce la proprietà sul target di dipendenza, tutti gli altri target che si chiamano utilizzando CallTarget avranno il valore. Prova tu stesso –