Gradle multi项目,如何处理不同的rootDirs

时间:2017-03-22 07:41:15

标签: java gradle build.gradle

我的公司目前正在从Ant转向Gradle以获得Java项目,但我仍然坚持使用干净的设置。假设我为一家为客户构建网站的公司工作,这些公司通常使用相同的根库(核心项目),但有一些特定的代码,这些代码放在子项目中。根据客户,我们构建一个新的子项目,这取决于核心项目。客户数量将来会增加。

目前我们有三个项目:

  • 核心项目。这应该单独运行,因为我们希望能够单独进行单元测试。
  • 两个依赖核心项目的子项目,但有一些特定于项目的项目。

我成功地将整个ant构建转换为核心项目的gradle构建。我的想法是将所有功能和项目结构放在核心,而只是额外用于子项目中实际需要的内容。

以下是我们文件夹结构的简短示例:

-- core
    - build.gradle
    - settings.gradle
    -- repository (our external jars used)
    -- Implementation
      -- source_code
        -- all the core project folders
      -- Projects
        -- Client A
          - build.gradle
          - settings.gradle
          -- more project specific folders
        -- Client B
          - build.gradle
          - settings.gradle
          -- more project specific folders

我经常使用$ rootDir变量。核心的settings.gradle的一小部分看起来像这样:

project(':CoreProjectA').projectDir = new File(rootDir, 'Implementation/Source_code/Core/coreA')
project(':CoreProjectB').projectDir = new File(rootDir, 'Implementation/Source_code/Core/CoreB')

但还有更多。此外,在核心build.gradle中,我将这样称为我们的存储库:

repositories {
   //All sub-projects will now refer to the same 'libs' directory
    flatDir {
        dirs "$rootDir/repository/lib/jaxb"
        //many more dirs here
    }
}

现在,当我从核心项目进行gradle构建时,这一切都很有效。 我打算将下一段代码放在每个客户的子项目build.gradle中:

apply from: '../../../build.gradle'

当我从Client A文件夹运行gradle构建时,我的rootDir显然已经改变了,现在,我的所有路径都无法在任何地方找到。

有没有办法以干净的方式设置它?所以添加的每个子项目总是可以使用相同的结构?或者我是否必须完全为每个子项目提供build.gradle和settings.gradle?

我知道最后一个选项可以工作,但这是一个很大的开销,对我来说似乎并不好看。

提前致谢!

3 个答案:

答案 0 :(得分:1)

看起来您在子项目中有额外的settings.gradle。这使得Gradle认为子项目是一个独立项目。如果从子项目中删除settings.gradle,Gradle将在文件系统层次结构中查找它,将在核心项目中找到一个,将创建正确的多模块项目,并且所有路径都应该正常工作。

因此,只需删除额外的settings.gradle文件,您的构建就可以正常工作。在子项目中使用build.gradle非常好。

答案 1 :(得分:1)

我最近处理过类似的配置,所以让我解释一下如何构建Gradle基础架构。既然你提到了很多要求,我希望我会错过任何一个要求,你可以将我的方案应用到你的问题中。

一般

我们实际上使用构建系统(如Gradle)来让他们处理任何依赖项(项目,模块,任务)。那么,为什么我们应该在文件系统层次结构中定义依赖性,如果我们可以在Gradle中简单地定义它呢?

我会尽可能避免使用路径(约定优于配置)并尝试坚持使用Gradle项目来构建脚本和依赖项。

此外,如果您在核心float nearMaxValue = BitConverter.ToSingle(BitConverter.GetBytes(BitConverter.ToInt32(BitConverter.GetBytes(float.MaxValue), 0) - 1), 0); Console.WriteLine("{0:R}: float.MaxValue", float.MaxValue); Console.WriteLine("{0:R}: previous float", nearMaxValue); Console.WriteLine("{0:R}: difference", float.MaxValue - nearMaxValue); 中定义依赖项,则应该只调用此gradle文件,即使您只想构建子项目。你的gradle.build破坏了整个Gradle逻辑。相反,您应该使用apply from: '../../../build.gradle'之类的东西来构建第一个子项目。

第一种方法(以核心为根项目)

文件系统结构:

gradle :sub1:build

核心core/ build.gradle settings.gradle src/ ... sub1/ src/ ... build.gradle [optional] sub2/ src/ ... build.gradle [optional]

settings.gradle

核心include 'sub1' include 'sub2'

build.gradle

第二种方法(所有项目独立)

文件系统结构:

allprojects {
     apply plugin: 'java'

     repositories {
         // define repos for all projects
     }
}

subprojects {
     dependencies {
         // let subprojects depend on core
         compile rootProject
     }
}

project(':sub1') {
     // define anything you want (e.g. dependencies) just for this subproject
     // alternative: use build.gradle in subproject folder
}

Root core/ src/ ... build.gradle [optional] sub1/ src/ ... build.gradle [optional] sub2/ src/ ... build.gradle [optional] build.gradle settings.gradle

settings.gradle

Root'build.gradle'

include 'core'
include 'sub1'
include 'sub2'

这种方法提供了很大的灵活性,因为每个依赖逻辑都由Gradle处理,你永远不必将任何东西复制到另一个位置。只需改变依赖关系就可以了。

来源

Gradle Tutorial on Multi-project Builds

Question in Gradle Forum

答案 2 :(得分:0)

我要感谢Nikita,特别是lukegv的详细答案,但我最终采用了不同的方法。

我不希望有一个主要的gradle构建并在每次有新项目时扩展它。另外,如果他们想为其中一个项目创建构建,我想让同事保持简单和合乎逻辑。

因此,我保留了上面所描述的结构。在根gradle.settings但改变了

project(':CoreProjectA').projectDir = new File(rootDir, 'Implementation/Source_code/Core/coreA')
project(':CoreProjectB').projectDir = new File(rootDir, 'Implementation/Source_code/Core/CoreB')

成:

project(':CoreProjectA').projectDir = new File(customRootDir, 'Implementation/Source_code/Core/coreA')
project(':CoreProjectB').projectDir = new File(customRootDir, 'Implementation/Source_code/Core/CoreB')

在每个项目中,我都有一个带有customRootDir的properties.gradle(相对于projects目录)。

这一切都像魅力一样。我可以进入任何项目文件夹并生成构建,同时使用root的build.gradle功能。