自定义生成

使用标准生成进程(导入 Microsoft.Common.props 和 Microsoft.Common.targets)的 MSBuild 项目有多个可用于自定义生成过程的扩展性挂钩 。

许多可自定义的生成操作由属性控制。 了解如何以及在何处设置属性值以获得所需的效果非常重要。 可以在命令行(和响应文件)、特殊文件(如 Directory.Build.props)、导入的文件或项目文件中设置属性。 了解属性的使用、设置或更改位置以及导入文件的顺序(包括从诸如 .NET SDK 之类的 SDK 隐式导入)非常重要。

有关属性的列表,请参阅 MSBuild 通用属性

探索自定义选项

以下自定义选项按复杂性和影响范围的增加的顺序列出。 我们建议使用最不复杂的自定义选项,从此列表的顶部开始,以满足你的目的。

自定义选项 说明
将参数添加到 MSBuild 命令行 设置影响主项目生成和所有依赖项目的生成的全局属性。
自定义单个项目的生成 将属性添加到 .props.targets 文件以自定义生成设置。
处理生成过程中生成的文件 如何确保生成的文件正确包含在生成输出中。
自定义一个或多个项目的生成 将属性添加到 Directory.Build.props 或将属性和目标添加到 Directory.Build.targets,以自定义文件夹下所有项目的生成。 此方法可用于设置 SDK 设置或使用的属性,以及确定自定义项的范围,以便它们影响文件夹或子文件夹中的所有项目。
自定义本地生成 仅在本地计算机上更改生成,而不影响共享的源文件。
自定义所有 .NET 生成 为 .NET 生成自定义具有系统范围的生成。
自定义 C++ 生成 自定义 C++ 生成,其范围限定为项目、解决方案、文件夹或由系统上的 MSBuild 安装管理的所有生成。

向项目的命令行 MSBuild 调用添加参数

可以在命令行上设置全局属性。 全局属性影响所有项目生成,包括依赖项。 回想一下,生成项目会自动触发所有项目依赖项的可能生成。 MSBuild 的正常行为是生成任何过期的依赖项目。 这些依赖项目生成使用与原始项目相同的命令行全局属性设置启动。

源目录中或之上的 Directory.Build.rsp 文件会应用到项目的命令行生成。 有关详细信息,请参阅 MSBuild 响应文件

选择将属性添加到 .props.targets 文件

MSBuild 依赖于导入顺序,属性(或 UsingTask 或目标)的最后一个定义是使用的定义。

使用显式导入时,可以随时从 .props.targets 文件导入。 下面介绍广泛使用的约定:

  • .props 文件在导入顺序的早期导入。

  • .targets 文件在生成顺序的后期导入。

此约定由 <Project Sdk="SdkName"> 导入强制执行(即,在文件的所有内容之前首先导入 Sdk.props,然后在文件的所有内容之后最后导入 Sdk.targets)。

在决定在何处放置属性后,使用以下通用原则:

  • 对于许多属性,在何处定义它们并不重要,因为它们不会被覆盖,只能在执行时读取。

  • 对于可能在单个项目中自定义的行为,请在 .props 文件中设置默认值。

  • 通过读取可能自定义属性的值,避免在 .props 文件中设置依赖属性,因为在 MSBuild 读取用户项目之前不会进行自定义。

  • .targets 文件中设置依赖属性,因为它们将从单个项目中提取自定义项。

  • 如果需要覆盖属性,请在所有用户项目自定义项生效后,在 .targets 文件中执行此操作。 使用派生属性时务必小心;还可能需要覆盖派生属性。

  • 包括 .props 文件中的项目(以属性为条件)。 在任何项目之前都要考虑所有属性,因此可以提取用户项目属性自定义项,在 .props 文件中添加导入的项使用户的项目有机会 RemoveUpdate 导入所引入的任何项目。

  • 定义 .targets 文件中的目标。 但是,如果 SDK 导入了 .targets 文件,请记住此方案使得覆盖目标更加困难,因为默认情况下用户的项目没有可以覆盖它的地方。

  • 如果可能,宁可在评估时自定义属性,也不更改目标内的属性。 此原则可以更轻松地加载项目并了解正在执行的操作。