习惯性Gradle脚本构建'debug'和'release'JAR文件
我试图创建一个Gradle构建脚本,它将在'release'或'debug'模式下构建一个Java .jar
文件,并且无法参数化脚本。
问题是: 在使用Java插件的Gradle脚本中,通过何种惯用方式来实现这一点? (或者,如果没有惯用的方法,那么实际上有效的黑客解决方案是什么?)
我不介意参数化方法,只要命令行和IDE调用可以在两个输出选项之间轻松选择即可。 该jar文件将在其他项目中用作库,例如Android应用程序和JavaFX应用程序,所以我希望参数化方法可以从他们自己的Gradle脚本中调用/依赖。
理想情况下,我想“模拟”Android Gradle插件的每个任务的调试/发布版本的能力,即
$ ./gradlew build
$ ./gradlew assembleRelease
$ ./gradlew checkDebug
但如果失败了,即使是顶级的buildDebug和buildRelease也是合适的。
我试过的东西
本节与问题无关。
初始点
我有以下gradle文件/项目:
group 'TestGradleProjectGroup'
apply plugin: 'java'
sourceCompatibility = 1.8
version '1.0-release'
compileJava {
options.debug = false
}
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
}
这工作正常,并生成jar文件:
$ ls TestGradleModule/build/libs/
TestGradleModule-1.0-release.jar
当用javap
检查提取的类时,它不包含任何调试信息。 欢呼。 不,我们需要一种方法来制作调试版本。
添加调试和发布任务
version '1.0-release'
compileJava {
options.debug = false
}
task buildRelease(type: GradleBuild, dependsOn: build) {
project.version = '1.0-release'
compileJava {
options.debug = false
}
}
task buildDebug(type: GradleBuild, dependsOn: build) {
project.version = '1.0-debug'
compileJava {
options.debug = true
}
}
这不起作用,因为调试项目总是被构建,即使buildRelease是命令行上给出的任务。 我想这是因为两个任务的代码都是在配置时(Gradle构建生命周期)运行的,而我只想运行一个。 所以我想我想在执行时间运行它们?
添加一些doLast任务
version '1.0-release'
compileJava {
options.debug = false
}
task buildRelease(type: GradleBuild, dependsOn: build) {
doLast {
project.version = '1.0-release'
compileJava {
options.debug = false
}
}
}
task buildDebug(type: GradleBuild, dependsOn: build) {
doLast {
project.version = '1.0-debug'
compileJava {
options.debug = true
}
}
}
这更糟糕。 输出文件始终是1.0版本,这是因为顶层的“默认”。 如果我发表评论,那么不会创建一个版本化的jar,而是TestGradleModule.jar
的默认值。 似乎doLast块的内容对compileJava任务的影响完全没有用处(但对此没有任何警告)。 我猜这些修改已经太迟了,不能在执行时完成,或者需要做其他事情,以便compileJava任务的“配置”不同。
使用配置?
我注意到Java插件的手册中包含对buildConfigName
和uploadConfigName
的引用,并声称它们依赖于“配置ConfigName中产生工件的任务”。 鉴于我在配置时没有参数化,插件能够做到这一点看起来很有希望:
group 'TestGradleProjectGroup'
apply plugin: 'java'
sourceCompatibility = 1.8
configurations {
debug
release
}
version '1.0-release'
compileJava {
options.debug = false
}
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
}
但:
buildRelease
或buildDebug
添加到./gradlew tasks --all
的输出中 - ./gradlew tasks --all
,正如我预期的那样。 但我可以运行这些任务。 buildRelease
和buildDebug
,而不是例如assembleRelease
等 buildRelease
在运行时似乎不依赖于任何东西,因此没有任何有用的效果。 迭代任务?
作为最后的尝试,我试图创建所有适当的任务并链接所有事物的依赖关系。 我试着迭代任务并添加依赖关系:
gradle.taskGraph.whenReady { taskGraph ->
taskGraph.allTasks.each { taskIter ->
println("iterating" + taskIter)
def releaseTask = project.task(taskIter.name + "Release")
def debugTask = project.task(taskIter.name + "Debug")
taskIter.dependsOn += [releaseTask, debugTask].toSet()
println("new taskIter.dependsOn:" + taskIter.dependsOn)
/*
set debug mode here,
copy over effects of task to debug/release
disable effects of task
*/
}
}
但
总之,我不知道我在做什么。 作为最后的手段,我可以手动创建所有的任务,但这似乎打败了使用Java插件的重点,并且非常垃圾?
你是否需要用一次gradle创建两个罐子? 如果不是这样,它可以像使用一些额外的参数到gradle一样简单,比如
compileJava {
options.debug = project.hasProperty('debugBuild')
}
gradle assemble -PdebugBuild=true # or false
有关文档,请参阅此处:https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_properties_and_system_properties
也不是说你可能会在Gradle论坛中获得更好的帮助。
不知道,但也许我的gradle-java-flavors插件可以在这里帮助。 例如:
plugins {
id "com.lazan.javaflavours" version "1.2"
}
javaFlavours {
flavour 'debug'
flavour 'release'
}
debugJar {
version = "${project.version}-debug"
}
releaseJar {
version = "${project.version}-release"
}
每种风格都有它自己的Jar
和JavaCompile
任务等,您可以指定自定义源,资源,测试,每种风味的依赖关系。
请参阅这里了解有关可用的任务,目录和配置的更多概述,以及用于涵盖功能的测试。
这种方法与GradleBuild
风格不同,因为“风味”可以愉快地生活在一个项目中,这个项目可以构建多个构件,而不是使用两个不同的参数运行两次项目。
由于您对问题进行了深入分析,因此您的问题很详细。 尽管我相信如果你想以更简单的方式思考,这个问题就可以解决。
因此,如果我们认为简单,那么针对您的案例可能的解决方案是在发布完成后运行调试任务。 看下面的例子:
compileJava {
options.debug = false
}
task buildRelease(type: GradleBuild, dependsOn: build) {
doLast {
project.version = '1.0-release'
compileJava {
options.debug = false
}
}
}
task buildDebug(type: GradleBuild, dependsOn: build) {
doLast {
project.version = '1.0-debug'
compileJava {
options.debug = true
}
}
}
// Here you are telling the buildDebug task to be executed right after the
// buildRelease task is finalized.
buildDebug.mustRunAfter buildRelease
以上述方式控制任务执行的顺序,而不会在它们之间引入明确的依赖关系。
链接地址: http://www.djcxy.com/p/40887.html上一篇: Idiomatic Gradle script to build 'debug' and 'release' JAR files
下一篇: Keep Background Image from Resizing During CSS Animation and Remove Flicker