我正在向我的项目中添加一个自定义.tt
模板生成目标,以便在CoreBuild
之前运行,其中有两种方法:
<Project...>
<Target Name="TransformOnBuild" AfterTargets="BeforeBuild">
</Project>
和
<Project...>
<Target Name="TransformOnBuild" BeforeTargets="CoreBuild">
</Project>
如果我的目标应该在我的项目构建之前运行,因为项目依赖于它,那么对我来说使用后者更好吗?我见过前者曾经做过像生成文本模板这样的事情,但是这似乎是一种不可靠的方法,因为它可能会在CoreBuild
之后运行,这太迟了。或者有什么原因可以解释为什么在核心构建之前仍然保证运行AfterTargets="BeforeBuild"
呢?
我还看到了BeforeTargets="BeforeBuild"
,它将在更早的时候构建。这是放置`.tt文本生成目标的更好地方吗?
发布于 2017-05-18 03:13:36
在@stjin回答的基础上,一个好的解决方案似乎正在使用
BeforeTargets="CoreCompile" DependsOnTargets="PrepareForBuild"
这就是.net sdk (用于.net核心/标准项目的新风格的csproj ) 是用于自动生成AssemblyInfo.cs的。
它使用以下注释来解释原因:
注意,这必须在每次调用CoreCompile之前运行,以确保所有编译器运行时都能看到生成的程序集信息。至少有一种涉及Xaml的场景,其中调用CoreCompile时没有其他潜在的钩子,如编译或CoreBuild等,因此我们直接连接到CoreCompile。此外,我们必须在PrepareForBuild之后运行,以确保创建了中间目录。
请注意,“中间目录”(在本例中为obj/[TargetFramework]
)是将输出.cs
文件放在这里的地方,这也可能是您想要做的。
发布于 2017-05-18 07:52:15
更新2
这是目标构建顺序
以下是你的问题的答案:
如果我的目标应该在我的项目构建之前运行,因为该项目依赖它,那么使用后者更好吗?
还是AfterTargets="BeforeBuild“仍然保证在核心构建之前运行的原因?
我还看到了BeforeTargets="BeforeBuild" ,它将在更早的时候构建。这是放置`.tt文本生成目标的更好地方吗?
在CoreBuild?之前运行目标
> there appear to be 2 ways of doing it.
There are more options to achieve this. Please review below.
为此,您应该使用特定的内置目标(BeforeBuild或AfterBuild)。这是Microsoft在使用依赖于安全地扩展构建过程的项目时向Microsoft.Common.targets提供的机制。
如果在CoreBuild之前只有一个目标要运行,则可以这样做:
<Target Name="BeforeBuild">
<!-- add your tasks here -->
</Target>
如果要在CoreBuild之前运行多个目标,则可以定义一个属性,其中包含需要按所需执行顺序调用的所有目标:
<PropertyGroup>
<BeforeBuildDependsOn>
CustomTarget1;
CustomTarget2;
CustomTarget3
</BeforeBuildDependsOn>
</PropertyGroup>
<Target Name="BeforeBuild" DependsOnTargets="$(BeforeBuildDependsOn)"/>
更新:
基于@stijn提供的片段:
AfterTargets=" BeforeBuild“将插入/执行如下自定义目标:(取决于BeforeBuild)
<BuildDependsOn>
BeforeBuild;
|-> Custom Target
CoreBuild;
AfterBuild
</BuildDependsOn>
BeforeTargets="CoreBuild“将像这样插入/执行自定义(取决于CoreBuild):
<BuildDependsOn>
BeforeBuild;
|-> Custom Target
CoreBuild;
AfterBuild
</BuildDependsOn>
因此,“模板生成目标”将在相同的位置(在BeforeBuild和CoreBuild之间)执行,但取决于不同的目标,这就是为什么要使用的A固有目标应该是BeforeBuild内联或依赖项。
现在关于第三方问题的评论,BeforeBuild/AfterBuild目标是针对最终用户的,第三方提供者应该在不影响基本工作流程的情况下实现他们的脚本。以下是第三方应该使用的一些选项,以避免打破常规流:
考虑到这一点为基础:
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
<Target Name="Build" DependsOnTargets="$(BuildDependsOn)"/>
选项1: --这将在BeforeBuild之前注入您的自定义第三方脚本,而不会影响默认的BuildDependsOn序列,这仍然允许最终用户不使用BeforeBuild目标。
<PropertyGroup>
<BuildDependsOn>
MyCustomThirdParty;
$(BuildDependsOn);
</BuildDependsOn>
</PropertyGroup>
<PropertyGroup>
<MyCustomThirdPartyDependsOn>
BeforeMyCustomThirdParty;
CustomStep1;
CustomStep2;
CustomStep1;
AfterMyCustomThirdParty
</MyCustomThirdPartyDependsOn>
</PropertyGroup>
<Target Name="MyCustomThirdParty" DependsOnTargets="$(MyCustomThirdPartyDependsOn)"/>
选项2:如果需要在BeforeBuild目标之后执行第三方脚本,可以这样做:
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
MyCustomThirdParty;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
注意:为了使其正常工作,必须在PropertyGroup导入之后添加Microsoft.CSharp.targets和目标。
这样,您将能够使用多个第三方脚本,尊重一般的工作流程。
显然,您可以根据情况使用这些选项的组合。但你应该遵循以下一般规则:
在使用默认的visual生成的构建脚本(如.csproj、.vbproj等项目)时,应该考虑这些因素。如果您正在为其他语言或目的实现您自己的脚本,您可以在任何地方使用BeforeTargets和AfterTargets,但是为什么不遵循基于现有脚本的良好实践呢?
发布于 2017-05-18 02:37:55
在Microsoft.Common.CurrentVersion.targets中,构建目标基本上是:
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
<Target Name="Build" DependsOnTargets="$(BuildDependsOn)"/>
<PropertyGroup>
<CoreBuildDependsOn>
PrepareForBuild;
PreBuildEvent;
...
Compile;
...
PostBuildEvent
</CoreBuildDependsOn>
</PropertyGroup>
<Target Name="CoreBuild" DependsOnTargets="$(CoreBuildDependsOn)">
因此,使用BeforeTargets="CoreBuild"
确实会在CoreBuild之前运行,但毕竟它的依赖目标运行,所以在所有实际的构建步骤之后。这通常不是您想要的,相反,如果您想在编译之前运行一些东西等等,请使用BeforeTargets="PrepareForBuild"
,甚至AfterTargets="BeforeBuild"
,甚至BeforeTargets="BeforeBuild"
。
https://stackoverflow.com/questions/44043918
复制相似问题