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

时间:2016-07-07 09:13:09

标签: .net visual-studio msbuild solution msbuild-task

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

约束

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

我试过

1)通过将以下内容添加到B

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

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

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

,将帖子构建事件添加到B,在A.sln上调用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]

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

2 个答案:

答案 0 :(得分:1)

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

我认为这可能比ItemDefinitionGroup更有意义,而不是PropertyGroup。至少这就是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实际上使用了项目外的依赖项黑客,所以我知道它有效。

<!-- 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>

答案 1 :(得分:1)

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

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