Tutorial: Usar MSBuild
MSBuild es la plataforma de compilación para Microsoft y Visual Studio.Este tutorial presenta los bloques de compilación de MSBuild y muestra la forma de escribir, manipular y depurar los proyectos de MSBuild.Aprenderá a:
Crear y manipular un archivo del proyecto
Cómo usar las propiedades de compilación
Cómo usar los elementos de compilación
Puede ejecutar MSBuild desde Visual Studio o en la ventana Comandos.En este tutorial, creará un archivo del proyecto de MSBuild con Visual Studio.Editará el archivo del proyecto en Visual Studio y utilizará una ventana Comandos para compilar el proyecto y examinar los resultados.
Crear un proyecto de MSBuild
El sistema de proyectos de Visual Studio se basa en MSBuild.Esto facilita la creación de un nuevo archivo del proyecto con Visual Studio.En esta sección, creará un archivo del proyecto de Visual C#.En su lugar, puede crear un archivo del proyecto de Visual Basic.En el contexto de este tutorial, la diferencia entre los dos archivos del proyecto es secundaria.
Para crear un archivo del proyecto
Abra Visual Studio.
En el menú Archivo, elija Nuevo y haga clic en Proyecto.
En el cuadro de diálogo Nuevo proyecto, seleccione el tipo de proyecto de Visual C# y, a continuación, seleccione la plantilla Aplicación de Windows Forms.En el cuadro Nombre, escriba BuildApp.Escriba una Ubicación para la solución, por ejemplo, D:\.Acepte los valores predeterminados para Crear directorio para la solución (seleccionado), Agregar al control de código fuente (no seleccionado) y Nombre de la solución (BuildApp).
Haga clic en Aceptar para crear el archivo del proyecto.
Examinar el archivo del proyecto.
En la sección anterior, utilizó Visual Studio para crear un archivo del proyecto de Visual C#.El archivo del proyecto se representa en el Explorador de soluciones por el nodo de proyecto denominado BuildApp.Puede utilizar el editor de código de Visual Studio para examinar el archivo del proyecto.
Para examinar el archivo del proyecto
En el Explorador de soluciones, haga clic en el nodo de proyecto BuildApp.
En el explorador de Propiedades, observe que la propiedad Project File es BuildApp.csproj.Todos los nombres de los archivos del proyecto llevan el sufijo "proj".Si hubiera creado un proyecto de Visual Basic, el nombre del archivo del proyecto sería BuildApp.vbproj.
Haga clic con el botón secundario en el nodo del proyecto y, después, haga clic en Descargar el proyecto.
Haga clic con el botón secundario de nuevo en el nodo del proyecto y, a continuación, haga clic en Editar BuildApp.csproj.
El archivo del proyecto aparece en el editor de código.
Destinos y tareas
Los archivos del proyecto son archivos con formato XML y con el nodo raíz Project.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
Debe especificar el espacio de nombres xmlns en el elemento Project.
El trabajo de compilar una aplicación se hace con los elementos Destino y Tarea .
Una tarea es la unidad de trabajo más pequeña, en otras palabras, el "átomo" de una compilación.Las tareas son componentes ejecutables independientes que pueden tener entradas y salidas.No hay actualmente ninguna tarea a la que se haga referencia o que esté definida en el archivo del proyecto.Agregará tareas al archivo del proyecto en las secciones siguientes.Para obtener más información, vea el tema Tareas de MSBuild.
Un destino es una secuencia con nombre de tareas.Hay dos destinos al final del archivo del proyecto incluidos actualmente en comentarios HTML: BeforeBuild y AfterBuild.
<Target Name="BeforeBuild"> </Target> <Target Name="AfterBuild"> </Target>
Para obtener más información, vea el tema Objetivos de MSBuild.
El nodo Project tiene un atributo DefaultTargets opcional que selecciona el destino predeterminado para la compilación, en este caso Build.
<Project ToolsVersion="4.0" DefaultTargets="Build" ...
El destino Build no se define en el archivo del proyecto.En su lugar, se importa del archivo Microsoft.CSharp.targets utilizando el elemento Import.
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Los archivos importados se insertan realmente en el archivo del proyecto, dondequiera que se les haga referencia.
MSBuild realiza el seguimiento de los destinos de una compilación y garantiza que cada destino se compile solamente una vez.
Agregar un destino y una tarea
Agregue un destino al archivo del proyecto.Agregue una tarea al destino que imprima un mensaje.
Para agregar un destino y una tarea
Agregue estas líneas al archivo del proyecto, justo después de la instrucción Import:
<Target Name="HelloWorld"> </Target>
Esto crea un destino denominado HelloWorld.Observe que tiene compatibilidad con Intellisense mientras edita el archivo del proyecto.
Agregue líneas al destino HelloWorld para que la sección resultante sea similar a esta:
<Target Name="HelloWorld"> <Message Text="Hello"></Message> <Message Text="World"></Message> </Target>
Guarde el archivo de proyecto.
La tarea Message es una de las muchas tareas que se distribuyen con MSBuild.Para obtener una lista completa de tareas disponibles e información de uso, vea Referencia de tareas de MSBuild.
La tarea Message toma el valor de cadena del atributo Text como entrada y lo muestra en el dispositivo de salida.El destino HelloWorld ejecuta la tarea Message dos veces: primero para mostrar "Hello" y luego para mostrar "World".
Compilar el destino
Ejecute MSBuild desde el símbolo del sistema de Visual Studio para compilar el destino HelloWorld definido anteriormente.Utilice el modificador de línea de comandos /target o /t para seleccionar el destino.
[!NOTA]
Haremos referencia al símbolo del sistema de Visual Studio como la ventana Comandos en las secciones siguientes.
Para compilar el destino
Haga clic en Inicio y, a continuación, en Todos los programas.Busque y haga clic en el símbolo del sistema de Visual Studio en la carpeta Visual Studio Tools.
En la ventana Comandos, navegue hasta la carpeta que contiene el archivo del proyecto, en este caso, D:\BuildApp\BuildApp.
Ejecute msbuild con el modificador de comando /t:HelloWorld.Esto selecciona y compila el destino HelloWorld:
msbuild buildapp.csproj /t:HelloWorld
Examine la salida en la ventana Comandos.Debe ver las dos líneas "Hello" y "World":
Hello World
[!NOTA]
Si en su lugar ve The target "HelloWorld" does not exist in the project es probable que se haya olvidado de guardar el archivo del proyecto en el editor de código.Guarde el archivo y vuelva a intentarlo.
Alternando entre el editor de código y la ventana Comandos, puede cambiar el archivo del proyecto y ver rápidamente los resultados.
[!NOTA]
Si ejecuta msbuild sin el modificador de comando /t, msbuild compilará el destino proporcionado por el atributo DefaultTarget del elemento Project, en este caso "Build".Esto compila el BuildApp.exe de la aplicación de Windows Forms.
Propiedades de compilación
Las propiedades de compilación son pares de nombre y valor que guían la compilación.Ya se han definido varias propiedades de compilación al principio del archivo del proyecto:
<PropertyGroup>
...
<ProductVersion>10.0.11107</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{30E3C9D5-FD86-4691-A331-80EA5BA7E571}</ProjectGuid>
<OutputType>WinExe</OutputType>
...
</PropertyGroup>
Todas las propiedades son elementos secundarios de elementos PropertyGroup.El nombre de la propiedad es el nombre del elemento secundario y el valor de la propiedad es el elemento de texto del elemento secundario.Por ejemplo,
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
define la propiedad denominada TargetFrameworkVersion, dándole el valor de cadena "v4.0".
Las propiedades de compilación se pueden volver a definir en cualquier momento.If
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
aparece más adelante en el archivo del proyecto, o en un archivo importado posteriormente en el archivo del proyecto, TargetFrameworkVersion toma el nuevo valor "v3.5".
Examinar el valor de una propiedad
Para obtener el valor de una propiedad, utilice la sintaxis siguiente, donde PropertyName es el nombre de la propiedad:
$(PropertyName)
Utilice esta sintaxis para examinar algunas de las propiedades en el archivo del proyecto.
Para examinar el valor de una propiedad
En el editor de código, reemplace el destino HelloWorld por este código:
<Target Name="HelloWorld"> <Message Text="Configuration is $(Configuration)" /> <Message Text="MSBuildToolsPath is $(MSBuildToolsPath)" /> </Target>
Guarde el archivo de proyecto.
Desde la ventana Comandos, escriba y ejecute la siguiente línea:
msbuild buildapp.csproj /t:HelloWorld
Examine los resultados.Debe ver estas dos líneas (es posible que su versión de .NET Framework difiera):
Configuration is Debug MSBuildToolsPath is C:\Windows\Microsoft.NET\Framework\v4.0.20317
[!NOTA]
Si no ve estas líneas, es probable que se haya olvidado de guardar el archivo del proyecto en el editor de código.Guarde el archivo y vuelva a intentarlo.
Propiedades condicionales
Muchas propiedades, como Configuration, se definen condicionalmente, es decir, el atributo Condition aparece en el elemento de propiedad.Las propiedades condicionales se definen o vuelven a definir solo si la condición se evalúa como "true".Observe que a las propiedades no definidas se les proporciona el valor predeterminado de una cadena vacía.Por ejemplo,
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
significa "Si la propiedad Configuration no se ha definido todavía, defínala y dele el valor 'Debug'".
Casi todos elementos de MSBuild pueden tener un atributo Condition.Para obtener más información sobre cómo utilizar el atributo Condition, vea Condiciones de MSBuild.
Propiedades reservadas
MSBuild reserva algunos nombres de propiedad para almacenar información sobre el archivo del proyecto y los binarios de MSBuild.MSBuildToolsPath es un ejemplo de una propiedad reservada (nueva en MSBuild 3.5).Como a cualquier otra propiedad, a las propiedades reservadas se hace referencia con la notación $.Para obtener más información, vea Cómo: Hacer referencia al nombre o ubicación del archivo de proyecto y Propiedades reservadas de MSBuild.
Variables de entorno
En los archivos del proyecto, se puede hacer referencia a las variables de entorno como si fueran propiedades de compilación.Por ejemplo, para utilizar la variable de entorno PATH en el archivo de proyecto, utilice $(Path).Si el proyecto incluye la definición de una propiedad que tiene el mismo nombre que una variable de entorno, la propiedad del proyecto reemplaza el valor de la variable de entorno.Para obtener más información, vea Cómo: Utilizar variables de entorno al compilar.
Establecer propiedades desde la línea de comandos
Las propiedades se pueden definir en la línea de comandos utilizando el modificador de línea de comandos /property o /p.Los valores de propiedad recibidos desde la línea de comandos invalidan los valores de propiedad establecidos en el archivo del proyecto y las variables de entorno.
Para establecer el valor de una propiedad desde la línea de comandos
Desde la ventana Comandos, escriba y ejecute la siguiente línea:
msbuild buildapp.csproj /t:HelloWorld /p:Configuration=Release
Examine los resultados.Debe ver esta línea:
Configuration is Release.
MSBuild crea la propiedad Configuration y le asigna el valor "Release".
Caracteres especiales
Ciertos caracteres tienen un significado especial en archivos del proyecto de MSBuild.Ejemplos de estos caracteres son los signos de punto y coma (;) y los asteriscos (*).Para utilizar estos caracteres especiales con su significado literal en un archivo de proyecto, es preciso especificarlos con la sintaxis %xx, donde xx representa el valor hexadecimal ASCII del carácter.
Cambie la tarea Message para mostrar el valor de la propiedad Configuration con caracteres especiales para que se pueda leer mejor.
Para utilizar caracteres especiales en la tarea Message
En el editor de código, reemplace ambas tareas Message por esta línea:
<Message Text="%24(Configuration) is %22$(Configuration)%22" />
Guarde el archivo de proyecto.
Desde la ventana Comandos, escriba y ejecute la siguiente línea:
msbuild buildapp.csproj /t:HelloWorld
Examine los resultados.Debe ver esta línea:
$(Configuration) is "Debug"
Para obtener más información, vea Caracteres especiales de MSBuild.
Elementos de compilación
Un elemento es un fragmento de información, normalmente un nombre de archivo, que se utiliza como entrada al sistema de compilación.Por ejemplo, una colección de elementos que representan archivos de código fuente pueden pasarse a una tarea denominada Compile para compilarlos en un ensamblado.
Todos los elementos son elementos secundarios de elementos ItemGroup.El nombre de elemento es el nombre del elemento secundario y el valor de elemento es el valor del atributo Include del elemento secundario.Los valores de elementos con el mismo nombre se agrupan en tipos de elemento de ese nombre.Por ejemplo,
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
define un grupo de elementos que contiene dos elementos.El tipo de elemento Compile tiene dos valores: "Program.cs" y "Properties\AssemblyInfo.cs".
El código siguiente crea el mismo tipo de elemento declarando ambos archivos en un atributo Include, separados por punto y coma.
<ItemGroup>
<Compile Include="Program.cs;Properties\AssemblyInfo.cs" />
</ItemGroup>
Para obtener más información, vea Elementos de MSBuild.
[!NOTA]
Las rutas de acceso de archivo son relativas a la carpeta que contiene el archivo del proyecto de MSBuild.
Examinar los valores de tipo de elemento
Para obtener los valores de un tipo de elemento, utilice la sintaxis siguiente, donde ItemType es el nombre del tipo de elemento:
@(ItemType)
Utilice esta sintaxis para examinar el tipo de elemento Compile en el archivo del proyecto.
Para examinar los valores de tipo de elemento
En el editor de código, reemplace la tarea de destino HelloWorld por este código:
<Target Name="HelloWorld"> <Message Text="Compile item type contains @(Compile)" /> </Target>
Guarde el archivo de proyecto.
Desde la ventana Comandos, escriba y ejecute la siguiente línea:
msbuild buildapp.csproj /t:HelloWorld
Examine los resultados.Debe ver esta línea larga:
Compile item type contains Form1.cs;Form1.Designer.cs;Program.cs;Properties\AssemblyInfo.cs;Properties\Resources.Designer.cs;Properties\Settings.Designer.cs
Los valores de un tipo de elemento se separan de forma predeterminada con puntos y coma.
Para cambiar el separador de un tipo de elemento, utilice la sintaxis siguiente, donde ItemType es el tipo de elemento y Separator es una cadena de uno o más caracteres de separación:
@(ItemType, Separator)
Cambie la tarea Message para utilizar retornos de carro y saltos de línea (% 0A%0D) con el fin de mostrar los elementos Compile uno por línea.
Para mostrar los valores de tipo de elemento uno por línea
En el editor de código, reemplace la tarea Message por esta línea:
<Message Text="Compile item type contains @(Compile, '%0A%0D')" />
Guarde el archivo de proyecto.
Desde la ventana Comandos, escriba y ejecute la siguiente línea:
msbuild buildapp.csproj /t:HelloWorld
Examine los resultados.Debe ver las siguientes líneas:
Compile item type contains Form1.cs Form1.Designer.cs Program.cs Properties\AssemblyInfo.cs Properties\Resources.Designer.cs Properties\Settings.Designer.cs
Include, Exclude y caracteres comodín
Puede utilizar los caracteres comodín "*", "**" y "?" con el atributo Include para agregar elementos a un tipo de elemento.Por ejemplo,
<Photos Include="images\*.jpeg" />
agrega todos los archivos con la extensión ".jpeg" de la carpeta images al tipo de elemento Photos, mientras que
<Photos Include="images\**.jpeg" />
agrega todos los archivos con la extensión ".jpeg" de la carpeta images, y todas sus subcarpetas, al tipo de elemento Photos.Para obtener más ejemplos, vea Cómo: Seleccionar los archivos que se van a compilar.
Observe que según se declaran elementos se agregan al tipo de elemento.Por ejemplo,
<Photos Include="images\*.jpeg" />
<Photos Include="images\*.gif" />
crea un tipo de elemento denominado Photo que contiene todos los archivos de la carpeta de imágenes con una extensión ".jpeg" o ".gif".Esto es equivalente a la línea siguiente:
<Photos Include="images\*.jpeg;images\*.gif" />
Puede excluir un elemento de un tipo de elemento con el atributo Exclude.Por ejemplo,
<Compile Include="*.cs" Exclude="*Designer*">
agrega todos los archivos con la extensión ".cs" al tipo de elemento Compile, salvo los archivos cuyos nombres contienen la cadena "Designer".Para obtener más ejemplos, vea Cómo: Excluir archivos de la compilación.
El atributo Exclude solamente afecta a los elementos agregados por el atributo Include en el elemento que contiene ambos.Por ejemplo,
<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">
no excluiría el archivo Form1.cs, que se agregó en el elemento anterior.
Para incluir y excluir elementos
En el editor de código, reemplace la tarea Message por esta línea:
<Message Text="Compile item type contains @(XFiles)" />
Agregue este grupo de elementos justo después del elemento Import:
<ItemGroup> <XFiles Include="*.cs;properties/*.resx" Exclude="*Designer*" /> </ItemGroup>
Guarde el archivo de proyecto.
Desde la ventana Comandos, escriba y ejecute la siguiente línea:
msbuild buildapp.csproj /t:HelloWorld
Examine los resultados.Debe ver esta línea:
Compile item type contains Form1.cs;Program.cs;Properties/Resources.resx
Metadatos de elementos
Los elementos pueden contener metadatos además de la información recopilada de los atributos Include y Exclude.Estos metadatos los pueden utilizar las tareas que requieren más información sobre elementos que solo el valor de elemento.
Los metadatos de elementos se declaran en el archivo de proyecto creando un elemento con el nombre de los metadatos como elemento secundario del elemento.Un elemento puede tener cero o varios valores de metadatos.Por ejemplo, el elemento CSFile siguiente tiene los metadatos Culture con un valor de "Fr":
<ItemGroup>
<CSFile Include="main.cs">
<Culture>Fr</Culture>
</CSFile>
</ItemGroup>
Para obtener el valor de metadatos de un tipo de elemento, utilice la sintaxis siguiente, donde ItemType es el nombre del tipo de elemento y MetaDataName es el nombre de los metadatos:
%(ItemType.MetaDataName)
Para examinar los metadatos de elementos
En el editor de código, reemplace la tarea Message por esta línea:
<Message Text="Compile.DependentUpon: %(Compile.DependentUpon)" />
Guarde el archivo de proyecto.
Desde la ventana Comandos, escriba y ejecute la siguiente línea:
msbuild buildapp.csproj /t:HelloWorld
Examine los resultados.Debe ver las siguientes líneas:
Compile.DependentUpon: Compile.DependentUpon: Form1.cs Compile.DependentUpon: Resources.resx Compile.DependentUpon: Settings.settings
Observe cómo la frase "Compile.DependentUpon" aparece varias veces.El uso de metadatos con esta sintaxis dentro de un destino produce el "procesamiento por lotes".El procesamiento por lotes significa que las tareas dentro del destino se ejecutan una vez para cada valor de metadatos único.Este es el script de MSBuild equivalente de la construcción de programación "bucle for" común.Para obtener más información, vea Procesamiento por lotes de MSBuild.
Metadatos conocidos
Cada vez que se agrega un elemento a una lista de elementos, se le asignan metadatos conocidos.Por ejemplo, %(Filename) devuelve el nombre de archivo de cualquier elemento.Para obtener una lista completa de metadatos conocidos, vea Metadatos de los elementos conocidos de MSBuild.
Para examinar los metadatos conocidos
En el editor de código, reemplace la tarea Message por esta línea:
<Message Text="Compile Filename: %(Compile.Filename)" />
Guarde el archivo de proyecto.
Desde la ventana Comandos, escriba y ejecute la siguiente línea:
msbuild buildapp.csproj /t:HelloWorld
Examine los resultados.Debe ver las siguientes líneas:
Compile Filename: Form1 Compile Filename: Form1.Designer Compile Filename: Program Compile Filename: AssemblyInfo Compile Filename: Resources.Designer Compile Filename: Settings.Designer
Comparando los dos ejemplos anteriores, puede ver que mientras que no todos los elementos del tipo de elemento Compile tiene metadatos DependentUpon, todos los elementos tienen metadatos Filename conocidos.
Transformaciones de metadatos
Las listas de elementos se pueden transformar en nuevas listas de elementos.Para transformar una lista de elementos, utilice la sintaxis siguiente, donde ItemType es el nombre del tipo de elemento y MetadataName es el nombre de los metadatos:
@(ItemType -> '%(MetadataName)')
Por ejemplo, una lista de elementos de archivos de origen se puede transformar en una colección de archivos de objeto mediante una expresión como @(SourceFiles -> '%(Filename).obj').Para obtener más información, vea Transformaciones de MSBuild.
Para transformar elementos mediante metadatos
En el editor de código, reemplace la tarea Message por esta línea:
<Message Text="Backup files: @(Compile->'%(filename).bak')" />
Guarde el archivo de proyecto.
Desde la ventana Comandos, escriba y ejecute la siguiente línea:
msbuild buildapp.csproj /t:HelloWorld
Examine los resultados.Debe ver esta línea:
Backup files: Form1.bak;Form1.Designer.bak;Program.bak;AssemblyInfo.bak;Resources.Designer.bak;Settings.Designer.bak
Observe que los metadatos expresados en esta sintaxis no producen el procesamiento por lotes.
Pasos adicionales
Para obtener información sobre cómo crear un archivo del proyecto simple paso por paso, intente Tutorial: Crear un archivo del proyecto de MSBuild desde el principio.