Search code examples
gradleandroid-studiobuild-processsubproject

Making a Studio/Gradle project build both locally and inside another project


I don’t know how common this situation is but here’s what worked for me. The question is: Is this sane, or is there a better way?

tl;dr:

dependencies {
    // remove trailing ':Lib'
    ppath = project.path
    ppath = ppath.substring(0, ppath.length() - 4)
    compile project(ppath + ":jsoup:Lib")
}

Main project OpenKeychain (https://github.com/open-keychain/open-keychain)
|-Git submodule KeybaseLib (https://github.com/timbray/KeybaseLib)
 |- Git submodule jsoup (https://github.com/timbray/jsoup)

Directory structure is set up for Android Studio & Gradle, for all three projects. This means that there’s an idiosyncratically-named directory under the project root (I like to use “Lib” for library type projects), and source starts at root/Lib/src/main/...

open-keychain
|- settings.gradle [1]
|- OpenKeychain
  |- build.gradle [2]
|- extern
  |- KeybaseLib
    |- settings.gradle [3]
    |- Lib
       |- build.gradle [4]
       |- jsoup

OK, the problem is, what goes in [1], [2], [3], and [4] so that I can gradle-build KeybaseLib & also jsoup both from the open-keychain root and the KeybaseLib root?

[1]

    include ':extern:KeybaseLib:Lib'
    include ':extern:KeybaseLib:jsoup:Lib'

[2]

dependencies {    
    compile project(':extern:KeybaseLib:Lib')
    ...
}

[3]

include 'Lib'
include ':jsoup:Lib'

[4]

dependencies {
    // remove trailing ':Lib'
    ppath = project.path
    ppath = ppath.substring(0, ppath.length() - 4)
    compile project(ppath + ":jsoup:Lib")
}

Solution

  • Instead of doing trickery to try to modify the Gradle-esque project paths, I think it would be simpler to give your modules consistent single-element names and remap the directories in settings.gradle.

    Be aware that Gradle only supports a single settings.gradle file (though looking at your question I think you're not assuming it will use both of them, but you're expecting it to use one at a time). I also vaguely recall an Android Studio bug where it did Something Wrong if there's more than one settings.gradle file in a project. I don't recall the nature of the bug and my searches in the bug database don't find it, but if you see bad behavior, please add a comment to this answer.

    Having said that, here's how it works. Caveat: I haven't actually tested this code, but it should get you started; if you have problems, let me know and I can revise my answer.

    open-keychain's settings.gradle:

    include ':KeybaseLib'
    include ':jsoupLib'
    project(':KeybaseLib').projectDir = new File(settingsDir, 'extern/KeybaseLib/Lib')
    project(':jsoupLib').projectDir = new File(settingsDir, 'extern/KeybaseLib/jsoup/Lib')
    

    KeybaseLib's settings.gradle:

    include ':KeybaseLib'
    include ':jsoupLib'
    project(':KeybaseLib').projectDir = new File(settingsDir, 'Lib')
    project(':jsoupLib').projectDir = new File(settingsDir, 'jsoup/Lib')
    

    There's a relevant question on remapping modules here:

    Android studio add external project to build.gradle