2016-07-26 43 views
1

我正在創建一個自定義的MSBuild腳本,該腳本旨在將Import編輯到多個C#項目中。該腳本根據Platform屬性添加了要複製的多個屬性,引用和文件,以使最終輸出能夠利用一組本機二進制文件。換句話說,它會根據平臺選擇正確的本機二進制文件和相關數據。爲不支持的平臺引發錯誤

目前,我正在做這樣的事情:

<PropertyGroup Condition="'$(Platform)' == 'x86'"> 
    <bin1>..\..\lib\mybinaries\x86\bin1.dll</bin1> 
    <bin2>..\..\lib\mybinaries\x86\bin2.dll</bin2> 
</PropertyGroup> 
<PropertyGroup Condition="'$(Platform)' == 'x64'"> 
    <bin1>..\..\lib\mybinaries\x64\bin1.dll</bin1> 
    <bin2>..\..\lib\mybinaries\x64\bin2.dll</bin2> 
</PropertyGroup> 

<ItemGroup> 
    <Reference Include="bin2.dll"> 
    <SpecificVersion>False</SpecificVersion> 
    <HintPath>$(bin2)</HintPath> 
    <Private>True</Private> 
    </Reference> 
</ItemGroup> 
<ItemGroup> 
    <None Include="$(bin1)"> 
    <CopyToOutputDirectory>Always</CopyToOutputDirectory> 
    </None> 
</ItemGroup> 

當一個項目內建有UNSUPPORT平臺(如任何CPU),我想構建引發錯誤。我怎樣才能做到這一點?

我調查了一下,看看是否有辦法在構建目標之外引發錯誤,但我無法找到它。即使我確實找到了一個,我也會擔心如果開發者以某種方式讓他們的系統選擇了不受支持的平臺,會發生什麼。 (例如Visual Studio可能會開始拒絕打開該項目。)

我可以覆蓋BeforeBuild目標,但如果導入此文件的C#項目會覆蓋該目標本身,則會崩潰。 (或者我的會覆蓋他們的,這取決於Import<Target Name="BeforeBuild">的順序。)在這種情況下,不會引發錯誤。這使得它非常脆弱,而且不夠健壯。

我該如何做到這一點,使用戶不可能打破它?還是有一個完全不同的替代方法,我可以考慮包括有條件的二進制文件?

+0

也許你正在尋找類似'<目標名稱= 「MyPlatformCheck」 BeforeTargets = 「生成」/>'?這將在構建之前運行,並使用內置的msbuild功能和自定義名稱,因此很難覆蓋。可能有更好的目標可以使用,例如'PrepareBuild'左右,但我不知道從頭頂上的那些人。 – stijn

+0

@stijn我沒有意識到有可能讓Build取決於自定義任務。如果你能把它變成答案,我會接受它。 – jpmc26

回答

2

一種慣用的方法是要麼使用Target elementBeforeTargets屬性,或使用Project elementInitialTargets屬性。因此,您可以使用所需的所有邏輯編寫自定義目標,然後自動調用它。這也使得用戶難以打破它。

如果您使用BeforeTargets,您會希望找到一個在構建中提前調用的目標,最好是Build和Clean。要弄清楚最簡單的方法是使用診斷日誌(命令行中的msbuild /v:d myproject)構建項目。然後你會看到你不是唯一想要檢查平臺有效性的人:第一個要求C++項目的目標是微軟自己的_CheckForInvalidConfigurationAndPlatform。所以,如果你使用

<Target Name="PlatformCheck" BeforeTargets="_CheckForInvalidConfigurationAndPlatform"> 
    <Error Text="Bad Platform" Condition="'$(bin1)' == ''"/> 
</Target> 

然後PlatformCheck將成爲第一個被稱爲的目標之一。

或者,如果你喜歡的另一種方式,那麼它的

<Project ToolsVersion="4.0" xmlns="..." InitialTargets="PlatformCheck"> 
+0

更新版本的MSBuild的任務列表可以在這裏找到:https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-task-reference。我結束了使用'AssignProjectConfiguration'。嘗試依賴'Build'在這個過程中太遲了;你會在這之前丟失DLL錯誤。 – jpmc26

1

我會用一個帶有錯誤任務的目標。但是如果你想避免擁有一個自定義的Target,你可以使用一個骯髒的技巧來讓構建突破一個屬性,如果你只是定義一個肯定會失敗的路徑。

這將是類似的東西:

<PropertyGroup Condition="'$(Platform)' == 'x86'"> 
    <bin1>..\..\lib\mybinaries\x86\bin1.dll</bin1> 
    <bin2>..\..\lib\mybinaries\x86\bin2.dll</bin2> 
</PropertyGroup> 
<PropertyGroup Condition="'$(Platform)' == 'x64'"> 
    <bin1>..\..\lib\mybinaries\x64\bin1.dll</bin1> 
    <bin2>..\..\lib\mybinaries\x64\bin2.dll</bin2> 
</PropertyGroup> 
<PropertyGroup Condition="'$(bin1)' == ''"> 
    <bin1>ERROR: platform '$(Platform)' is not supported, please set it to x86 or x64</bin1> 
</PropertyGroup> 

構建將失敗,因爲這不是一個有效的路徑,並同時生成日誌將是混亂的,它將包含的文件 - 這裏面明確信息未找到。 :)

同樣,我建議你定義一個目標......