You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
6
6
helpviewer_keywords:
7
7
- MSBuild, transforms
8
8
- transforms [MSBuild]
9
9
author: ghogen
10
10
ms.author: ghogen
11
11
manager: mijacobs
12
12
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.
13
14
---
15
+
14
16
# MSBuild transforms
15
17
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.
17
21
18
22
## Transform modifiers
19
23
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).
21
25
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:
23
27
24
28
```xml
25
29
@(RESXFile->'%(filename).resources')
26
30
```
27
31
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*.
29
33
30
34
> [!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:
> 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)', ',')`.
33
36
34
-
## Use multiple modifiers
37
+
## Multiple transform modifiers
35
38
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:
37
40
38
41
```xml
39
42
@(RESXFile->'Toolset\%(filename)%(extension)')
40
43
```
41
44
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*.
43
46
44
-
## Dependency analysis
47
+
## Target mapping and dependency analysis
45
48
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.
47
50
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.
49
52
50
53
```xml
51
54
<TargetName="CopyOutputs"
@@ -59,13 +62,11 @@ For example, if the items in the @(RESXFile) item list are *Form1.resx*, *Form2.
59
62
</Target>
60
63
```
61
64
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).
65
66
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
67
68
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*.
0 commit comments