【问题标题】:Using msbuild.exe to build a project with a dependency requiring a different Platform property使用 msbuild.exe 构建具有需要不同平台属性的依赖项的项目
【发布时间】:2017-10-05 13:38:58
【问题描述】:

我有两个相当简单的 C# 项目:一个可以构建为 x86 或 AnyCPU 的可执行文件,它引用(通过<ProjectReference>)一个只有 AnyCPU 配置的 DLL 项目。这一切都在 Visual Studio 中按预期工作。

我正在尝试使用/p:Platform="x86" 从命令行构建可执行项目的 x86 版本(及其依赖项)。这会导致 DLL 项目的生成失败。 (而/p:Platform="AnyCPU" 有效,大概是因为它对两个项目都有效。)

我使用的完整命令行是:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild MyProject\MyProject.csproj /t:Build /p:Configuration="Release" /p:Platform="x86"

我有哪些选择可以让这个构建从命令行运行?最好完全不修改 DLL 项目,或者以干扰在 Visual Studio 中正常使用它们的方式修改项目。

(这里的最终目标是一个批处理文件,可以构建项目的干净版本以进行分发。)


附加信息:

这两个项目都有“调试”和“发布”配置。可执行项目在平台下具有“x86”和“AnyCPU”。 DLL 项目在 Platform 下只有“AnyCPU”可用。 “平台目标”选项在所有情况下都与“平台”匹配。 (没有“首选 32 位”选项,因为我在 VS2010 上。)

该错误似乎是 DLL 中与编译相关的错误(“不允许不安全代码”),尽管我不是 100% 肯定,但似乎是因为在正在匹配的 DLL 项目(由于 Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " 等)将指定编译所需的参数(例如 AllowUnsafeBlocksDefineConstants)。

【问题讨论】:

  • 平台属性设置解决方案平台。仅对 C++ 项目重要的配置细节。但是您要更改的实际设置是出现在 Project > Properties > Build 选项卡上的设置。只要你添加多个平台,它们匹配是相当重要的,否则混淆将是致命的。他们通常不会,项目默认为平台的 AnyCPU,但选中了“首选 32 位”复选框。请务必更改 Debug 和 Release 配置的设置。
  • @HansPassant 我不明白你在说什么。项目设置中的“平台目标”(即:项目文件中的<PlatformTarget>)与$(Platform) 指定的“平台”(即:为构建选择的任何平台)以您期望项目的正常方式匹配文件,例如:<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">。 Visual Studio 将构建 x86 EXE + AnyCPU DLL 组合就好了。如何从命令行执行此操作?能够在两种配置中构建 EXE 是有意的。
  • Hmya,这就是我所说的“致命”。右键单击您的 EXE 项目 > 属性 > 构建选项卡。顶部有两个组合框和您关心的两个设置,“平台目标”和“首选 32 位”。组合框有 4 个可能的值,即 Debug/Release 和 x86/AnyCPU 的组合。写下这 4 种组合的所有设置值并将其发布在您的问题中。
  • @HansPassant 将该信息附加到我的问题的末尾。在我看来,我的问题可能是“有没有办法拦截<ProjectReference> 所做的任何事情”(单独构建 DLL 很简单)。不过,我不确定这实际上有多实用。但是 VS 显然可以做到这一点(x86 solution "platform" 使用 AnyCPU DLL project "platform")。
  • VS2010,哎呀,难以复制。所以这实际上是关于 DLL 项目中的“允许不安全代码”复选框。相同的配方,您有 4 个可能的值,而 DLL 项目的平台目标设置不起作用,因为您希望所有 4 个都使用 AnyCPU。确保为所有 4 个可能的组合勾选复选框。

标签: c# msbuild msbuild-4.0


【解决方案1】:

回答我自己的问题...首先,MSBuild 可以构建解决方案文件。这完全符合您的预期:

msbuild MySolution.sln /p:Configuration="Release" /p:Platform="x86"

结果是带有 AnyCPU DLL 的 x86 可执行文件(如解决方案指定的那样)。

互联网上有一些人暗示它的行为在某些晦涩难懂的情况下与 Visual Studio 不完全匹配。但对于我的目的来说,它似乎工作得很好。 (我认为他们在构建事物的顺序方面存在问题。)

我知道 MSBuild 可以构建一个解决方案文件,但是——糟糕——在我正在处理的更复杂的事情上失败后,我忽略了在我的简单复制案例上对其进行测试。


仅凭以上内容不足以获得完全令人满意的答案,尤其是在需要自定义内容的情况下。 MSBuild 构建解决方案文件的方式是基于解决方案文件创建一个虚拟项目文件。这可以通过首先设置一个环境变量来检查,如下所示:

set MSBuildEmitSolution=true

这将在解决方案文件旁边发出虚拟项目文件,然后可以对其进行检查。

我还没有完全分析它在做什么,但它看起来很简单,就像它使用 <MSBuild> taskProjects 参数一样对于每个项目。根据文档,它似乎使用了AdditionalProperties 中指定的那些。 (This 似乎也很有用。)


作为参考,下面是从生成的项目文件中提取的一些相关代码:

<Target Name="Build" Outputs="@(CollectedBuildOutput)">
  <MSBuild Projects="@(ProjectReference)" BuildInParallel="True" Properties="BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" SkipNonexistentProjects="%(ProjectReference.SkipNonexistentProjects)">
    <Output TaskParameter="TargetOutputs" ItemName="CollectedBuildOutput" />
  </MSBuild>
</Target>

@(ProjectReference) 从哪里获取数据:

<ItemGroup>
  <ProjectReference Include="X:\Solution\MyProject\MyProject.csproj">
    <ToolsVersion>
    </ToolsVersion>
    <SkipNonexistentProjects>False</SkipNonexistentProjects>
    <AdditionalProperties>Configuration=Release; Platform=x86; VisualStudioVersion=10.0</AdditionalProperties>
    <Configuration>Release</Configuration>
    <Platform>x86</Platform>
  </ProjectReference>
  <ProjectReference Include="X:\Solution\DLLProject\DLLProject.csproj">
    <ToolsVersion>
    </ToolsVersion>
    <SkipNonexistentProjects>False</SkipNonexistentProjects>
    <AdditionalProperties>Configuration=Release; Platform=AnyCPU; VisualStudioVersion=10.0</AdditionalProperties>
    <Configuration>Release</Configuration>
    <Platform>AnyCPU</Platform>
  </ProjectReference>
</ItemGroup>

(注意不同的AdditionalProperties。)

【讨论】:

    猜你喜欢
    • 2011-06-08
    • 2012-11-04
    • 2017-03-22
    • 2015-05-13
    • 2013-01-30
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多