将构建标识为由于依赖项目引用而引起的

时间:2017-09-30 21:48:36

标签: msbuild

在MSBuild中是否有一个属性或其他机制,表明正在构建当前项目,因为它是另一个项目引用的?

2 个答案:

答案 0 :(得分:1)

除了@stijn的回答之外,我发现你还可以阻止将属性传递给依赖项目。

例如,您可以通过将<ProjectReference>更新为包含<GlobalPropertiesToRemove>DeployOnBuild</GlobalPropertiesToRemove>来阻止Web项目依赖项与顶级项目一起构建。或者,根据另一个属性自动执行:

<PropertyGroup Condition="'$(DisableProjectReferenceDeployOnBuild)'=='true'">
  <BeforeResolveReferences>
    $(BeforeResolveReferences);
    DisableProjectReferenceDeployOnBuild
  </BeforeResolveReferences>
</PropertyGroup>

<Target Name="DisableProjectReferenceDeployOnBuild">
  <ItemGroup>
    <_ProjectReferencesTmp Include="@(ProjectReferences)" />
    <ProjectReferences Remove="@(ProjectReferences)" />
    <ProjectReferences Include="@(_ProjectReferencesTmp)">
      <GlobalPropertiesToRemove>%(GlobalPropertiesToRemove);DeployOnBuild</GlobalPropertiesToRemove>
    </ProjectReferences>
  </ItemGroup>
</Target>

(我不会将此标记为答案,因为它没有直接回答我提出的问题)

答案 1 :(得分:1)

在环顾四周之后,使用内置功能似乎无法做到这一点。从一个角度来看,这是有道理的:为什么项目必须知道它是由用户直接构建还是构建为依赖项?可能MSBuild团队也遵循这个逻辑:MSBuild中有很多扩展点但不是这样做的。

两个问题:构建依赖项目的代码只是使用MSBuild任务,并没有提供传递属性的方法。但即使它确实如此,它只能在从命令行构建时才能工作,而不是在VS中,所以它不是一个完整的&#39;解。这是一个摘自ResolveProjectReferences的片段,用于构建依赖项目:

<!--
    Build referenced projects when building from the command line.
    -->
<MSBuild
    Projects="@(_MSBuildProjectReferenceExistent)"
    Targets="%(_MSBuildProjectReferenceExistent.Targets)"
    BuildInParallel="$(BuildInParallel)"
    Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration); %(_MSBuildProjectReferenceExistent.SetPlatform)"
    Condition="'%(_MSBuildProjectReferenceExistent.BuildReference)' == 'true' and '@(ProjectReferenceWithConfiguration)' != '' and '$(BuildingInsideVisualStudio)' != 'true' and '$(BuildProjectReferences)' == 'true' and '@(_MSBuildProjectReferenceExistent)' != ''"
    ContinueOnError="$(ContinueOnError)"
    RemoveProperties="%(_MSBuildProjectReferenceExistent.GlobalPropertiesToRemove)">
  ...
</MSBuild>

所以,没办法在这里添加属性。虽然如您所知,您可以通过设置ProjectReference的GlobalPropertiesToRemove来删除属性;取决于你在此之后的价值是多少。

剩下的还有很多选择;您可以指定使用的目标:_MSBuildProjectReferenceExistent.Targets设置为$(ProjectReferenceBuildTargets),以便您可以覆盖调用的目标,但是您需要所有可能是依赖项目的项目来声明自定义目标(将在转而调用Build目标,以免破坏事物。可行但不好,而不是问题的直接答案。其他解决方案也是如此:您可以通过复制它并在上面显示的代码段中添加属性来覆盖整个ResolveProjectReferences目标(对于任何可以拥有依赖项目的项目)。

但是如上所述(以及上面代码段中的条件所示):在VS中构建时,这些可能的解决方案都不适用。我不确切知道为什么或如何运作,但是如果A依赖于B并且你在VS中构建A并且它看到B已经过时它甚至会在构建A之前启动它的构建并且我不会# 39;不知道与之互动的任何标准方式。