【问题标题】:How to express artifact dependency on another solution如何表达对另一个解决方案的工件依赖
【发布时间】:2016-07-07 09:13:09
【问题描述】:

我们的解决方案 (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 来向 A 调用 msbuild on B 添加构建后事件

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

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

【问题讨论】:

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


    【解决方案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>
    

    【讨论】:

    • 确实,我终于在项目级别上完成了。查看我刚刚发布的答案
    【解决方案2】:

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

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

    【讨论】:

    • 你知道PostBuildEventTargetAfterBuild之间有什么区别吗?
    • 不知道,但我发现了这个:stackoverflow.com/questions/6128567/…
    • 谢谢。我必须买一本关于这个主题的书。 MSDN 所做的一切都让我对它们的无上下文片段感到困惑......
    猜你喜欢
    • 2016-06-07
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    • 2014-12-29
    • 1970-01-01
    • 2012-03-31
    • 2020-08-02
    • 1970-01-01
    相关资源
    最近更新 更多