Elementos de MSBuild
Los elementos de MSBuild son entradas del sistema de compilación y suelen representar archivos (los archivos se especifican en el atributo Include
). Se agrupan en tipos de elemento de acuerdo con sus nombres de elemento. Los tipos de elemento son listas de elementos con nombre que se pueden usar como parámetros de las tareas. Las tareas utilizan los valores de los elementos para llevar a cabo los pasos del proceso de compilación.
Dado que el nombre de los elementos viene determinado por el tipo de elemento al que pertenecen, los términos "elemento" y "valor de elemento" se pueden utilizar indistintamente.
Crear elementos en un archivo de proyecto
Declara los elementos del archivo del proyecto como elementos secundarios de un elemento ItemGroup. Los nombres de elementos válidos comienzan con una letra mayúscula o minúscula o un carácter de subrayado (_
); los caracteres posteriores válidos incluyen caracteres alfanuméricos (letras o dígitos), carácter de subrayado y guión (-
). El nombre del elemento secundario es el tipo del elemento. El atributo Include
del elemento especifica los elementos (archivos) que se incluirán con ese tipo de elemento. Por ejemplo, el código XML siguiente crea un tipo de elemento denominado Compile
, que incluye dos archivos.
<ItemGroup>
<Compile Include = "file1.cs"/>
<Compile Include = "file2.cs"/>
</ItemGroup>
El elemento file2.cs no reemplaza al elemento file1.cs, sino que se anexa el nombre de archivo a la lista de valores del tipo del elemento Compile
.
El código XML siguiente crea el mismo tipo de elemento declarando ambos archivos en un atributo Include
. Observe que los nombres de archivo están separados por un punto y coma.
<ItemGroup>
<Compile Include = "file1.cs;file2.cs"/>
</ItemGroup>
El atributo Include
es una ruta de acceso que se interpreta en relación con la carpeta del archivo de proyecto, $(MSBuildProjectPath)
, incluso si el elemento está en un archivo importado, como un archivo .targets
.
Crear elementos durante la ejecución
Durante la fase de evaluación de una compilación, se asignan valores a los elementos que están fuera de los elementos Target. En la siguiente fase de la ejecución, se pueden crear o modificar elementos como se indica a continuación:
Cualquier tarea puede emitir un elemento. Para emitir un elemento, el elemento Task debe tener un elemento Output secundario que tenga un atributo
ItemName
.La tarea CreateItem puede emitir un elemento. (en desuso).
Los elementos
Target
pueden contener elementos ItemGroup que contengan elementos de elemento.
Hacer referencia a elementos en un archivo de proyecto
Para hacer referencia a tipos de elemento en el archivo del proyecto, utilice la sintaxis @(ItemType)
. Por ejemplo, podría hacer referencia al tipo de elemento del ejemplo anterior utilizando @(Compile)
. Con esta sintaxis, puede pasar elementos a las tareas especificando el tipo de elemento como un parámetro de la tarea. Para obtener más información, vea Cómo: Seleccionar los archivos que se van a compilar.
De manera predeterminada, los elementos de un tipo de elemento se separan con punto y coma (;) cuando se expanden. Puede usar la sintaxis @(ItemType, 'separator')
para especificar un separador distinto del predeterminado. Para obtener más información, vea Cómo: Mostrar una lista de elementos separados por comas.
Utilizar caracteres comodín para especificar elementos
Puede usar los caracteres comodín **
, *
y ?
para especificar un grupo de archivos como entradas para una compilación en lugar de enumerar cada archivo por separado.
- El carácter comodín
?
coincide con un único carácter. - El carácter comodín
*
coincide con cero o más caracteres. - La secuencia de caracteres comodín
**
coincide con una ruta de acceso parcial.
Por ejemplo, puede usar el elemento siguiente en el archivo de proyecto para especificar todos los archivos .cs
del directorio que contiene el archivo de proyecto.
<CSFile Include="*.cs"/>
El elemento siguiente selecciona todos los archivos .vb
de la unidad D:
:
<VBFile Include="D:/**/*.vb"/>
Si desea incluir los caracteres literales *
o ?
de un elemento sin expansión de caracteres comodín, debe escapar los caracteres comodín.
Para obtener más información sobre los caracteres comodín, vea Cómo: Seleccionar los archivos que se van a compilar.
Usar el atributo Exclude
Los elementos de elemento pueden contener el atributo Exclude
, que excluye elementos específicos (archivos) del tipo de elemento. El Exclude
atributo se usa normalmente junto con caracteres comodín. Por ejemplo, el código XML siguiente agrega todos los archivos .cs del directorio al tipo de elemento CSFile
, excepto el archivo DoNotBuild.cs.
<ItemGroup>
<CSFile Include="*.cs" Exclude="DoNotBuild.cs"/>
</ItemGroup>
El atributo Exclude
solamente afecta a los elementos agregados por el atributo Include
en el elemento de elemento que contiene ambos. En el ejemplo siguiente no se excluiría el archivo Form1.cs, que se ha agregado en el elemento de elemento anterior.
<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">
Para obtener más información, vea Cómo: Excluir archivos de la compilación.
Metadatos de elementos
Los elementos pueden contener metadatos además de la información recopilada en los atributos Include
y Exclude
. Estos metadatos pueden ser utilizados por las tareas que requieren más información sobre los elementos o para procesar por lotes tareas y destinos. Para obtener más información, consulte Procesamiento por lotes.
Los metadatos son una colección de pares clave-valor que se declaran en el archivo del proyecto como elementos secundarios de un elemento de elemento. El nombre de los metadatos es el nombre del elemento secundario, y el valor de los metadatos es el valor del elemento secundario.
Los metadatos están asociados al elemento de elemento que los contiene. Por ejemplo, el siguiente código XML agrega metadatos Culture
que tienen el valor Fr
a los elementos one.cs y two.cs del tipo de elemento CSFile
.
<ItemGroup>
<CSFile Include="one.cs;two.cs">
<Culture>Fr</Culture>
</CSFile>
</ItemGroup>
Un elemento puede tener cero o varios valores de metadatos. Puede cambiar los valores de los metadatos en cualquier momento. Si establece los metadatos en un valor vacío, se quitan eficazmente de la compilación.
Hacer referencia a metadatos de elementos en un archivo de proyecto
Puede hacer referencia a los metadatos de elementos en el archivo del proyecto mediante la sintaxis %(ItemMetadataName)
. Si existe ambigüedad, se puede calificar una referencia mediante el nombre del tipo de elemento. Por ejemplo, puede especificar %(ItemType.ItemMetaDataName)
. En el ejemplo siguiente se usan los metadatos Display
para procesar por lotes la tarea Message
. Para obtener más información sobre cómo usar los metadatos de elementos para el procesamiento por lotes, vea Metadatos de elementos en el procesamiento por lotes de tareas.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Stuff Include="One.cs" >
<Display>false</Display>
</Stuff>
<Stuff Include="Two.cs">
<Display>true</Display>
</Stuff>
</ItemGroup>
<Target Name="Batching">
<Message Text="@(Stuff)" Condition=" '%(Display)' == 'true' "/>
</Target>
</Project>
Metadatos de elementos conocidos
Cuando se agrega un elemento a un tipo de elemento, se le asignan metadatos conocidos. Por ejemplo, todos los elementos tienen los metadatos conocidos %(Filename)
, cuyo valor es el nombre de archivo del elemento (sin la extensión). Para obtener más información, vea Metadatos de elementos conocidos.
Transformar tipos de elemento mediante metadatos
Puede transformar listas de elementos en nuevas listas de elementos mediante metadatos. Por ejemplo, puede transformar un tipo de elemento CppFiles
que tiene elementos que representan archivos .cpp
en una lista correspondiente de archivos .obj
mediante la expresión @(CppFiles -> '%(Filename).obj')
.
El código siguiente crea un tipo de elemento CultureResource
que contiene copias de todos los elementos EmbeddedResource
con metadatos Culture
. El valor de los metadatos Culture
se convierte en el valor de los nuevos metadatos CultureResource.TargetDirectory
.
<Target Name="ProcessCultureResources">
<ItemGroup>
<CultureResource Include="@(EmbeddedResource)"
Condition="'%(EmbeddedResource.Culture)' != ''">
<TargetDirectory>%(EmbeddedResource.Culture) </TargetDirectory>
</CultureResource>
</ItemGroup>
</Target>
Para ver más operaciones sobre los elementos, consulte Funciones de elementos de MSBuild y Transformaciones.
Definiciones de elementos
Se pueden agregar metadatos predeterminados a cualquier tipo de elemento mediante el elemento ItemDefinitionGroup. Al igual que los metadatos conocidos, los metadatos predeterminados están asociados a todos los elementos del tipo de elemento que especifique. Puede invalidar explícitamente los metadatos predeterminados en una definición de elemento. Por ejemplo, el siguiente código XML proporciona a los elementos de Compile
one.cs y three.cs los metadatos BuildDay
con el valor "Monday". El código proporciona al elemento two.cs los metadatos BuildDay
con el valor "Tuesday".
<ItemDefinitionGroup>
<Compile>
<BuildDay>Monday</BuildDay>
</Compile>
</ItemDefinitionGroup>
<ItemGroup>
<Compile Include="one.cs;three.cs" />
<Compile Include="two.cs">
<BuildDay>Tuesday</BuildDay>
</Compile>
</ItemGroup>
Para obtener más información, vea Definiciones de elementos.
Atributos de los elementos de un ItemGroup de un destino
Los elementos Target
pueden contener elementos ItemGroup que contengan elementos de elemento. Los atributos de esta sección son válidos cuando se especifican para un elemento en un ItemGroup
que se encuentra en un Target
.
Atributo Remove
El atributo Remove
quita elementos específicos (archivos) del tipo de elemento. Este atributo se introdujo en .NET Framework 3.5 (solo destinos internos). A partir de MSBuild 15.0, se admiten los destinos internos y externos.
En el ejemplo siguiente se quitan todos los archivos .config
del tipo de elemento Compile
.
<Target>
<ItemGroup>
<Compile Remove="*.config"/>
</ItemGroup>
</Target>
Atributo MatchOnMetadata
El atributo MatchOnMetadata
solo es aplicable a los atributos Remove
que hacen referencia a otros elementos (por ejemplo, Remove="@(Compile);@(Content)"
) e indica a la operación Remove
que haga coincidir los elementos en función de los valores de los nombres de metadatos especificados, en lugar de según los valores de los elementos.
Regla de coincidencia para B Remove="@(A)" MatchOnMetadata="M"
: eliminar todos los elementos de B
que tengan metadatos M
, cuyo valor de metadatos V
para M
coincida con cualquier elemento de A
con metadatos M
de valor V
.
<Project>
<ItemGroup>
<A Include='a1' M1='1' M2='a' M3="e"/>
<A Include='b1' M1='2' M2='x' M3="f"/>
<A Include='c1' M1='3' M2='y' M3="g"/>
<A Include='d1' M1='4' M2='b' M3="h"/>
<B Include='a2' M1='x' m2='c' M3="m"/>
<B Include='b2' M1='2' m2='x' M3="n"/>
<B Include='c2' M1='2' m2='x' M3="o"/>
<B Include='d2' M1='3' m2='y' M3="p"/>
<B Include='e2' M1='3' m2='Y' M3="p"/>
<B Include='f2' M1='4' M3="r"/>
<B Include='g2' M3="s"/>
<B Remove='@(A)' MatchOnMetadata='M1;M2'/>
</ItemGroup>
<Target Name="PrintEvaluation">
<Message Text="%(B.Identity) M1='%(B.M1)' M2='%(B.M2)' M3='%(B.M3)'" />
</Target>
</Project>
En el ejemplo, los valores de los elementos b2
, c2
y d2
se eliminan del elemento B
porque:
b2
yc2
deB
coinciden conb1
deA
enM1=2
yM2=x
.d2
deB
coincide conc1
deA
enM1=3
yM2=y
.
La tarea Message
produce lo siguiente:
a2 M1='x' M2='c' M3='m'
e2 M1='3' M2='Y' M3='p'
f2 M1='4' M2='' M3='r'
g2 M1='' M2='' M3='s'
Ejemplo de uso de MatchOnMetadata
desde MSBuild:
<_TransitiveItemsToCopyToOutputDirectory Remove="@(_ThisProjectItemsToCopyToOutputDirectory)" MatchOnMetadata="TargetPath" MatchOnMetadataOptions="PathLike" />
Esta línea elimina los elementos de _TransitiveItemsToCopyToOutputDirectory
que tienen los mismos valores de metadatos TargetPath
de los elementos de _ThisProjectItemsToCopyToOutputDirectory
.
Atributo MatchOnMetadataOptions
Especifica la estrategia de coincidencia de cadenas utilizada por MatchOnMetadata
para buscar coincidencias con los valores de metadatos entre elementos (los nombres de los metadatos siempre coinciden sin distinguir entre mayúsculas y minúsculas). Los valores posibles son CaseSensitive
, CaseInsensitive
o PathLike
. El valor predeterminado es CaseSensitive
.
PathLike
aplica una normalización compatible con las rutas de acceso a los valores, como la normalización de las orientaciones de las barras, la omisión de las barras finales, la eliminación de .
y ..
, y la caracterización como absolutas de todas las rutas de acceso relativas con respecto al directorio actual.
Atributo KeepMetadata
Si se genera un elemento dentro de un destino, el elemento de elemento puede contener el atributo KeepMetadata
. Si se especifica este atributo, solo los metadatos que se especifican en la lista delimitada por punto y coma de nombres se transferirán desde el elemento de origen al elemento de destino. Un valor vacío para este atributo equivale a no especificarlo. El atributo KeepMetadata
se introdujo en .NET Framework 4.5.
En el ejemplo siguiente se muestra cómo utilizar el atributo KeepMetadata
.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="4.0">
<ItemGroup>
<FirstItem Include="rhinoceros">
<Class>mammal</Class>
<Size>large</Size>
</FirstItem>
</ItemGroup>
<Target Name="MyTarget">
<ItemGroup>
<SecondItem Include="@(FirstItem)" KeepMetadata="Class" />
</ItemGroup>
<Message Text="FirstItem: %(FirstItem.Identity)" />
<Message Text=" Class: %(FirstItem.Class)" />
<Message Text=" Size: %(FirstItem.Size)" />
<Message Text="SecondItem: %(SecondItem.Identity)" />
<Message Text=" Class: %(SecondItem.Class)" />
<Message Text=" Size: %(SecondItem.Size)" />
</Target>
</Project>
<!--
Output:
FirstItem: rhinoceros
Class: mammal
Size: large
SecondItem: rhinoceros
Class: mammal
Size:
-->
Atributo RemoveMetadata
Si se genera un elemento dentro de un destino, el elemento de elemento puede contener el atributo RemoveMetadata
. Si se especifica este atributo, todos los metadatos se transfieren desde el elemento de origen al elemento de destino excepto aquellos cuyos nombres figuran en la lista de nombres delimitada por punto y coma. Un valor vacío para este atributo equivale a no especificarlo. El atributo RemoveMetadata
se introdujo en .NET Framework 4.5.
En el ejemplo siguiente se muestra cómo utilizar el atributo RemoveMetadata
.
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MetadataToRemove>Size;Material</MetadataToRemove>
</PropertyGroup>
<ItemGroup>
<Item1 Include="stapler">
<Size>medium</Size>
<Color>black</Color>
<Material>plastic</Material>
</Item1>
</ItemGroup>
<Target Name="MyTarget">
<ItemGroup>
<Item2 Include="@(Item1)" RemoveMetadata="$(MetadataToRemove)" />
</ItemGroup>
<Message Text="Item1: %(Item1.Identity)" />
<Message Text=" Size: %(Item1.Size)" />
<Message Text=" Color: %(Item1.Color)" />
<Message Text=" Material: %(Item1.Material)" />
<Message Text="Item2: %(Item2.Identity)" />
<Message Text=" Size: %(Item2.Size)" />
<Message Text=" Color: %(Item2.Color)" />
<Message Text=" Material: %(Item2.Material)" />
</Target>
</Project>
<!--
Output:
Item1: stapler
Size: medium
Color: black
Material: plastic
Item2: stapler
Size:
Color: black
Material:
-->
Para ver más operaciones sobre los elementos, consulte Funciones de elementos de MSBuild.
Atributo KeepDuplicates
Si se genera un elemento dentro de un destino, el elemento de elemento puede contener el atributo KeepDuplicates
. KeepDuplicates
es un atributo Boolean
que especifica si se debe agregar al grupo de destino un elemento que es un duplicado exacto de un elemento existente.
Si el elemento de origen y de destino tienen el mismo valor Include
pero distintos metadatos, el elemento se agrega aunque KeepDuplicates
está establecido en false
. Un valor vacío para este atributo equivale a no especificarlo. El atributo KeepDuplicates
se introdujo en .NET Framework 4.5.
En el ejemplo siguiente se muestra cómo utilizar el atributo KeepDuplicates
.
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Item1 Include="hourglass;boomerang" />
<Item2 Include="hourglass;boomerang" />
</ItemGroup>
<Target Name="MyTarget">
<ItemGroup>
<Item1 Include="hourglass" KeepDuplicates="false" />
<Item2 Include="hourglass" />
</ItemGroup>
<Message Text="Item1: @(Item1)" />
<Message Text=" %(Item1.Identity) Count: @(Item1->Count())" />
<Message Text="Item2: @(Item2)" />
<Message Text=" %(Item2.Identity) Count: @(Item2->Count())" />
</Target>
</Project>
<!--
Output:
Item1: hourglass;boomerang
hourglass Count: 1
boomerang Count: 1
Item2: hourglass;boomerang;hourglass
hourglass Count: 2
boomerang Count: 1
-->
Dado que el atributo KeepDuplicates
considera los metadatos de los elementos además de los valores de elemento, es importante saber lo que sucede con los metadatos. Por ejemplo, consulte Detección de duplicados al usar la función de elemento de metadatos.
Actualización de los metadatos de los elementos de un ItemGroup fuera de un destino
Los elementos que están fuera de los destinos pueden actualizar sus metadatos existentes a través del atributo Update
. Este atributo no está disponible para elementos incluidos en destinos.
<Project>
<PropertyGroup>
<MetadataToUpdate>pencil</MetadataToUpdate>
</PropertyGroup>
<ItemGroup>
<Item1 Include="stapler">
<Size>medium</Size>
<Color>black</Color>
<Material>plastic</Material>
</Item1>
<Item1 Include="pencil">
<Size>small</Size>
<Color>yellow</Color>
<Material>wood</Material>
</Item1>
<Item1 Include="eraser">
<Color>red</Color>
</Item1>
<Item1 Include="notebook">
<Size>large</Size>
<Color>white</Color>
<Material>paper</Material>
</Item1>
<Item2 Include="notebook">
<Size>SMALL</Size>
<Color>YELLOW</Color>
</Item2>
<!-- Metadata can be expressed either as attributes or as elements -->
<Item1 Update="$(MetadataToUpdate);stapler;er*r;@(Item2)" Price="10" Material="">
<Color>RED</Color>
</Item1>
</ItemGroup>
<Target Name="MyTarget">
<Message Text="Item1: %(Item1.Identity)
Size: %(Item1.Size)
Color: %(Item1.Color)
Material: %(Item1.Material)
Price: %(Item1.Price)" />
</Target>
</Project>
<!--
Item1: stapler
Size: medium
Color: RED
Material:
Price: 10
Item1: pencil
Size: small
Color: RED
Material:
Price: 10
Item1: eraser
Size:
Color: RED
Material:
Price: 10
Item1: notebook
Size: large
Color: RED
Material:
Price: 10
-->
En MSBuild versión 16.6 y versiones posteriores, el atributo Update
admite referencias de metadatos calificados para facilitar la importación de metadatos de dos o más elementos.
<Project>
<ItemGroup>
<Item1 Include="stapler">
<Size>medium</Size>
<Color>black</Color>
<Material>plastic</Material>
</Item1>
<Item1 Include="pencil">
<Size>small</Size>
<Color>yellow</Color>
<Material>wood</Material>
</Item1>
<Item1 Include="eraser">
<Size>small</Size>
<Color>red</Color>
<Material>gum</Material>
</Item1>
<Item1 Include="notebook">
<Size>large</Size>
<Color>white</Color>
<Material>paper</Material>
</Item1>
<Item2 Include="pencil">
<Size>MEDIUM</Size>
<Color>RED</Color>
<Material>PLASTIC</Material>
<Price>10</Price>
</Item2>
<Item3 Include="notebook">
<Size>SMALL</Size>
<Color>BLUE</Color>
<Price>20</Price>
</Item3>
<!-- Metadata can be expressed either as attributes or as elements -->
<Item1 Update="@(Item2);er*r;@(Item3)" Size="%(Size)" Color="%(Item2.Color)" Price="%(Item3.Price)" Model="2020">
<Material Condition="'%(Item2.Material)' != ''">Premium %(Item2.Material)</Material>
</Item1>
</ItemGroup>
<Target Name="MyTarget">
<Message Text="Item1: %(Item1.Identity)
Size: %(Item1.Size)
Color: %(Item1.Color)
Material: %(Item1.Material)
Price: %(Item1.Price)
Model: %(Item1.Model)" />
</Target>
</Project>
<!--
Item1: stapler
Size: medium
Color: black
Material: plastic
Price:
Model:
Item1: pencil
Size: small
Color: RED
Material: Premium PLASTIC
Price:
Model: 2020
Item1: eraser
Size: small
Color:
Material: gum
Price:
Model: 2020
Item1: notebook
Size: large
Color:
Material: paper
Price: 20
Model: 2020
-->
Comentarios:
- Los metadatos no calificados (
%(MetadataName)
) se enlazan al tipo de elemento que se actualiza (Item1
en el ejemplo anterior). Los metadatos calificados (%(Item2.Color)
) se enlazan dentro del conjunto de tipos de elemento coincidentes capturados de la expresión de actualización. - Si un elemento coincide varias veces dentro y entre varios elementos a los que se hace referencia:
- Se captura la última repetición de cada tipo de elemento al que se hace referencia (por lo tanto, se captura un elemento por cada tipo de elemento).
- Esto coincide con el comportamiento del procesamiento por lotes de elementos de tarea incluidos en destinos.
- Donde se pueden colocar referencias a %():
- Metadata
- Condiciones de metadatos
- La coincidencia de los nombres de los metadatos no distingue mayúsculas de minúsculas.
Actualización de los metadatos de los elementos de un ItemGroup de un destino
Los metadatos también se pueden modificar dentro de destinos, con una sintaxis menos expresiva que Update
:
<Project>
<ItemGroup>
<Item1 Include="stapler">
<Size>medium</Size>
<Color>black</Color>
<Material>plastic</Material>
</Item1>
<Item1 Include="pencil">
<Size>small</Size>
<Color>yellow</Color>
<Material>wood</Material>
</Item1>
<Item1 Include="eraser">
<Size>small</Size>
<Color>red</Color>
<Material>gum</Material>
</Item1>
<Item1 Include="notebook">
<Size>large</Size>
<Color>white</Color>
<Material>paper</Material>
</Item1>
<Item2 Include="pencil">
<Size>MEDIUM</Size>
<Color>RED</Color>
<Material>PLASTIC</Material>
<Price>10</Price>
</Item2>
<Item2 Include="ruler">
<Color>GREEN</Color>
</Item2>
</ItemGroup>
<Target Name="MyTarget">
<ItemGroup>
<!-- Metadata can be expressed either as attributes or as elements -->
<Item1 Size="GIGANTIC" Color="%(Item2.Color)">
<Material Condition="'%(Item2.Material)' != ''">Premium %(Item2.Material)</Material>
</Item1>
</ItemGroup>
<Message Text="Item1: %(Item1.Identity)
Size: %(Item1.Size)
Color: %(Item1.Color)
Material: %(Item1.Material)
Price: %(Item1.Price)
Model: %(Item1.Model)" />
</Target>
</Project>
<!--
Item1: stapler
Size: GIGANTIC
Color: GREEN
Material: Premium PLASTIC
Price:
Model:
Item1: pencil
Size: GIGANTIC
Color: GREEN
Material: Premium PLASTIC
Price:
Model:
Item1: eraser
Size: GIGANTIC
Color: GREEN
Material: Premium PLASTIC
Price:
Model:
Item1: notebook
Size: GIGANTIC
Color: GREEN
Material: Premium PLASTIC
Price:
Model:
-->