为不受支持的平台

时间:2016-07-26 18:13:52

标签: msbuild

我正在创建一个自定义的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>

当使用不支持的平台(例如Any CPU)构建项目时,我希望构建引发错误。我怎么能这样做?

我查看是否有办法在构建目标之外引发错误,但我无法找到错误。即使我找到了一个,我也会担心如果开发人员以某种方式让他们的系统选择一个不受支持的平台会发生什么。 (例如Visual Studio可能会开始拒绝打开项目。)

我可以覆盖BeforeBuild目标,但如果导入此文件的C#项目覆盖该目标本身,则会出现故障。 (或者我的会覆盖他们的,取决于Import<Target Name="BeforeBuild">的顺序。)在这种情况下,不会产生任何错误。这使得它相当脆弱而且不够稳健。

如何以一种用户不太可能破坏它的方式实现这一目标?或者是否有一种完全不同的替代方法我可以考虑有条件地包含二进制文件?

2 个答案:

答案 0 :(得分: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">

答案 1 :(得分:1)

我会使用带有Error任务的Target。但是如果你想避免使用自定义Target,你可以使用一个脏技巧来使构建突破属性,如果你只是定义一个肯定会失败的路径。

会是这样的:

tmp

构建将失败,因为这不是有效路径,并且虽然构建日志会令人困惑,但它将在文件未找到的内部包含此明确消息。 :)

同样,我建议定义目标......