Gradle: Include the same SourceSet in Multiple subprojects

685 views Asked by At

How would I add a single source set to multiple subprojects?

First of all ... yes I know how ridiculous this is. This is just something I have to do.

The setup

  • The project uses the Groovy DSL.
  • There are 3 subprojects (A,B,C), each with there own unique main source set.
  • There are 5 additional sourcesets (1, 2, 3, 4, 5) external to these projects.
  • Nonce of the external sourcesets can be compiled alone.
  • All of the source sets depend on an interface that is defined 3 different times in each subproject.
  • The subproject main source cannot depend on any of the external sources
  • 1 and 2 need to be compiled with A, B, and C.
  • 3 needs to be compiled with A and also B.
  • 4 needs to be compiled with B and also C
  • 5 needs to be compiled with C only.
  • 4 and 5 need depend on a class defined in 2.
  • 5 must be a standalone sourceset so that it can be included as a sourceset inside of any future subprojects that might be added.
  • None of the external sources are allowed to include sources from any other sourceset
  • None of the external sources are allowed to be compiled alone.
  • None of the external sources are allowed to be included as a jar or project dependency; they MUST be included as a source set and they MUST be compiled seperately for each subproject that includes them.

A

sourceSets {
    main {
        java {
            srcDirs = ["src",
                       "$rootDir/source_sets/1/src",
                       "$rootDir/source_sets/2/src",
                       "$rootDir/source_sets/3/src"
            ]
        }
    }
}

B

sourceSets {
    main {
        java {
            srcDirs = ["src",
                       "$rootDir/source_sets/1/src",
                       "$rootDir/source_sets/2/src",
                       "$rootDir/source_sets/3/src",
                       "$rootDir/source_sets/4/src"
            ]
        }
    }
}

C

sourceSets {
    main {
        java {
            srcDirs = ["src",
                       "$rootDir/interfaces/source_sets/1/src",
                       "$rootDir/interfaces/source_sets/2/src",
                       "$rootDir/interfaces/source_sets/4/src",
                       "$rootDir/interfaces/source_sets/5/src"
            ]
        }
    }
}

settings.gradle

include(":interfaces/A")
project(":interfaces/A").name = "A"

include(":interfaces/A")
project(":interfaces/A").name = "A"

include(":interfaces/A")
project(":interfaces/A").name = "A"

The problem is that 4 and 5 are not able to find the class in 2, and my IDE (IntelliJ) cannot resolve the correct classpath.

Really what I need is for the external sourcesets to act as if there were 3 separate copies of them without there actually being 3 separate copies, and I need to do it without the use of symbolic/soft links.

The solution needs to only use gradle, but it can use JetBrains "idea" plugin for gradle so long as it doesn't involve committing any files under the ".idea" folder, but it can include inline xml or files in a resource folder outside of the .idea folder.

So yeah ... this is overly complicated and just .. ugh! But that's just how it is.

1

There are 1 answers

0
Bjørn Vester On

Ugh indeed.

I don't have an answer, but this is too long to put into a comment. So here goes.

I assume this is a problem with IntelliJ only, and not when compiling with Gradle, right? If that is the case, you should try and model your project in IntelliJ as you want it, and once you have found a way to do it, then figure out how to use customize the Idea plugin to do it for you.

However, I am pretty sure you can't have multiple modules in IntelliJ share the same "content root". So I only see the options left that you don't want - which is either to copy (synchronize) the sources with a new folder only used for IntelliJ (which won't allow for modifications), create symlinks (which aren't always portable) or to restructure your external sources so they can be compiled independently (which may not be easily possible)

:-(