【问题标题】:Modify DefineConstants for referenced project in MSBuild and Visual Studio在 MSBuild 和 Visual Studio 中修改引用项目的 DefineConstants
【发布时间】:2013-09-22 09:09:12
【问题描述】:

我有一个解决方案,其中包含一个 windows phone 类库项目 BaseProj,以及几个引用该项目的 WP 项目 A、B em> 等等。BaseProj 有一个 LocationHelper 类。

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

我可以使用条件编译符号来实现这一点,问题是:如何根据我是否正在构建项目 A 使用适当的符号构建 BaseProj > 还是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>

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    pre-build.ps1会读取当前项目的manifest来判断是否有定位能力(ID_CAP_LOCATION),如果BaseProjDebug和Release配置定义INCLUDE_LOCATION_API。如有必要,将添加或删除INCLUDE_LOCATION_API。由于这将修改 BaseProj.csproj,构建脚本将退出并显示错误代码以阻止构建完成。

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

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

    我不会考虑这种最佳做法,但它可以完成工作,而且我不需要考虑在项目之间切换时应该使用哪些配置。

    【讨论】:

      【解决方案2】:

      这可以通过定义新的项目配置来完成。假设您已经有 Debug 和 Release 配置,并且它们配置了 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 两次的简单脚本。例如:

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

      【讨论】:

      • 但这意味着我在开发的时候还是需要手动切换配置吧?选择新的启动项目时,有没有办法自动获得正确的设置?该解决方案包含 +10 个项目,所以我不想依赖内存
      • 是的,您必须手动切换。这就是为什么我建议使用命令行脚本来执行构建。或者,您可以将脚本连接到 Visual Stuio 中的快捷方式之一。将现有逻辑硬编码到标准 *.targets 文件中,不可能在 元素中传递配置设置。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-01
      • 1970-01-01
      • 2019-03-02
      相关资源
      最近更新 更多