Search code examples
gradlegit-submodules

How do I configure a dependency in a gradle project such that it also works as a submodule?


I want to use a project in my project as a git submodule, ideally without changing the upstream project (or if it makes sense, changing it in a way that will get merged there).

The problem is that the project consists of modules, 2 of which I want to directly use, with the one also depending on the other.

myProject
├ submodule
| ├ first
| | ├ build.gradle: implementation project(":second") <---- this fails if I don't change it to :submodule:second
| ├ second
| ├ settings.gradle: include ':first', ':second'
├ app
| ├ build.gradle: implementation project(":submodule:first"), implementation project(":submodule:second")
| ├ settings.gradle: include ':submodule:first', ':submodule:second', ':app'

As my project's settings.gradle replaces the submodule's settings.gradle, the submodule's absolute paths suddenly change. Can I somehow `include ':submodule:second as :second'?

I know I can use implementation project(somePrefix + ":second") and define this somePrefix accordingly but that would involve touching the submodule.


Solution

  • Gradle project paths (e.g. ':submodule:second')

    • actually represent project hierarchies. This means that using include ':submodule:second' in your settings.gradle will implicitly create a project called submodule, even if not relevant for the build at all.
    • do not need to match the directory structure (this is just a convention). You may set the project directory independent from the project path (and the project name).

    Check out the following example from the documentation:

    // include two projects, 'foo' and 'foo:bar'
    // directories are inferred by replacing ':' with '/'
    include 'foo:bar'
    
    // include one project whose project dir does not match the logical project path
    include 'baz'
    project(':baz').projectDir = file('foo/baz')
    

    However, I would recommend to not use include at all. Instead use includeBuild and setup a composite build. Composite builds differ from classical multi-project builds in their coupling. Since your Git submodule indicates a build that may be used as a standalone project (with its own settings.gradle), the strong coupling of a multi-project builds seems inappropriate. Multiple settings.gradle files may also cause problems in a multi-project build, but are fine for composite builds.