这似乎是一个显而易见的事情,但是我已经把大部分头发都拉出来试图在网上找到任何例子或自己做.
我有19个项目的ac#解决方案和运行构建脚本的Jenkins构建服务器来驱动MSBuild.MSBuild当然会根据输入与输出确定需要编译和不需要编译的内容.
我正在尝试创建一个自定义目标来有条件地更新MSBuild将要编译的那些项目的AssemblyInfo.cs以增加文件版本.当然,我想让这些项目不是单独编译的.
我知道如何在每次运行的CoreBuild之前注入一个目标,所以如果有一些变量我可以测试一下是否会发生可以工作的编译.我也知道如何确定编译是否运行,因此有条件地进行一些可能但不理想的后处理.
我如何调整构建过程来实现这一目标?
由于似乎没有直接回答这个问题,有没有人知道如何执行与MSBuild相同的逻辑来确定哪些项目需要重建?
Aku*_*uma 11
最后,解决方案是Sayed Ibrahim Hashimi的博客条目和来自MSDN论坛条目的信息'执行目标时(核心)编译将执行'的组合.
我基本上采用Sayed的注入方法让我的目标在所有项目上运行'extend-corecompile.proj',而不必编辑每个proj文件,而是用'CoreCompileDependsOn'的覆盖替换它的内容,指向采用相同的自定义目标输入和输出作为'CoreCompile'目标.最终结果是一个目标,只有当'CoreCompile'在构建脚本中集中管理时才会运行.
感谢他们的所有输入,这是我在'extend-corecompile.proj'中使用的框架代码:
<!--The following property group adds our custom post-target to the post compile call list -->
<PropertyGroup>
    <TargetsTriggeredByCompilation>
        $(TargetsTriggeredByCompilation);
        CustomPostTarget
    </TargetsTriggeredByCompilation>
</PropertyGroup>
<!--The following property group adds our custom pre-target to CoreCompileDependsOn to ensure it is called before CoreCompile -->
<PropertyGroup>
    <CoreCompileDependsOn>
        $(CoreCompileDependsOn);
        CustomPreTarget
    </CoreCompileDependsOn>
</PropertyGroup>
<!-- The following custom pre-target has the same inputs and outputs as CoreCompile so that it will only run when CoreCompile runs.
    Because we have injected this file and Targets are resolved in sequence we know this Target will fire before CoreCompile.-->
<Target Name="CustomPreTarget" 
    Inputs="$(MSBuildAllProjects);
            @(Compile);                               
            @(_CoreCompileResourceInputs);
            $(ApplicationIcon);
            $(AssemblyOriginatorKeyFile);
            @(ReferencePath);
            @(CompiledLicenseFile);
            @(EmbeddedDocumentation); 
            $(Win32Resource);
            $(Win32Manifest);
            @(CustomAdditionalCompileInputs)"
    Outputs="@(DocFileItem);
             @(IntermediateAssembly);
             @(_DebugSymbolsIntermediatePath);                 
             $(NonExistentFile);
             @(CustomAdditionalCompileOutputs)">
    <!--Do pre-compilation processing here-->
</Target>
<!--This target will be called by CoreCompile-->
<Target Name="CustomPostTarget" >
    <!--Do post-compilation processing here-->
</Target>
不确定如果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目标文件中捕获的.如果您查看该文件,您会在顶部看到一个类似下面的导入.
<Import Project="$(CustomBeforeMicrosoftCommonTargets)" Condition="'$(CustomBeforeMicrosoftCommonTargets)' != '' and Exists('$(CustomBeforeMicrosoftCommonTargets)')"/>
如果属性不为空且文件存在,则此语句将导入文件(位于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的全部内容.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <FileToInject Condition=" '$(FileToInject)'=='' ">$(MSBuildThisFileDirectory)extend-corecompile.proj</FileToInject>
  </PropertyGroup>
  <ItemGroup>
    <ProjectsToBuild Include="ProjA\ProjA.csproj"/>
    <ProjectsToBuild Include="ProjB\ProjB.csproj"/>
  </ItemGroup>
  <Target Name="Build">
    <MSBuild Projects="@(ProjectsToBuild)"
             Properties="CustomBeforeMicrosoftCommonTargets=$(FileToInject)" />   
  </Target>
  <Target Name="Clean">
    <MSBuild Projects="@(ProjectsToBuild)" Targets="Clean"/>
  </Target>
  <Target Name="Rebuild" DependsOnTargets="Clean;Build"/>
</Project>
在上面的Build目标中,我使用MSBuild任务来构建ProjA和ProjB.正如您所看到的,我正在传递属性CustomBeforeMicrosoftCommonTargets = $(FileToInject),它指向extend-corecompile.proj.通过在构建ProjA和ProjB时传递此属性,它将自动导入构建过程的extend-corecompile.proj文件.您可以在下面看到extend-corecompile.proj的内容.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <TargetsTriggeredByCompilation>
      $(TargetsTriggeredByCompilation);
      MyCustomTarget
    </TargetsTriggeredByCompilation>
  </PropertyGroup>
  <Target Name="MyCustomTarget">
    <Message Text="MyCustomTarget called" Importance ="high"/>
  </Target>
</Project>
此项目文件使用我之前博客文章中概述的技术,仅在执行CoreCompile时才执行MyCustomTarget.
注意:您可以访问https://github.com/sayedihashimi/sayed-samples/tree/master/ExtBuildMultiple获取此示例的最新版本.
| 归档时间: | 
 | 
| 查看次数: | 7249 次 | 
| 最近记录: |