2017-09-30 51 views
1

在MSBuild中是否有一个属性或其他一些机制,指示当前项目正在构建,因为它是另一个项目引用的?确定构建是由于依赖项目引用造成的

+1

取决于你对“正在建造”的定义是什么。当项目A有一个对项目B的引用时,msbuild实际上在项目B上被多次调用,具有不同的目标。对于实际的构建目标,没有办法将其与正常构建区分开来(至少在我使用标准VS生成的项目文件时没有人知道:查看诊断构建输出一切都完全相同)。对于其他目标(GetNativeManifest,GetCopyToOutputDirectoryItems),您可能会认为只有在项目正在构建时才会调用它,因为它是被引用的。 – stijn

+0

@stijn谢谢,这确实是我之后的构建目标,但很高兴知道。如果你添加这个答案,我会接受它。 –

+0

@stijn出于兴趣。您是否可以让一个附加属性传递给依赖项目而不将相同属性传递给入口项目?(例如,通过将某些元数据添加到某个项目中) –

回答

1

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

两个问题:构建依赖项目的代码只是使用MSBuild任务,并没有提供传递属性的方法。但即使这样做,它只会在从命令行构建时才起作用,而不是在VS中构建,因此它不是一个“完整的”解决方案。以下是从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),这样你就可以覆盖被调用的目标,但是你需要所有可能依赖项目的项目来声明一个自定义目标(这又会调用建立目标以及为了不破坏的东西)。可行,但不好,而不是对问题的直接回答。其他解决方案也是如此:通过复制它并在上面显示的代码片段中添加一个属性,您可以覆盖整个ResolveProjectReferences目标(对于任何可能具有相关项目的项目)。

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

1

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

例如,您可以通过更新<ProjectReference>以包含<GlobalPropertiesToRemove>DeployOnBuild</GlobalPropertiesToRemove>来防止使用顶级项目构建Web Project依赖项。或者,基于另一个属性自动做到这一点:

<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> 

(我不会纪念这个作为回答,因为它没有直接回答我问的问题)