30/8/2010 12:28
El Bruno
[MSBUILD] Invocando Targets y pasando valores entre los mismos (VI)

Buenas,
una vez definidos nuestros MSBuild Targets, es momento de controlar el flujo de llamadas entre ellos. Para esto utilizamos la tarea de MSBuild: CallTarget. Esta tarea tiene una sintaxis muy simple, y el atributo @Targets, define los MSBuild Targets que se invocarán.
Por ejemplo, en el siguiente proyecto, existen definidos 3 Targets:
y utilizando la tarea CallTarget, se define el siguiente flujo de llamadas: Target1 –> Target2 –> Target3, en las líneas 5 y 9:
1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
2: InitialTargets="Target1">
3: <Target Name="Target1">
4: <Message Text="Target 1" />
5: <CallTarget Targets="Target2" />
6: </Target>
7: <Target Name="Target2">
8: <Message Text="Target 2" />
9: <CallTarget Targets="Target3" />
10: </Target>
11: <Target Name="Target3">
12: <Message Text="Target 3" />
13: </Target>
14: </Project>
El resultado de la ejecución del prioyecto es similar al siguiente:
Ahora bien, esta tarea además de gestionar la llamada entre MSBuild Targets, analiza las dependencias entre los mismos al momento de ejecutar para evitar bucles infinitos.
El siguiente proyecto, muestra un ejemplo de un bucle infinito, donde el Target1 se llama a si mismo.
1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
2: InitialTargets="Target1">
3: <Target Name="Target1">
4: <Message Text="Target 1" />
5: <CallTarget Targets="Target1" />
6: </Target>
7: </Project>
Si intentamos ejecutar este proyecto, veremos que el compilador de MSBuild, se encarga de alertarnos sobre una dependencia circular:
Finalmente un caso común a tener en cuenta, es aquel en donde necesitamos invocar a un MSBuild Target, varias veces pero con diferentes valores. Es decir, similar a llamar a una función pasando diferentes valores a los parámetros de la misma.
El siguiente ejemplo muestra un proyecto en donde, en el MSBuild Target principal Target1, se invoca a un nuevo MSBuild Target denominado Target2, que muestra en ell output los valores de las propiedades $(Name) y $(Edad) (líneas 14 y 15).
Esta invocación no la realizo utilizando la tarea CallTarget, y además utilizo la tarea MSBuild Task para realizar la llamada, con las siguientes consideraciones:
- Utilizo el proyecto actual como proyecto a compilar, asignando $(MSBuildProjectFile) al atributo @Projects.
- Defino el Target2 como el MSbuild Target a invocar, en el atributo @Targets.
- Defino las propiedades $(Name) y $(Edad) con valores diferentes en cada llamada (líneas 8 y 11).
1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
2: DefaultTargets="Target1">
3: <Target Name="Target1">
4: <Message Text="Target 1" />
5: <CallTarget Targets="Target2" />
6: <MSBuild Projects="$(MSBuildProjectFile)"
7: Targets="Target2"
8: Properties="Name=Valentino;Edad=2" />
9: <MSBuild Projects="$(MSBuildProjectFile)"
10: Targets="Target2"
11: Properties="Name=Martina;Edad=Casi 1" />
12: </Target>
13: <Target Name="Target2">
14: <Message Text="Name = $(Name)" />
15: <Message Text="Edad = $(Edad)" />
16: </Target>
17: </Project>
Este proyecto, invoca nuevamente al compilador de MSBuild y en lugar de comenzar por el Target1, definido como @DefaultTarget, inicia en el Target2, e inicializa las propiedades con los valores correspondientes. El resultado de la ejecución muestra como no existen valores para las propiedades en la primera llamada, pero si se muestran datos en las llamadas con la tarea MSBuild Task.
Saludos @ Here
El Bruno (@elbruno en Twitter)
Archivado en: Visual Studio 2010,Build,Code Sample,Tutorial,MSBuild
Comparte este post: