How to support multiple projects in multiple langu

2020-05-28 11:17发布

问题:

I am trying to convert our antiquated Ant build to Gradle. The project contains about Java 50 sub-projects and 10 Scala sub-projects. The Java projects only contain Java and the Scala projects only Scala. Each project is getting built by Java then Scala which is slowing down our build considerably.

I want to place as much common logic in the root build.gradle file as possible which looks like this:

subprojects {
    apply plugin: 'java'
    apply plugin: 'scala'

    sourceCompatibility=1.7
    targetCompatibility=1.7

    sourceSets {
        main {
            scala {
                srcDir 'src'
            }
            java {
                srcDir 'src'
            }
        }
        test {
            scala {
                srcDir 'test'
            }
            java {
                srcDir 'test'
            }
        }
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        scalaTools "org.scala-lang:scala-compiler:2.9.3"
        compile "org.scala-lang:scala-library:2.9.3"
    }

    // Use the sbt compiler (not scalac ant task)
    tasks.withType(ScalaCompile) {
        scalaCompileOptions.useAnt = false
    }

    task showCompileClasspath << {
       sourceSets.main.compileClasspath.each { println it }
    }

    test {
        systemProperty "user.dir", projectDir
    }
}

When I run my build I get the following output, notice that :esb-server:compileJava and :esb-server:compileScala contain the same warnings, so the classes are being built twice. Also notice that every other project contains a compileJava and compileScala

:common:assemble
:esb-server:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:esb-server:compileScala
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:esb-server:processResources UP-TO-DATE
:esb-server:classes
:esb-server:jar
:esb-server:assemble
:plugins:compileJava UP-TO-DATE
:plugins:compileScala UP-TO-DATE
:plugins:processResources UP-TO-DATE
:plugins:classes UP-TO-DATE
:plugins:jar
:plugins:assemble
:raas-transform:assemble
:saxonee-helper:assemble
:scala-common:compileJava UP-TO-DATE
:scala-common:compileScala
/Users/iain.hull/code/trunk/ccdev/scala-common/src/com/workday/esb/assembly/audit/TreeAudit.scala:138: method first in trait IterableLike is deprecated: use `head' instead
    override def getLast():Option[AuditNode] = if (children.isEmpty) None else children.first.getLast
                                                                                        ^
one warning found
:scala-common:processResources UP-TO-DATE
:scala-common:classess
:scala-common:jar
:scala-common:assemble
:plugins:hibernatepersistence:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
:plugins:hibernatepersistence:compileScala
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
:plugins:hibernatepersistence:processResources
:plugins:hibernatepersistence:classes
:plugins:hibernatepersistence:jar
:plugins:hibernatepersistence:assemble

I know that the two apply plugin lines at the top of my root build.gradle are causing this behaviour. However if I only apply the correct plugin to each subproject I cannot refactor the common configuration into my root build.gradle. Another approach would be to just use the Scala plugin for everything, but is this the best way?

Can I use the Java plugin to compile Java projects and the Scala plugin to compile Scala projects, and still refactor common build configuration across all my projects to the root build.gradle? What is the best way to support multiple languages like this in Gradle?

回答1:

How about something like this:

configure(subprojects.findAll {project  ->
    file('src/main/java').exists()
}) {
    apply plugin: 'java'
}

configure(subprojects.findAll {project  ->
    file('src/main/scala').exists()
}) {
    apply plugin: 'scala'
}

Because your source directory is src, some other discriminator mechanism inside the closures is needed.