使用msbuild.exe构建具有需要不同Platform属性的依赖项的项目

时间:2017-10-05 13:38:58

标签: c# msbuild msbuild-4.0

我有两个相当简单的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中正常使用它们的方式修改项目。

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

其他信息:

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

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

1 个答案:

答案 0 :(得分:0)

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

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

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

互联网上有一些人表示,在一些不起眼的案例中,它的行为并不是Visual Studio的完美匹配。但它似乎对我的目的很好。 (我认为他们在订购内容方面存在问题。)

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

仅凭上述内容并不足以获得完全令人满意的答案,特别是如果需要定制的话。 MSBuild构建解决方案文件的方式是基于解决方案文件创建虚拟项目文件。这可以通过首先设置如下的环境变量来检查:

set MSBuildEmitSolution=true

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

我还没有完全分析它在做什么,但它看起来非常简单,就像使用<MSBuild> task Projects参数本身在解决方案指定的Configuration中传递一样}和Platform适合每个项目。根据文档,它似乎使用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。)