2017-09-30 42 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> 

(我不會紀念這個作爲回答,因爲它沒有直接回答我問的問題)