如何表达工件对另一个解决方案的依赖

How to express artifact dependency on another solution

我们的解决方案 (A.sln) 需要一个由另一个(遗留)解决方案 (B.sln) 构建的二进制文件。我不能详细说明为什么这是必要的,这是一个漫长而毛茸茸的故事。

约束条件

A 生成的应用程序在运行时只需要 B 的工件,因此在构建过程中何时满足此依赖关系并不重要。由于命名冲突,我们不想在同一目录中构建两个项目,而是将 B 的一些工件复制到 A 输出路径的子目录中。

我试过了

1) 通过将以下内容添加到 A.sln

,将依赖项 B 作为构建目标添加到 A
<Target Name="Build">
  <MSBuild Projects="$(SolutionDir)..\B\B.sln" Properties=" Platform=Win32; Configuration=$(Configuration); " />
</Target>

出于某种原因,这会在 A 的输出目录中构建 B,这是不需要的。

2) 通过将以下内容添加到 A.sln

,将 post 构建事件添加到 AB 上调用 msbuild
<PropertyGroup>
  <PostBuildEvent>
    msbuild $(SolutionDir)..\B\B.sln /p:configuration=$(ConfigurationName)
    xcopy /E /R /Y $(SolutionDir)..\B$(ConfigurationName) $(SolutionDir)$(ConfigurationName)\B\
  </PostBuildEvent>
</PropertyGroup>

出于某种原因,这在 VS 2015 命令提示符中有效,但在 Visual Studio 本身中无效。 VS(2015)抱怨

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\CodeAnalysis\Microso
ft.CodeAnalysis.targets(219,5): error MSB4175: The task factory "CodeTaskFactory
" could not be loaded from the assembly "C:\Windows\Microsoft.NET\Framework64\v4
.0.30319\Microsoft.Build.Tasks.v12.0.dll". Could not load file or assembly 'file
:///C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Build.Tasks.v12.0.
dll' or one of its dependencies. The system cannot find the file specified. [C:\
Users\Chiel.tenBrinke\Projects\MyProject\B\CppSource\B.vcxproj]

那么,最好的(即最简单、最易维护、最干净的)方法是什么?

<PropertyGroup>
  <PostBuildEvent>
    msbuild $(SolutionDir)..\B\B.sln /p:configuration=$(ConfigurationName)
    xcopy /E /R /Y $(SolutionDir)..\B$(ConfigurationName) $(SolutionDir)$(ConfigurationName)\B\
  </PostBuildEvent>
</PropertyGroup>

我认为 ItemDefinitionGroupPropertyGroup 更有意义。至少 Visual Studio 是这样放置的。

您也可以用 Condition 收紧它。也许是这样的:

<ItemDefinitionGroup Condition="!Exists('$(ConfigurationName)\b.exe')" Label="Copy b.exe">
  <PostBuildEvent>
    msbuild /t:Build /p:Configuration=$(ConfigurationName) B.vcxproj
    xcopy /E /R /Y ...\B$(ConfigurationName)\b.exe $(ConfigurationName)\B
  </PostBuildEvent>
</ItemDefinitionGroup>

我们不得不做类似的事情来破解无法使用工具正确表达的项目外依赖项。和你一样,我觉得 Target 是可行的方法,但我也无法让它工作...

无论如何,这是我们的 cryptdll.vcxproj,它实际上使用了项目外依赖 hack,所以我知道它有效。

<!-- The current project file is c.vcxproj. We have a hard requirement to always -->
<!-- use Win32/Debug EXE. Also, b.vcxproj depends on an artifact from a.vcxproj -->
<ItemDefinitionGroup Condition="!Exists('Win32\Debug\b.exe')" Label="MAC tool">
  <PreBuildEvent>
    <Message>Creating Win32/Release cryptest.exe for MAC computation</Message>
    <Command>
      msbuild /t:Build /p:Configuration=Debug;Platform=Win32 a.vcxproj
      msbuild /t:Build /p:Configuration=Debug;Platform=Win32 b.vcxproj
    </Command>
  </PreBuildEvent>
</ItemDefinitionGroup>

我最终的做法是在项目级别而不是解决方案级别。 解决方案A项目中的xml形式如下:

<Target Name="AfterBuild">
  <MSbuild
      Projects="$(SolutionDir)..\B\CppSource\SomeProject.vcxproj"
      Properties="
      Configuration=$(ConfigurationName);
      OutDir=$(SolutionDir)$(ConfigurationName)\B\;
      "/>
</Target>