我正在尝试创建一个Gradle构建脚本,该脚本将在“发布”或“调试”模式下构建一个Java .jar
文件,但在参数化该脚本时遇到问题。
问题是:在Gradle script中使用Java做这件事的惯用方法是什么?(或者,如果没有惯用的方法,什么是真正有效的hacky解决方案?)
我不介意参数化的方法,只要命令行和IDE调用可以很容易地在两个输出选项之间进行选择即可。jar文件将在其他项目中作为库使用,例如安卓应用程序和JavaFX应用程序,所以我希望参数化的方法可以从他们自己的Gradle脚本中调用/依赖。
理想情况下,我想“模仿”Android gradle插件的能力,即每个任务都有一个Debug/Release版本。
$ ./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 build lifecycle)运行的,而我只想让其中一个任务运行。所以我想我想在执行时运行它们?
添加一些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-release,这是因为顶层的'default‘。如果我将其注释掉,则不会生成版本化的jar,而是默认设置为TestGradleModule.jar
。似乎doLast块的内容对compileJava任务的影响是完全无用的(但是没有关于这方面的警告吗?)。我猜这些修改太晚了,不能在执行时完成,或者还有其他事情需要做,以便以不同的方式“配置”compileJava任务?
使用配置?
我注意到the Java plugin的手册中包含了对buildConfigName
和uploadConfigName
的引用,并声称它们依赖于“在configuration 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
的输出中。但我可以运行这些任务。buildRelease
和buildDebug
,而不是例如,assembleRelease
tasks在运行时似乎不依赖于任何东西,因此没有任何有用的效果。迭代任务?
作为最后一次尝试,我尝试创建所有合适的任务,并将所有内容的依赖关系链接起来。我尝试迭代任务并添加依赖项:
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插件的意义,而且非常垃圾?
发布于 2017-11-29 09:53:23
您是否需要使用单次运行gradle来创建两个jars?如果不是,那么只需对gradle使用一些额外的参数,例如
compileJava {
options.debug = project.hasProperty('debugBuild')
}
gradle assemble -PdebugBuild
也不是说你可以在gradle论坛上得到更好的帮助。
发布于 2017-12-05 17:15:11
你的问题很详细,因为你对问题进行了深入的分析。虽然我相信如果你能以更简单的方式思考,这个问题是可以解决的。
因此,如果我们认为简单,对您的情况一个可能的解决方案是在发布完成后运行调试任务。如下例所示:
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
通过上述方式,您可以控制任务执行的顺序,而不会在它们之间引入显式的依赖关系。
发布于 2017-12-05 18:11:17
不确定,但也许我的gradle-java-flavours插件可以在这里提供帮助。例如:
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
任务等,你也可以为每种风格指定定制的源代码、资源、测试和依赖关系。
有关可用任务、目录和配置的更多概述,请参见here;有关涵盖该功能的测试,请参阅here。
这种方法不同于您的GradleBuild
风格,因为“味道”可以愉快地生活在构建多个工件的单个项目中,而不是使用两个不同的参数运行两次项目。
https://stackoverflow.com/questions/47390481
复制相似问题