2017-04-16 43 views
1

我正在使用Gradle构建一个涉及本机库的Java项目。我有定义的任务jniHeaders如何追加一个Gradle任务而不使用`dependsOn`?

jniHeaders.dependsOn classes 

所以当我输入gradle jniHeaders,它将编译Java类和生成JNI头。到现在为止还挺好。

但我觉得打字gradle jniHeaders不是很自然。 99%的时间,如果你成功编译Java类,你也想生成JNI头文件。如果我可以用gradle classes编译Java类并在一个步骤中生成JNI头文件,那将会很好。

换句话说,我想任务jniHeaders添加到任务classes结束,但前提是classes成功地完成,实际上做了一些工作。

classes.doLast想起来,但我无法告诉它执行另一项任务。 classes.finalizedBy jniHeaders在某种程度上起作用,但生成JNI标头,无论classes的结果如何。我想我可以添加一些Groovy逻辑来获得我想要的确切行为,但我也怀疑必须有一种更简单的方法。

任何人有任何建议吗?

+0

是否调用多数民众赞成窃听你一个看似随意的任务只是概念?我可能会试图定义另一个任务'allTheThings'(或其他任何!),它们只依赖于'classes'和'jniHeaders'。这似乎比添加精品构建逻辑简单得多:) –

回答

1

将构建模型化为任务图的重点在于存在一个简单且健壮的执行模型。我建议你创建一个函数compileJNIHeaders(),并把它放在Gradle可以访问的地方(build.gradle本身以及buildSrc/src/main/groovy),这样你就可以轻松开发和测试它。

此功能可以在最适当的步骤来执行:

  • classes.doFirst(如果标题是您自己的代码)
  • classes.doLast(如果标题是依赖项目)
  • 放于一个任务compileJNIHeaders,它是您用于将项目打包为其部署格式的任务的依赖关系
+0

谢谢。我试图操纵依赖关系图,并忘记了最简单的模块化方法。 –

1

y有两个部分我们的问题:

  1. 添加任务jniHeaders成功编译java类后执行。
  2. 只有在完成任何工作后才执行jniHeaders任务。

由于classes任务是processResourcescompileJava的组件(见java plugin doc),我认为这是更好地钩到compileJava任务。正如你发现你自己,这可以用finalizedBy完成。另外,如果没有完成工作,则需要跳过该任务,例如,通过在您的jniHeaders任务中添加onlyIf声明。

例子:

task jniHeaders { 
    onlyIf { !sourceSets.main.allJava.empty } 
    doLast { 
     println "GENERATE JNI HEADERS for $project.name" 
    } 
} 
compileJava.finalizedBy jniHeaders 
+0

谢谢。但是我尝试了你的代码,它并没有像预期的那样工作。即使'compileJava'失败,'jniHeader'仍然会被执行,因为大概'allJava'不是空的! (我没有从一个干净的构建目录开始)无论如何,我采用了@ Raffaele的解决方案。感谢您的建议。 –