25

What is the key difference between includeBuild(...) and implementation(project(...)) in the Gradle build system? I cannot really see the usecase difference after reading the documentation:

  1. https://docs.gradle.org/current/userguide/declaring_dependencies.html#sub:project_dependencies
  2. https://docs.gradle.org/current/userguide/composite_builds.html#separate_composite

What I am trying to do: Share same codebase for two separate projects: data classes (kotlix.serialization), external database dao, interfaces. It is not a full library but just some code snippets.

How can I connect the two projects in Intellij so that type hinting works?

Hans
  • 2,419
  • 2
  • 30
  • 37
Jan Veselý
  • 1,329
  • 1
  • 15
  • 24
  • For me, `implementation(project(...))` is better. Each common component is just like a third-party library, making dependency graph more organized. – chehsunliu Jul 05 '21 at 02:55

2 Answers2

30

Composite Build (by using includeBuild) is a way to create a dependency between autonomous Gradle Projects.
Project import, is a way to create a dependency between two modules within a same Gradle Project.

Composite Build is far more powerful and is also meant to be the new way of factorizing gradle configuration between multiple projects that you traditionally do with the buildSrc technique. I found this "Structuring Large Projects" article to be easier to read than the "Composite Builds" doc.

An excellent sample project that demonstrates the power of Composite Builds can be found in Gradle sample_structuring_software_projects.

Project dependency case

The tree would look like this:

settings.gradle.kts
module1/build.gradle.kts
module2/build.gradle.kts

And you are declaring a dependency in module1/build.gradle.kts like this:

dependencies {
   implementation(project("com.domain:module2"))
}

The dependency will be resolved only if both projects are declared as sub-modules of a common root project.

It means you have a root settings.gradle.kts like this:

rootProject.name = "rootProject"
include(":module1")
include(":module2")

Composite build case

The projects do not need to have common "umbrella" root project. Each project is a totally independent project.

One project can simply declare a dependency on the other project (without even the target project knowing about it).

Tree:

project1/build.gradle.kts
project1/settings.gradle.kts
project2/build.gradle.kts
project2/settings.gradle.kts

In project1/settings.gradle.kts:

rootProject.name = "project1"
includeBuild("../project2") //No more ':' as it is not a module

In project2/settings.gradle.kts:

rootProject.name = "project2"

In project1/build.gradle.kts like this:

dependencies {
   implementation("com.domain:project2")
}
Luke Chambers
  • 785
  • 1
  • 10
  • 16
Renaud
  • 1,833
  • 19
  • 20
  • 10
    you're referencing the project2 prefixed with `com.domain:`. Where do you get that from? – caeus Apr 28 '22 at 22:17
  • 1
    There is a mistake in "Composite build case/build.gradle.kts/implementation" section. It should be: `dependencies{ implementation("com.domain:project2") }` . @AlejandroNavas, an `implementation` argument has to respect dependency notation pattern `group:name:version`, in the given example: `com.domain:project2` because version is empty. – rojarand May 07 '22 at 09:33
  • I believe it was working fine like this at the time, but I am not sure. If you can point us the gradle doc about the correct usage of `project` it would be great, I could not find it. – Renaud May 07 '22 at 18:35
  • `dependencies{ implementation("com.domain:project2") }` is correct. Also needs to be `includeBuild("../project2")` presuming that project1 and project2 are in the same folder. – craig.tadlock May 12 '22 at 06:52
1

I have the same problem. Reading on the first link, the next para says:

Local forks of module dependencies

A module dependency can be substituted by a dependency to a local fork of the sources of that module, if the module itself is built with Gradle. This can be done by utilising composite builds. This allows you, for example, to fix an issue in a library you use in an application by using, and building, a locally patched version instead of the published binary version. The details of this are described in the section on composite builds.

So, it should be implementation project according to me.

P.S. The code completion is working on one of my sub project but not on the other. I am still trying to figure that out

Hemil
  • 916
  • 9
  • 27