使用 msbuild.exe 构建具有需要不同平台的依赖项的项目 属性
Using msbuild.exe to build a project with a dependency requiring a different Platform property
我有两个相当简单的 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.
中正常使用它们的方式修改项目
(这里的最终目标是一个批处理文件,可以构建一个干净的项目版本以供分发。)
附加信息:
两个项目都有 "Debug" 和 "Release" 配置。可执行项目在 Platform 下有 "x86" 和 "AnyCPU" 可用。 DLL 项目在 Platform 下只有 "AnyCPU" 可用。 "Platform target" 选项在所有情况下都与 "Platform" 匹配。 (没有 "Prefer 32-bit" 选项,因为我在 VS2010 上。)
该错误似乎是 DLL 中与编译相关的错误 ("no unsafe code allowed"),尽管我不是 100% 确定这似乎是因为 none <PropertyGroup>
正在匹配 DLL 项目中的元素(由于 Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "
等),这些元素将指定编译所需的参数(例如 AllowUnsafeBlocks
和 DefineConstants
)。
回答我自己的问题...首先,MSBuild 可以构建解决方案文件。这完全符合您的预期:
msbuild MySolution.sln /p:Configuration="Release" /p:Platform="x86"
结果是带有 AnyCPU DLL 的 x86 可执行文件(如解决方案指定)。
互联网上有一些人表示,在某些不明确的情况下,它的行为与 Visual Studio 的行为并不 完美 匹配。但它似乎对我的目的来说工作得很好。 (我认为他们对内置的顺序有疑问。)
我知道 MSBuild 可以构建解决方案文件,但是——哎呀——我忽略了在我的简单复制案例上测试它,因为它在我正在处理的更复杂的事情上失败了。
仅以上内容不足以提供完全令人满意的答案,尤其是在需要自定义内容的情况下。 MSBuild 构建解决方案文件的方式是基于解决方案文件创建一个虚拟项目文件。这可以通过首先设置环境变量来检查,如下所示:
set MSBuildEmitSolution=true
这将在解决方案文件旁边发出虚拟项目文件,然后可以对其进行检查。
我还没有完全分析它在做什么,但它看起来相当简单,就像它在使用 <MSBuild>
task with the Projects
parameter that is itself passing in the solution-specified Configuration
and Platform
appropriate for each project. According to the documentation it seems to be using the ones specified in 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
。)
我有两个相当简单的 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.
中正常使用它们的方式修改项目(这里的最终目标是一个批处理文件,可以构建一个干净的项目版本以供分发。)
附加信息:
两个项目都有 "Debug" 和 "Release" 配置。可执行项目在 Platform 下有 "x86" 和 "AnyCPU" 可用。 DLL 项目在 Platform 下只有 "AnyCPU" 可用。 "Platform target" 选项在所有情况下都与 "Platform" 匹配。 (没有 "Prefer 32-bit" 选项,因为我在 VS2010 上。)
该错误似乎是 DLL 中与编译相关的错误 ("no unsafe code allowed"),尽管我不是 100% 确定这似乎是因为 none <PropertyGroup>
正在匹配 DLL 项目中的元素(由于 Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "
等),这些元素将指定编译所需的参数(例如 AllowUnsafeBlocks
和 DefineConstants
)。
回答我自己的问题...首先,MSBuild 可以构建解决方案文件。这完全符合您的预期:
msbuild MySolution.sln /p:Configuration="Release" /p:Platform="x86"
结果是带有 AnyCPU DLL 的 x86 可执行文件(如解决方案指定)。
互联网上有一些人表示,在某些不明确的情况下,它的行为与 Visual Studio 的行为并不 完美 匹配。但它似乎对我的目的来说工作得很好。 (我认为他们对内置的顺序有疑问。)
我知道 MSBuild 可以构建解决方案文件,但是——哎呀——我忽略了在我的简单复制案例上测试它,因为它在我正在处理的更复杂的事情上失败了。
仅以上内容不足以提供完全令人满意的答案,尤其是在需要自定义内容的情况下。 MSBuild 构建解决方案文件的方式是基于解决方案文件创建一个虚拟项目文件。这可以通过首先设置环境变量来检查,如下所示:
set MSBuildEmitSolution=true
这将在解决方案文件旁边发出虚拟项目文件,然后可以对其进行检查。
我还没有完全分析它在做什么,但它看起来相当简单,就像它在使用 <MSBuild>
task with the Projects
parameter that is itself passing in the solution-specified Configuration
and Platform
appropriate for each project. According to the documentation it seems to be using the ones specified in 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
。)