确定MSBuild CoreCompile是否将运行并调用自定义目标

这似乎是一个显而易见的事情,但是我已经把大部分头发都拉出来试图在网上找到任何例子或自己做。

我有19个项目的ac#解决方案和运行构建脚本的Jenkins构建服务器来驱动MSBuild。 MSBuild当然会根据输入与输出确定需要编译和不需要编译的内容。

我正在尝试创建一个自定义目标来有条件地更新MSBuild将要编译的那些项目的AssemblyInfo.cs以增加文件版本。 当然,我想让项目不是单独编译的。

我知道如何在每次运行的CoreBuild之前注入一个目标,所以如果有一些变量,我可以测试一下是否会发生可以工作的编译。 我也知道如何确定编译是否运行,因此有条件地进行一些可能但不理想的后期处理。

我如何调整构建过程来实现这一目标?

由于似乎没有直接回答这个问题,有没有人知道如何执行与MSBuild相同的逻辑来确定哪些项目需要重建?

最后,该解决方案结合了Sayed Ibrahim Hashimi的博客条目和来自MSDN论坛条目的信息’执行目标(核心)编译将执行’ 。

我基本上采用Sayed的注入方法让我的目标在所有项目上运行’extend-corecompile.proj’,而不必编辑每个proj文件,但用’CoreCompileDependsOn’的覆盖替换它的内容,指向采用相同的自定义目标输入和输出作为’CoreCompile’目标。 最终结果是仅在“CoreCompile”运行时运行的目标,而在构建脚本中进行集中管理。

感谢他们的所有输入,这里是我在’extend-corecompile.proj’中使用的框架代码:

   $(TargetsTriggeredByCompilation); CustomPostTarget      $(CoreCompileDependsOn); CustomPreTarget           

不确定如果CoreCompile失败会发生什么,它仍然会调用我们的目标吗? 我想及时我们会发现:)

我刚刚在http://sedodream.com/2012/07/28/MSBuildHowToExecuteATargetAfterCoreCompilePart2.aspx上写了这个答案,但我已经为你粘贴了解决方案。

几个月前,我写了一篇博客文章MSBuild如何在CoreCompile之后执行一个目标 ,其中我描述了如果执行CoreCompile目标你如何执行目标,如果跳过CoreCompile那么你的另一个目标也是如此。 我在上一篇文章中概述的方法的缺点是它需要您编辑.csproj / .vbproj / etc文件本身。 因此,如果您有一个构建多个项目的场景,则必须编辑所有项目文件。 在这篇文章中,我将描述如何执行相同的自定义而无需编辑项目文件本身。

在我们找到针对这个特定案例的解决方案之前,让我描述一下C#和VB项目所具有的可扩展性钩子。 构建C#和VB项目的大多数逻辑都是在C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Microsoft.Common.targets的MSBuild目标文件中捕获的。 如果您查看该文件,您会在顶部看到一个类似下面的导入。

  

如果属性不为空且文件存在,则此语句将导入文件(位于CustomBeforeMicrosoftCommonTargets的值)。 CustomBeforeMicrosoftCommonTargets的默认值为C:\ Program Files(x86)\ MSBuild \ v4.0 \ Custom.Before.Microsoft.Common.targets。 因此,如果您在该位置删除MSBuild文件,它将修改在该计算机上构建的每个C#/ VB项目的构建过程。 或者,如果您不想(或不能由于ACL),则可以将文件放在其他位置,然后通过重写CustomBeforeMicrosoftCommonTargets属性来指定其位置。 这是我将采取的方法。 我创建了一个示例解决方案,它包含两个项目ProjA和ProjB。 我还有一个构建脚本build.proj,用于自动化构建。 以下是build.proj的全部内容。

build.proj

    $(MSBuildThisFileDirectory)extend-corecompile.proj              

在上面的Build目标中,我使用MSBuild任务来构建ProjA和ProjB。 正如您所看到的,我正在传递属性CustomBeforeMicrosoftCommonTargets = $(FileToInject),它指向extend-corecompile.proj。 通过在构建ProjA和ProjB时传递此属性,它将自动导入构建过程的extend-corecompile.proj文件。 您可以在下面看到extend-corecompile.proj的内容。

延长-corecompile.proj

     $(TargetsTriggeredByCompilation); MyCustomTarget       

此项目文件使用我之前博客文章中概述的技术,仅在执行CoreCompile时才执行MyCustomTarget。

注意:您可以访问https://github.com/sayedihashimi/sayed-samples/tree/master/ExtBuildMultiple获取此示例的最新版本。

或者,您可以使用由所有项目引用的单个自动生成的VersionInfo.cs文件。 要使用此技术,请从项目的AssemblyInfo.cs文件中删除版本,公司信息等属性(是的,这很痛苦,但您只需要执行此操作一次),并使用批处理命令吐出一个VersionInfo.cs文件基于模板。 要在Visual Studio中引用公共文件,请从项目上下文菜单中选择“添加现有项”,然后在文件浏览器中导航到VersionInfo.cs文件后,单击“添加”旁边的下拉箭头,然后选择“添加为”。链接。

以下是我使用的一个示例。 此脚本将检入我们的SCC系统,并在构建开始时执行,为脚本提供%BUILD_NUMBER%。

 SET BUILD=%1 @echo using System.Reflection; > "%~p0Version.cs" @echo [assembly: AssemblyCompany("MyCompany, Inc.")] >> "%~p0Version.cs" @echo [assembly: AssemblyProduct("MyProduct")] >> "%~p0Version.cs" @echo [assembly: AssemblyCopyright("Copyright © 2012 MyCompany, Inc.")] >> "%~p0Version.cs" @echo [assembly: AssemblyTrademark("")]@echo [assembly: AssemblyVersion("1.0.%BUILD%.0")] >> "%~p0Version.cs" @echo [assembly: AssemblyFileVersion("1.0.%BUILD%.0")] >> "%~p0Version.cs" @echo ^ > "%~p0Version.wxi" @echo ^ >> "%~p0Version.wxi" @echo ^ >> "%~p0\Version.wxi" 

即使您获得了需要编译的项目列表,如果更新其中一个项目的assemblyinfo.cs,也可能会导致更改触发另一个项目的编译。

因此,最简单的方法是根据源代码控制版本号生成所有AssemblyInfo.cs文件。 您甚至可以获得每个项目目录的最新版本号,有效地了解该项目的“最后”修改时间。

看到这个问题: 如何使用MSBuild更改AssemblyProduct,AssemblyTitle?

根据您的评论,您是否查看过BeforeBuild和AfterBuild目标(在csproj文件的末尾):