修改MSBuild和Visual Studio中引用项目的DefineConstants

时间:2013-09-17 19:19:40

标签: c# visual-studio msbuild build-process conditional-compilation

我有一个Windows手机类库项目 BaseProj 的解决方案,以及几个引用该项目的WP项目,项目 A B 等。 BaseProj 有一个LocationHelper类。

假设项目 A 需要 BaseProj 来使用LocationHelper类进行编译,但项目 B 应该在没有ID_CAP_LOCATION-capabillity的情况下构建,因此,当 BaseProj 构建时,不应包含LocationHelper类。

我可以使用条件编译符号实现这一点,问题是:如何使用适当的符号构建 BaseProj ,具体取决于我是否正在构建项目 A B

经过一些研究后,我想出了以下解决方案,在BaseProj.csproj中我添加了

<PropertyGroup Condition=" '$(TestProperty)'==true ">
  <DefineConstants>$(DefineConstants);TEST_SYMBOL</DefineConstants>
</PropertyGroup>

在B.csproj中,ProjectReference中有一个属性:

<ProjectReference Include="..\BaseProj\BaseProj.csproj">
  <Project>{...}</Project>
  <Name>BaseProj</Name>
  <Properties>TestProperty=true</Properties>
</ProjectReference>

认为在使用 B 构建时应添加TEST_SYMBOL而不是 A 。当我使用MSBuild构建时,这非常有效。另一方面,Visual Studio完全忽略了这一点,这意味着当我调试和使用构建脚本进行发布构建时,我会得到不同的行为。

如何从MSBuild Visual Studio获取我想要的行为?

2 个答案:

答案 0 :(得分:1)

我想出了一个适用于MSBuild和Visual Studio的新解决方案。

首先,如果定义了条件编译符号INCLUDE_LOCATION_API BaseProj 将设置为使用位置api进行构建。

项目 A B 设置为使用执行powershell脚本的预构建事件构建, pre-build.ps1 。 (参考this question)。

pre-build.ps1 将读取当前项目的清单,以确定它是否具有位置功能(ID_CAP_LOCATION),以及 BaseProj Debug和发布配置定义INCLUDE_LOCATION_API。如有必要,我们会添加或删除INCLUDE_LOCATION_API。由于这将修改 BaseProj.csproj ,因此构建脚本将退出并显示错误代码,以防止构建完成。

当我从VS构建时,如果 BaseProj 具有正确的配置,它将正常构建。如果配置错误, BaseProj.csproj 将被修改,构建失败,但下一次构建将成功。

在我的构建脚本中,我在实际构建之前执行一次 pre-build.ps1 ,确保项目具有正确的配置。然后执行MSBuild并成功构建项目。

我不会考虑这个最佳实践,但它完成了工作,我不需要考虑在项目之间切换时应该使用哪些配置。

答案 1 :(得分:0)

这可以通过定义新的项目配置来完成。假设您已经具有调试和发布配置,并且使用ID_CAP_LOCATION配置它们,则可以创建新配置,例如:Debug_No_Location和Release_No_Location。这是在Visual Studio的“配置管理器”对话框中完成的。除了项目配置外,还可以定义相应的解决方案配置,以便更轻松地从Visual Studio构建它。之后,从Debug_No_Location / Release_No_Location配置中删除ID_CAP_LOCATION。

编辑解决方案中的所有项目并确保中间位置和二进制位置与其调试/发布配置不同非常重要,否则您将遇到在配置之间混合二进制的问题,从而使增量构建不可靠。

如果要从VS IDE构建两种风格(使用“位置”和“不使用”),则必须在配置之间手动切换。但是,从命令行,您可以创建两次调用MSBuild.exe的简单脚本。 E.g:

msbuild MySolution.sln /p:Configuration=Debug
msbuild MySolution.sln /p:Configuration=Debug_No_Location