【问题标题】:MSbuild build order issue - pre-build steps first or dependent projects firstMSbuild 构建顺序问题 - 先预构建步骤或先依赖项目
【发布时间】:2012-08-27 15:48:46
【问题描述】:

我有一个依赖于项目 B 的项目 A。项目 A 有一些预构建任务,这些任务依赖于项目 B 的一些生成文件。当我在 Visual Studio 中构建时,没问题。但是在使用MSBuild.exe的时候,就会出现问题,因为构建顺序是:

  • A 的预构建步骤
  • B 已编译
  • A 已编译

这是使用 MSBuild 的预期行为吗? 有没有办法告诉 MSBuild 在 A 的预构建步骤之前先执行 B?

我正在使用 VS2010 C# 和 C++/CLI。我不认为是否提供其他信息,但它是这样称呼的:

Running process (C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBUILD.exe "..\..\..\dev\build\MyProj.sln" /t:Clean /p:Configuration=Release;Platform=Win32)

【问题讨论】:

  • PreBuildEvent: 在调用 Csc.exe 之前在 Visual Studio 的输出窗口中执行。在此基础上,我不明白这个问题。
  • 我不确定,但您的问题是否与blogs.msdn.com/b/visualstudio/archive/2010/12/21/… 相似?
  • @P.Brian.Mackey Building VS solution 和 MSBuild.exe 是独立的进程。
  • @PavelBakshy 我也看到了那篇文章,但它谈论的内容略有不同。讨论的问题是由 Dependency 设置指定的一些项目依赖项触发的,而不是使用添加引用。这是关于我无法找到详细信息的预构建步骤。

标签: c# msbuild


【解决方案1】:

简答

删除您的构建事件,并将以下内容添加到您的项目 (.csproj):

<Target Name="AfterResolveReferences">
  <Exec Command="echo helloworld" />
</Target>

更多信息

您可以在此处阅读有关自定义构建过程的信息:http://msdn.microsoft.com/en-us/library/ms366724%28v=vs.110%29.aspx

Before Build 事件在 ResolveReferences 之前触发,因此如果您引用的项目在您的项目的 BeforeBuild 事件发生时尚未构建,那么您的 BeforeBuild 事件将失败。

要克服这个问题,您应该使用不同的入口点来自定义构建过程。在上面的示例中,我使用了 AfterResolveReferences,因为这将确保您引用的所有项目都已构建。

【讨论】:

  • 我只能说谢谢!这个小金块可以帮我解决很多问题。谁能想到在 Resolve References 调用之前调用了 pre-build 事件。这非常有效。
【解决方案2】:

这是一个相当老的问题,但我找到了这个简单的解决方案(它也可能适用于你) 只需添加

<PreBuildEventDependsOn>ResolveReferences</PreBuildEventDependsOn>

之前

<PreBuildEvent>

很遗憾,这必须在编辑器中完成,VS 编辑器不支持它(15.6.2 版)。

【讨论】:

    【解决方案3】:

    Jack 的回答似乎奏效了,但我不喜欢的是 VS UI 本身不支持对编辑 .csproj 的支持, 除了笨拙的“卸载项目,编辑项目(在此期间您不能像往常一样单击文件),重新加载项目”模型。 我想要的是在构建依赖项目之后触发预构建事件,并且在 VS 中与在 MSBuild 中的工作相同。 在解决了这个问题之后,我在 MSBuild 4.0 中找到了适合我的解决方案。

    无论我如何尝试,我都无法更改 PreBuildEvents 目标以在相关项目完成构建后触发。所以我做了什么 是禁用 PreBuildEvents 目标,并创建一个将在适当时间运行的混蛋自定义 PreBuildEvents 目标:

    <ItemGroup>
      <ProjectReference Include="..\YourProjectPath\YourProject.csproj">
        <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
      </ProjectReference>
    </ItemGroup>
    <Target Name="PreBuildEvent" AfterTargets="" BeforeTargets="" />
    <Target Name="BastardPreBuildEvent" AfterTargets="ResolveReferences" BeforeTargets="CoreResGen">
      <Exec Command="$(PreBuildEvent)" />
    </Target>
    

    【讨论】:

    • 这对我有用。我同意...这要好得多,因为它仍然支持 Visual Studio PreBuild 编辑器对话框。
    • 这个 'AfterTargets="" BeforeTargets="' 是否会阻止 PreBuildEvent 在之前的位置运行?或者只是因为您的 没有子元素?
    • 最有可能的是,将 AfterTargets 和 BeforeTargets 设置为空白是导致 PreBuildEvent 目标无法运行的原因。
    【解决方案4】:

    这可能很旧,但我最近遇到了同样的问题。 Jack 的回答是我试图使用的,但是在 Visual Studio 中加载项目时会调用 ResolveReferences 目标,这对我来说 不好,因为我在目标期间做了一个相当长的过程,我只想要在构建之前做。

    我最终使用的解决方案与 VeeTheSecond 类似,但涉及的部分更少:

    <Target Name="BeforeBuild" DependsOnTargets="ResolveReferences">
        ... exec something using a dependant project's output exe ...
    </Target>
    

    这将强制 BeforeBuild 目标等到所有依赖项目实际构建完成,以便 exec 命令可以使用依赖项目的输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-19
      • 2017-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多