2016-07-26 17 views
1

Importを複数のC#プロジェクトにするカスタムMSBuildスクリプトを作成しています。スクリプトは、Platformプロパティに基づいてコピーするいくつかのプロパティ、参照、およびファイルを追加して、最終出力がネイティブバイナリのセットを活用できるようにします。言い換えれば、適切なネイティブ・バイナリのセットとそのプラットフォームに基づく関連データを選択します。サポートされていないプラットフォームでエラーを発生させる

私は現在、このような何かをやっている:プロジェクトが(例えば、任意のCPUなど)未サポートのプラットフォームで構築されている場合

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

、私はビルドはエラーが発生します。これどうやってするの?

ビルドターゲットの外でエラーを発生させる方法があるか調べましたが、見つけられませんでした。私が見つけたとしても、開発者がどうにかしてサポートされていないプラットフォームを選んだら、どうなるのか心配です。

BeforeBuildターゲットをオーバーライドすることはできますが、このファイルをインポートするC#プロジェクトがそのターゲット自体をオーバーライドすると、これが壊れてしまいます(Visual Studioなどでプロジェクトを開くことが拒否される可能性があります)。 (Import<Target Name="BeforeBuild">の順番に応じて、自分自身をオーバーライドします)。その場合、エラーは発生しません。これはかなり壊れやすく、堅牢ではありません。

これをどのようにしてユーザーが壊れにくいようにすることができますか?あるいは、条件付きでバイナリを含めることができる、まったく異なる代替アプローチがありますか?

+0

だたぶん、あなたは 'のようなもの<ターゲット名= "MyPlatformCheck" BeforeTargets = "ビルド"/>'を探していますか?これはビルド前に実行され、組み込みのmsbuild機能とカスタム名を使用するので、オーバーライドするのが難しくなります。たとえば、より良いターゲットを使用することができます。 'PrepareBuild'かどうかはわかりませんが、私は頭の上からそれらを知らないのです。 – stijn

+0

@stijnビルドを行うことが可能であるかどうかはわかりませんでした。それを答えにすることができれば、私はそれを受け入れます。 – jpmc26

答えて

2

をお勧めします。したがって、必要なすべてのロジックを持つカスタムターゲットを作成し、それを自動的に呼び出すようにします。これはまた、ユーザーがそれを壊すのを難しくします。

BeforeTargetsを使用している場合は、ビルドの初期段階で呼び出されたターゲットを見つけて、ビルドとクリーンの両方で優先的に呼び出すことをお勧めします。最も簡単な方法を理解するには、診断ログ(コマンドラインにmsbuild /v:d myproject)を使用してプロジェクトを構築します。プラットフォームの妥当性をチェックする唯一の人ではないことがわかります.C++プロジェクトの最初のターゲットは、Microsoft自身の_CheckForInvalidConfigurationAndPlatformです。したがって、使用する場合は、

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

となります。次に、PlatformCheckは、呼び出される最初のターゲットの1つになります。

それとも、他の方法を好む場合、それは

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

MSBuildの新しいバージョンのタスクリストは、https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-task-referenceにあります。私は 'AssignProjectConfiguration'を使って終わりました。 「ビルド」に依存しようとする試みは、プロセスでは遅すぎた。それ以前に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> 

見つかりませんでした。 :)

繰り返しますが、私は慣用的な方法は、Target elementBeforeTargets属性を使用するか、またはProject elementInitialTargets属性を使用することです...ターゲットを定義

関連する問題