Skip to content

Commit 6abf8cc

Browse files
Merge pull request #14034 from GitHubber17/440808-f
Freshness Edit: Visual Studio - MSBuild
2 parents 695d30a + e801316 commit 6abf8cc

File tree

1 file changed

+27
-28
lines changed

1 file changed

+27
-28
lines changed

docs/msbuild/msbuild-transforms.md

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,54 @@
11
---
2-
title: Use MSBuild transforms to build projects
3-
description: Learn how MSBuild uses transforms, one-to-one conversions of one item list to another, to build projects more efficiently.
4-
ms.date: 11/04/2016
5-
ms.topic: how-to
2+
title: Transforms in Project Builds and Target Mapping
3+
description: Learn how MSBuild uses transforms to build projects more efficiently with one-to-one conversions of one item list to another.
4+
ms.date: 06/26/2025
5+
ms.topic: concept-article
66
helpviewer_keywords:
77
- MSBuild, transforms
88
- transforms [MSBuild]
99
author: ghogen
1010
ms.author: ghogen
1111
manager: mijacobs
1212
ms.subservice: msbuild
13+
#customer intent: As a developer, I want to understand how MSBuild applies transforms for project builds and target mapping, so I can use transforms in my projects.
1314
---
15+
1416
# MSBuild transforms
1517

16-
A transform is a one-to-one conversion of one item list to another. In addition to enabling a project to convert item lists, a transform enables a target to identify a direct mapping between its inputs and outputs. This topic explains transforms and how MSBuild uses them to build projects more efficiently.
18+
A transform is a one-to-one conversion of one item list to another. Transforms enable projects in Visual Studio to convert item lists. Transforms also enable targets to identify a direct mapping between their inputs and outputs.
19+
20+
This article explains transforms and how the Microsoft Build Engine (MSBuild) uses them to build projects more efficiently.
1721

1822
## Transform modifiers
1923

20-
Transforms are not arbitrary, but are limited by special syntax in which all transform modifiers must be in the format %(\<ItemMetaDataName>). Any item metadata can be used as a transform modifier. This includes the well-known item metadata that is assigned to every item when it is created. For a list of well-known item metadata, see [Well-known item metadata](../msbuild/msbuild-well-known-item-metadata.md).
24+
Transforms aren't defined arbitrarily. Each transform is identified as a modifier of the format `%(\<ItemMetaDataName>)`. Any item metadata can be used as a transform modifier, including the well-known item metadata assigned to every item at creation. For the well-known item metadata list, see [MSBuild well-known item metadata](msbuild-well-known-item-metadata.md).
2125

22-
In the following example, a list of *.resx* files is transformed into a list of *.resources* files. The %(filename) transform modifier specifies that each *.resources* file has the same file name as the corresponding *.resx* file.
26+
The following example transforms a list of *.resx* files into a list of *.resources* files. The `%(filename)` transform modifier specifies that each *.resources* file has the same file name as the corresponding *.resx* file:
2327

2428
```xml
2529
@(RESXFile->'%(filename).resources')
2630
```
2731

28-
For example, if the items in the @(RESXFile) item list are *Form1.resx*, *Form2.resx*, and *Form3.resx*, the outputs in the transformed list will be *Form1.resources*, *Form2.resources*, and *Form3.resources*.
32+
If the items in the `@(RESXFile)` item list are *Form1.resx*, *Form2.resx*, and *Form3.resx*, the transformed list contains the outputs *Form1.resources*, *Form2.resources*, and *Form3.resources*.
2933

3034
> [!NOTE]
31-
> You can specify a custom separator for a transformed item list in the same way you specify a separator for a standard item list. For example, to separate a transformed item list by using a comma (,) instead of the default semicolon (;), use the following XML:
32-
> `@(RESXFile->'Toolset\%(filename)%(extension)', ',')`
35+
> The default separator for items in a transformed list is the semicolon `;`. You can specify a custom separator in the same way you specify a separator for a standard item list. To separate items with a comma `,` use the syntax `@(RESXFile->'Toolset\%(filename)%(extension)', ',')`.
3336
34-
## Use multiple modifiers
37+
## Multiple transform modifiers
3538

36-
A transform expression can contain multiple modifiers, which can be combined in any order and can be repeated. In the following example, the name of the directory that contains the files is changed but the files retain the original name and file name extension.
39+
A transform expression can contain multiple modifiers that can be combined in any order and can be repeated. In the following example, the name of the directory that contains the files is changed but the files retain the original name and file name extension:
3740

3841
```xml
3942
@(RESXFile->'Toolset\%(filename)%(extension)')
4043
```
4144

42-
For example, if the items that are contained in the `RESXFile` item list are *Project1\Form1.resx*, *Project1\Form2.resx*, and *Project1\Form3.text*, the outputs in the transformed list will be *Toolset\Form1.resx*, *Toolset\Form2.resx*, and *Toolset\Form3.text*.
45+
If the items in the `RESXFile` item list are *Project1\Form1.resx*, *Project1\Form2.resx*, and *Project1\Form3.text*, the transformed list contains the outputs *Toolset\Form1.resx*, *Toolset\Form2.resx*, and *Toolset\Form3.text*.
4346

44-
## Dependency analysis
47+
## Target mapping and dependency analysis
4548

46-
Transforms guarantee a one-to-one mapping between the transformed item list and the original item list. Therefore, if a target creates outputs that are transforms of the inputs, MSBuild can analyze the timestamps of the inputs and outputs, and decide whether to skip, build, or partially rebuild a target.
49+
Transforms guarantee a one-to-one mapping between the transformed item list and the original item list. If a target creates outputs that are transforms of the inputs, MSBuild can analyze the timestamps of the inputs and outputs. MSBuild uses the information to decide whether to skip, build, or partially rebuild a target.
4750

48-
In the [Copy task](../msbuild/copy-task.md) in the following example, every file in the `BuiltAssemblies` item list maps to a file in the destination folder of the task, specified by using a transform in the `Outputs` attribute. If a file in the `BuiltAssemblies` item list changes, the `Copy` task runs only for the changed file, and all other files are skipped. For more information about dependency analysis and how to use transforms, see [How to: Build incrementally](../msbuild/how-to-build-incrementally.md).
51+
The following example transforms the inputs for the [Copy task](copy-task.md) into outputs. Every file in the inputs `BuiltAssemblies` item list maps to a file in the destination folder of the task specified by using a transform in the `Outputs` attribute. If a file in the `BuiltAssemblies` item list changes, the `Copy task` runs for the changed file only and skips all other files.
4952

5053
```xml
5154
<Target Name="CopyOutputs"
@@ -59,13 +62,11 @@ For example, if the items in the @(RESXFile) item list are *Form1.resx*, *Form2.
5962
</Target>
6063
```
6164

62-
## Example
63-
64-
### Description
65+
For more information about dependency analysis and how to use transforms, see [MSBuild incremental builds for new or stale targets](how-to-build-incrementally.md).
6566

66-
The following example shows an MSBuild project file that uses transforms. This example assumes that there is just one *.xsd* file in the *c:\sub0\sub1\sub2\sub3* directory, and that the working directory is *c:\sub0*.
67+
## Project file with transforms
6768

68-
### Code
69+
The following example shows a project file for MSBuild that uses transforms. The example assumes the *c:\sub0\sub1\sub2\sub3* directory contains only one *.xsd* file and the working directory is *c:\sub0*.
6970

7071
```xml
7172
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
@@ -86,11 +87,9 @@ For example, if the items in the @(RESXFile) item list are *Form1.resx*, *Form2.
8687
</Project>
8788
```
8889

89-
### Comments
90+
The example produces the following output:
9091

91-
This example produces the following output:
92-
93-
```
92+
```output
9493
rootdir: C:\
9594
fullpath: C:\sub0\sub1\sub2\sub3\myfile.xsd
9695
rootdir + directory + filename + extension: C:\sub0\sub1\sub2\sub3\myfile.xsd
@@ -103,6 +102,6 @@ extension: .xsd
103102

104103
## Related content
105104

106-
- [MSBuild concepts](../msbuild/msbuild-concepts.md)
107-
- [MSBuild reference](../msbuild/msbuild-reference.md)
108-
- [How to: Build incrementally](../msbuild/how-to-build-incrementally.md)
105+
- [MSBuild concepts](msbuild-concepts.md)
106+
- [MSBuild reference](msbuild-reference.md)
107+
- [MSBuild incremental builds for new or stale targets](how-to-build-incrementally.md)

0 commit comments

Comments
 (0)