我有一个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获取我想要的行为?
答案 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