Skip to content

Commit 7963874

Browse files
Merge pull request #14167 from ghogen/improve-customize-article
Improve customize for codegen article
2 parents cd54c32 + 2fc8afe commit 7963874

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

docs/msbuild/customize-builds-for-generated-files.md

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Handle generated files in a build
33
description: Customize MSBuild project files in Visual Studio so that files generated during the build process are included in build output.
4-
ms.date: 02/28/2023
4+
ms.date: 8/5/2025
55
ms.topic: how-to
66
helpviewer_keywords:
77
- MSBuild, transforms
@@ -22,22 +22,55 @@ Files generated during execution don't exist during the evaluation phase, theref
2222

2323
<!-- Some logic that generates your file goes here -->
2424
<!-- Generated files should be placed in $(IntermediateOutputPath) -->
25+
<WriteLinesToFile
26+
File="$(IntermediateOutputPath)GeneratedFile.cs"
27+
Lines='enum MyEnum { A, B }'
28+
Overwrite="true" />
29+
<ItemGroup>
30+
<Compile Include="$(IntermediateOutputPath)GeneratedFile.cs" />
31+
</ItemGroup>
2532

2633
<ItemGroup>
2734
<!-- If your generated file was placed in `obj\` -->
28-
<None Include="$(IntermediateOutputPath)my-generated-file.xyz" CopyToOutputDirectory="PreserveNewest"/>
35+
<None Include="$(IntermediateOutputPath)GeneratedFile.cs" TargetPath="GeneratedFile.cs" CopyToOutputDirectory="PreserveNewest"/>
2936
<!-- If you know exactly where that file is going to be, you can hard code the path. -->
30-
<None Include="some\specific\path\my-generated-file.xyz" CopyToOutputDirectory="PreserveNewest"/>
37+
<None Include="some\specific\path\my-generatedfile" CopyToOutputDirectory="PreserveNewest"/>
3138

3239
<!-- If you want to capture "all files of a certain type", you can glob like so. -->
3340
<None Include="some\specific\path\*.xyz" CopyToOutputDirectory="PreserveNewest"/>
3441
<None Include="some\specific\path\*.*" CopyToOutputDirectory="PreserveNewest"/>
3542
</ItemGroup>
3643
</Target>
44+
45+
<Target Name="CleanGeneratedCode" AfterTargets="CoreClean">
46+
<Delete Files="$(IntermediateOutputPath)GeneratedFile.cs" />
47+
</Target>
3748
```
3849

3950
Adding your generated file to `None` or `Content` is sufficient for the build process to see it. You also want to ensure it gets added at the right time. Ideally, your target runs before `BeforeBuild`. `AssignTargetPaths` is another possible target, as it is the final opportunity to modify `None` and `Content` items (among others) before they are transformed into new items. See [Common Item Types](common-msbuild-project-items.md).
4051

52+
Copy the above, paste it into a file, and call it `buildcodegen.targets`. Then, run `dotnet new console`, import the file, and build it to see how it works.
53+
54+
```xml
55+
<Project Sdk="Microsoft.NET.Sdk">
56+
<Import Project="buildcodegen.targets"/>
57+
<PropertyGroup>
58+
<OutputType>Exe</OutputType>
59+
<TargetFramework>net9.0</TargetFramework>
60+
<ImplicitUsings>enable</ImplicitUsings>
61+
<Nullable>enable</Nullable>
62+
</PropertyGroup>
63+
</Project>
64+
```
65+
66+
Run *msbuild.exe* and look at the output to verify that your file was generated and copied to the output folder. You can use *ildasm.exe* to confirm that your output binaries include the generated code `MyEnum`:
67+
68+
`ildasm CodeGen.dll`
69+
70+
## Next steps
71+
72+
This example could be improved to support more realistic use cases. For example, to support [incremental builds](./incremental-builds.md) when the generated code depends on an input file, `Inputs` and `Outputs` should be provided to the target. Such a target would only regenerate the file if the date of the input file or files is more recent than the output file. Often when customizing for code generation, it's recommended to create a custom task. See [Create a custom task for code generation](./tutorial-custom-task-code-generation.md).
73+
4174
## Related content
4275

4376
- [Customize your build](customize-your-build.md).

0 commit comments

Comments
 (0)