我在 .csproj 中有这样的部分:
<Target Name="Date" BeforeTargets="BeforeBuild">
<WriteLinesToFile File="$(IntermediateOutputPath)BuildInfo.gen.cs"
Lines="...."/>
</Target>
<ItemGroup>
<Compile Include="$(IntermediateOutputPath)BuildInfo.gen.cs"
Condition="Exists('$(IntermediateOutputPath)BuildInfo.gen.cs')"/>
</ItemGroup>
IntermediateOutputPath
正如预期的那样解决了,一切都很好。但由于整个路径在我的 .csproj 中重复了 3 次,我想清理它并提出自定义变量:
<PropertyGroup>
<BuildInfoPath>$(IntermediateOutputPath)BuildInfo.gen.cs</BuildInfoPath>
</PropertyGroup>
<Target Name="Date" BeforeTargets="BeforeBuild">
<WriteLinesToFile File="$(BuildInfoPath)" Lines="...."/>
</Target>
<ItemGroup>
<Compile Include="$(BuildInfoPath)"
Condition="Exists('$(BuildInfoPath)')"/>
</ItemGroup>
我的变量已解析,但其内容不完全正确 - 我的效果就像IntermediateOutputPath
是一个空字符串。
那么我如何定义自己的变量引用IntermediateOutputPath
呢?
我已经发现,如果我将变量定义包装在其中,Target
它将部分起作用——即Target
上面所示的部分将获得正确的变量,但反过来ItemGroup
我的变量将为空。
MSBuild 有两个阶段:评估和执行。请参阅“ MSBuild 如何构建项目”。在评估阶段评估“顶层”的元素,即文档根元素的直接子元素
ItemGroup
。a 中的元素在执行阶段进行评估。PropertyGroup
Project
ItemGroup
PropertyGroup
Target
我假设这是一个SDK 风格的项目。在后台,根据 SDK 类型导入一组文件。有些文件是在 .csproj 项目文件内容之前导入的,有些文件是在 .csproj 项目文件内容之后导入的。该
IntermediateOutputPath
属性是在评估阶段定义的,但在 .csproj 内容之后导入的文件中定义。在评估阶段的项目文件内容中,该属性尚未定义,并且在定义之前使用该属性会生成一个空字符串 - 正如您所观察到的。
在 SDK 样式项目中,仅使用
IntermediateOutputPath
目标内的属性。您仍然可以定义自己的属性和依赖项,
IntermediateOutputPath
但需要将定义包装在目标中,并确保在使用值之前执行定义,例如: