【问题标题】:Is there a way to force gradle to compile c++ code(and only it) for only 1 project at a time?有没有办法强制 gradle 一次只为 1 个项目编译 c++ 代码(并且只编译它)?
【发布时间】:2019-08-06 11:13:13
【问题描述】:

我们有几个通过 jenkins 管道使用 gradle 构建的独立项目,并将一些 c++ 代码编译为 gradle 作业的一部分。我们使用vc17。
通过并行构建它们,我们有时会遇到文件损坏的相关问题(经常被忽视)。

有没有办法强制一次只为 1 个 gradle 作业编译 c++ 代码?
最好尽快完成,即不削减工人或线程或其他此特定代码编译的资源。

PS:我知道我可以在运行其他构建的同时阻止一些 jenkins 构建,但这远非最佳 - 每个 jenkins 工作在 1-2 小时内完成,而 gradle 只需要大约 2/3,其中大约 2/3 时间轮流编译c++代码

【问题讨论】:

  • 如果并行构建创建“损坏的文件”,它们并不是真正独立的,是吗?我建议您通过提取 stompy 位并引入依赖项来解决这种损坏的原因(通常是中间文件被踩到)
  • 嗯,源是独立的,但编译器和构建器很常见,这就是问题所在
  • 但是编译器和构建器很常见,这就是问题所在 - 很可能不是
  • 您可以将编译器包装在某个脚本文件中,该文件将首先获取一些“锁”,并在完成后释放它,但取决于导致损坏的确切原因,如果它只是两个编译器同时运行的实例,或者它是编译器实例之间的构建缓存共享(那么如果这种锁定的包装器将在两个作业之间交错构建,您可能仍然会以损坏的文件结束)。另外,我不是 Jenkins 专家,但是否有某种方法可以隔离不同作业的构建目录(包括 VC17 的内部缓存)?我实际上希望这是默认的......
  • 项目被隔离,但编译同时进行,因此有几个实例在运行

标签: c++ jenkins gradle


【解决方案1】:

是的,您可以这样做。在 Gradle 中构建依赖结构,其中项目通过 dependsOn 引用。 (正如@Botje 指出的那样——您的项目似乎并不独立。)

假设您有一个projectA,这取决于之前完成的projectB 编译。您还有一个projectC,这取决于projectAprojectB 以B > A > C 的顺序完成。

你可以通过在Gradle中声明C的编译任务来使C的编译依赖于A、B:

dependsOn( projectACompilationTask )
dependsOn( projectBCompilationTask )

为确保 A、B 的正确顺序,您可以为 projectCCompilationTask 定义:

tasks.findByName('projectACompilationTask').mustRunAfter 'projectBCompilationTask'

您还必须定义我在此处描述的编译任务。例如,您可以使用任务来触发 CMake 或您当前使用的任何东西来启动编译。

【讨论】:

  • 项目之间没有依赖关系。它们在不同的工作空间中运行,它们是隔离的。他们使用通过共享库提供的相同构建脚本,但问题仅在 gradle 通过 cmake 构建代码时出现。 Gradle 有相似但不同的配置。
  • 如果你建议我手动编写这些工作的构建顺序 - 那是不好的
  • 为什么会这样?如果您不想要完整构建管道的顺序,您仍然可以引入 C++ 编译顺序,确保编译仅在另一次编译之后发生。或者您可以使用配置任务来设置您想要执行的构建,然后确保一次只执行一个管道。如果您只需要知道 Gradle 是否有一些内部标志,告诉它一次不要编译多个 C++ 代码库 - 不,没有这样的事情。您需要明确自己需要什么,然后相应地实施构建管道。
  • 听起来好像您需要重新设计整个管道架构。您声称项目之间没有依赖关系,但您还声称当您一次编译多个 C++ 实例时文件会损坏。对我来说毫无意义,看看@Botje 提到了什么。
  • 好吧..我不想每次出现新的类似项目时都重写每个配置文件。我想要的是某种锁,它可以防止其他代码库在 1 运行时编译。如果 c++ 编译器和 gradle 没有解决方案,我会尝试通过管道制作一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 2021-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多