【问题标题】:msbuild of a vc++ solution cleaning project after already built using VS2015 projects and solujtions已使用 VS2015 项目和解决方案构建后的 vc++ 解决方案清理项目的 msbuild
【发布时间】:2017-12-23 22:59:49
【问题描述】:

我一直在重新设计我的自定义 VC++ 构建以与新的 TFS 2015 构建解决方案兼容。

问题是运行 msbuild。我可以发布一个简化版本,但我的解决方案包含两个项目:

1 Makefile 项目旨在构建所需的所有库,以及 1 个 .exe 项目。

我在 .exe 项目中有对 makefile 项目的引用,因此如果需要,.exe 的构建会强制库的构建。

我们看到的问题是,当我们使用解决方案的 msbuild 进行重建时,它首先重建库,然后当它到达 .exe 时,它​​会清理库项目,导致一些重建的文件被删除然后阻止.exe文件的链接,因为.lib文件被删除了。

为什么要再次清理 makefile 项目?好像到了.exe项目后,重新解析了依赖,不知道库项目已经重建了。

提前致谢。拉里

【问题讨论】:

  • 所以你运行msbuild some.sln /t:Rebuild,结果是干净的 M/build M/clean M/clean E/build E(其中 M 代表 Makefile 项目,E 代表 exe 项目?正是这些步骤?
  • 我们得到一个 M/Rebuild,然后当它进入 .exe 项目时,它执行了 M/Clean、M/Build,然后是 E/Rebuild。
  • 这似乎没有反映您在问题中陈述的事情之一:如果 M/Build 出现在 E/Rebuild 之前,那么在 M 被构建之后,E 怎么还会有链接问题?
  • 我们的问题是,当它进入 exe 项目时,它实际上正在再次重建 M 项目(通过 Clean and Build)。 Rebuild 对我们来说与 clean and build 不同,rebuild 有一些额外的要求。我们的最佳解决方案是在 M 项目第一次重建后不再对其进行任何操作。我们将进行多处理器构建,最终将有超过 1000 个 E。
  • 顺便说一下,devenv 的工作方式似乎有所不同。

标签: c++ makefile tfs msbuild


【解决方案1】:

我没有详细介绍所有细节,但发生这种情况的原因是,在命令行上构建时,重新构建 exe 项目会导致 exe 项目的 Clean + Build,并且 exe 项目的 Clean 目标最终会调用CleanReferencedProjects 目标会导致在 Makefile 项目上调用 Clean(以及稍后的 Build)。

此 CleanReferencedProjects 以属性 BuildingInsideVisualStudioBuildProjectReferences 为条件,因此在 VS 内部构建无论如何都会跳过这一步,因为 BuildingInsideVisualStudio 是真的,它甚至被记录在案:

直接从命令行构建项目时,清理那些引用的项目 存在于磁盘上。对于 IDE 构建和命令行 .SLN 构建,解决方案构建管理器 照顾这个。

BuildProjectReferences 属性记录如下:

默认情况下,我们将构建(如果适用,清理)所有项目引用。但这可以用来禁用它

所以一种可能的解决方案是调用msbuild some.sln /t:Rebuild /p:BuildProjectReferences=False。在只有 2 个项目的情况下,这将正常工作,但我不能保证这将始终在具有更多项目间依赖关系的更复杂情况下工作。

现在有一件事让我想知道:为什么我自己从来没有见过这种行为?答案在于我不经常使用 makefile 项目,而我使用的 C++ 项目略有不同:在那里,Rebuid 目标是根据 Clean+Build 定义的(而对于 Makefile 项目,它是独立的,单独的目标)。因此,当exe项目调用BuildProjectReferences时,它会在C++项目中调用Clean,但这会导致

Target "Clean" skipped. Previously built successfully.

因为当 C++ 项目的 Rebuild 被调用时,它已经被称为 Clean and Build。

因此,另一种可能的解决方案是对 Makefile 项目执行相同的操作。你说你的 Rebuild 有额外的要求;我不知道它们是什么,也不知道为什么需要它们(可以说 Rebuild 与 Clean + Build 的效果不同是错误的)但这可能无论如何都可以工作,例如在 makefile 项目中使用它(一直在文件末尾):

<Target Name="Rebuild" DependsOnTargets="Clean;Build">
  <!--additional requirements here perhaps?-->
</Target>

一切正常,Clean/Build 只调用一次。

如果这些解决方案都不适用,除了从解决方案中删除 makefile 项目,并在本地和 TFS 中的解决方案之前手动构建它之外,我不会立即看到其他方法。

【讨论】:

    【解决方案2】:

    如果多个项目位于同一个文件夹中,Visual Studio 会在编译下一个项目时尝试擦除输出文件夹(通常是 Debug 或 Release)。最好的解决方案是将每个项目放在单独的文件夹中。

    【讨论】:

      猜你喜欢
      • 2014-05-08
      • 2011-06-07
      • 1970-01-01
      • 2016-04-26
      • 2013-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多