gradle - 如何在使用Gradle构建胖罐的同时编译不同口味

原文 标签 gradle build.gradle v8 j2v8

How to compile different flavors while building a fat jar using Gradle

I want to include the Java Bindings for V8 ("J2V8") in a Java project. The reasons are that (i) the V8 JavaScript engine is much faster then the JavaScript engine shipped with the JRE and (ii) the library I am using is available in JavaScript only and a port to Java is much effort.

The issue is that J2V8 is compiled for different platforms: linux 64bit, macos 64bit, windows 64 bit, windows 32 bit.

I now want to generate different JARs, containing all the dependencies (fat jars):

  • jabref-linux_x86_64.jar
  • jabref-macosx_x86_64.jar
  • jabref-windows_x86_32.jar
  • jabref-windows_x86_64.jar
  • jabref-all.jar - the platform indipendent JAR without v8 engine

I am currently creating fat jars using the shadow plugin.

Note that the project is not an Android project. There, with the Android plugin, it seems to be straight-forward to do that.

The first idea is to introduce configurations and configuration-specific dependencies:

configurations {
    linux_x86_64Compile.extendsFrom compile
    macosx_x86_64Compile.extendsFrom compile
    windows_x86_32Compile.extendsFrom compile
    windows_x86_64Compile.extendsFrom compile
}

dependencies {
    compile configuration: 'linux_x86_64',   group: 'com.eclipsesource.j2v8', name: 'j2v8_linux_x86_x64',  version: '4.6.0'
    compile configuration: 'macosx_x86_64',  group: 'com.eclipsesource.j2v8', name: 'j2v8_macosx_x86_x64', version: '4.6.0'
    compile configuration: 'windows_x86_32', group: 'com.eclipsesource.j2v8', name: 'j2v8_win32_x86',      version: '4.6.0'
    compile configuration: 'windows_x86_64', group: 'com.eclipsesource.j2v8', name: 'j2v8_win32_x86_x64',  version: '4.6.0'
...
}

But now I'm stuck. In pseudocode, I'd like to do:

task releaseSingleJar(dependsOn: "shadowJar", name) {
    doLast {
        copy {
            from("$buildDir/libs/JabRef-${project.version}-fat.jar")
            into("$buildDir/releases/")

            rename { String fileName ->
                fileName.replace('-fat', '-$name')
            }
        }
    }
}

task releaseJars() {
  forEach name in "linux_x86_64", "macosx_x86_64", "windows_x86_32", "windows_x86_64", "all":
     if (name != "all") activate configuration $name
     releaseSingleJar($name)

shadowJar is from the shadow plugin.

Background information

Related questions

The question Using Gradle to manage Java web app with flavors like Android has a similar title, but asks for source directories, whereas I ask for dependencies. Further, I want to generate a fat JAR and there a plain JAR seems to be enough. However, it might be that the solution is similar. A hint was to use the gradle-java-flavours plugin with the main source being JavaFlavoursExtension.groovy.

Following questions are similar to this one. However, the setting is related to Android apps and not to plain Java apps.

Answer

You might be interested in my gradle-java-flavours plugin which creates source sets, configurations and compile, jar and test tasks for each flavour in a java only project.

eg:

import com.github.jengelman.gradle.plugins.shadow.tasks.*
plugins {
    id 'com.lazan.javaflavours' version '1.2'
    id 'com.github.johnrengelman.shadow' version '1.2.4'
}
def flavours = ['linux_x86_64', 'macosx_x86_64', ...]
javaFlavours {
    flavours.each {
        flavour it
    }
}
dependencies {
    linux_x86_64Compile      'aaa:aaa:1.0'
    linux_x86_64Runtime      'bbb:bbb:1.0'
    macosx_x86_64TestCompile 'ccc:ccc:3.0'
}
flavours.each { String flavour ->
    SourceSet flavourSourceSet = sourceSets.getByName(flavour)
    Configuration flavourRuntime = configurations.getByName("${flavour}Runtime")
    JavaCompile flavourCompileTask = tasks.getByName("compile${flavour.capitalize()}Java")
    Task shadowJarTask = tasks.create(name: "${flavour}ShadowJar", type: ShadowJar) {
        classifier = "${flavour}-all"
        dependsOn flavourCompileTask 
        // todo configure (likely based on Configuration and SourceSet)
    }
    artifacts {
        archives shadowJarTask 
    }
    // wire the task into the DAG
    assemble.dependsOn shadowJarTask
}

翻译

我想在Java项目中包含Java Bindings for V8(“ J2V8”)。原因是(i)V8 JavaScript引擎要比JRE随附的JavaScript引擎快得多,并且(ii)我正在使用的库仅在JavaScript中可用,并且需要大量移植到Java。

问题是J2V8是compiled for different platforms:Linux 64位,macos 64位,Windows 64位,Windows 32位。

我现在想生成包含所有依赖项(fat jars)的不同JAR:


jabref-linux_x86_64.jar
jabref-macosx_x86_64.jar
jabref-windows_x86_32.jar
jabref-windows_x86_64.jar
jabref-all.jar-没有v8引擎的平台独立JAR


我目前正在使用shadow plugin创建胖子。

请注意,该项目不是Android项目。在那里,使用Android插件似乎很简单。

第一个想法是介绍配置和特定于配置的依赖项:

configurations {
    linux_x86_64Compile.extendsFrom compile
    macosx_x86_64Compile.extendsFrom compile
    windows_x86_32Compile.extendsFrom compile
    windows_x86_64Compile.extendsFrom compile
}

dependencies {
    compile configuration: 'linux_x86_64',   group: 'com.eclipsesource.j2v8', name: 'j2v8_linux_x86_x64',  version: '4.6.0'
    compile configuration: 'macosx_x86_64',  group: 'com.eclipsesource.j2v8', name: 'j2v8_macosx_x86_x64', version: '4.6.0'
    compile configuration: 'windows_x86_32', group: 'com.eclipsesource.j2v8', name: 'j2v8_win32_x86',      version: '4.6.0'
    compile configuration: 'windows_x86_64', group: 'com.eclipsesource.j2v8', name: 'j2v8_win32_x86_x64',  version: '4.6.0'
...
}


但是现在我被卡住了。用伪代码,我想做:

task releaseSingleJar(dependsOn: "shadowJar", name) {
    doLast {
        copy {
            from("$buildDir/libs/JabRef-${project.version}-fat.jar")
            into("$buildDir/releases/")

            rename { String fileName ->
                fileName.replace('-fat', '-$name')
            }
        }
    }
}

task releaseJars() {
  forEach name in "linux_x86_64", "macosx_x86_64", "windows_x86_32", "windows_x86_64", "all":
     if (name != "all") activate configuration $name
     releaseSingleJar($name)


shadowJar来自影子插件。

背景资料


该视频显示了我们设置中的速度差异:https://github.com/JabRef/jabref/pull/2250#issuecomment-264824598
JabRef中集成的当前状态:https://github.com/JabRef/jabref/pull/3180


相关问题

问题Using Gradle to manage Java web app with flavors like Android具有相似的标题,但要求提供源目录,而我要求依赖项。此外,我想生成一个胖的JAR,而普通的JAR似乎就足够了。但是,解决方案可能相似。提示是使用gradle-java-flavours plugin,主要来源为JavaFlavoursExtension.groovy

以下问题与此类似。但是,该设置与Android应用程序相关,与普通Java应用程序无关。


How to define different dependencies for different product flavors
Gradle: add dependency for a specific flavour of the library
Change dependency through a task in gradle
Use different resources for different application flavors using gradle
最佳答案
您可能对我的gradle-java-flavours plugin感兴趣,它可以为纯Java项目中的每种样式创建源集,配置以及编译,jar和测试任务。

例如:

import com.github.jengelman.gradle.plugins.shadow.tasks.*
plugins {
    id 'com.lazan.javaflavours' version '1.2'
    id 'com.github.johnrengelman.shadow' version '1.2.4'
}
def flavours = ['linux_x86_64', 'macosx_x86_64', ...]
javaFlavours {
    flavours.each {
        flavour it
    }
}
dependencies {
    linux_x86_64Compile      'aaa:aaa:1.0'
    linux_x86_64Runtime      'bbb:bbb:1.0'
    macosx_x86_64TestCompile 'ccc:ccc:3.0'
}
flavours.each { String flavour ->
    SourceSet flavourSourceSet = sourceSets.getByName(flavour)
    Configuration flavourRuntime = configurations.getByName("${flavour}Runtime")
    JavaCompile flavourCompileTask = tasks.getByName("compile${flavour.capitalize()}Java")
    Task shadowJarTask = tasks.create(name: "${flavour}ShadowJar", type: ShadowJar) {
        classifier = "${flavour}-all"
        dependsOn flavourCompileTask 
        // todo configure (likely based on Configuration and SourceSet)
    }
    artifacts {
        archives shadowJarTask 
    }
    // wire the task into the DAG
    assemble.dependsOn shadowJarTask
}
相关推荐

gradle - Gradle compileKotlin includeRuntime未将运行时添加到jar

android - 如何从命令行自动接受android库许可?

maven - 如何将jcenter / jitpack作为远程存储库添加到Apache Archiva?

python - 我如何获得我的gradle测试任务以对不在maven Central上的库使用python pip install?

java - 如何将/ META-INF / BenchmarkList附加到jmh任务以修复“错误:无法找到资源:/ META-INF / BenchmarkList”

java - Java游乐场的Gradle任务

java - 用gradle在jar中生成pom.xml

java - Gradle:找不到名称为“ default”的配置

intellij-idea - 同步gradle项目和IntelliJ IDEA项目中的更改运行非常缓慢

java - gradle的调试目标等效于传递参数的run {}块