Gradle初探

自己最近又在用JVM系的语言开新坑。这次终于说服自己从Jetbrains的温床里脱离出来改用了大家都在用的Gradle!感觉良好,在这里简单写一下大概咋用,给之后的自己留一个参考吧。

为什么自己要用Gradle呢?

  1. Gradle作为一个开源的构建系统不与任何IDE绑定(比如说IDEA),这相当于增加了代码的兼容性。
  2. Gradle里面可以直接从Maven Central上下库下来,省了我手动下库导入的过程,库更新了也好维护。这对我来说非常地有诱惑力。实测也非常舒服。
  3. Gradle从设计上来说非常灵活,Gradle默认的构建脚本是用Groovy写的(当然也可以用Kotlin但是这似乎不是主流的样子),而不是只有标记功能的XML,这使Gradle一下子非常强大。
  4. 大家都在用的样子。
  5. IDEA对于Gradle的支持非常棒!(所以到头来自己还是没有逃脱JB的舒适圈……)

虽然说Gradle的功能很强大我目前的用法还是最初级的。我目前用的Gradle代码大致如下:

plugins {
    id 'java'
    id 'org.jetbrains.kotlin.jvm' version '1.3.61'
}

group 'chengyuan'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8
project.ext.lwjglVersion = "3.2.3"
project.ext.lwjglNatives = "natives-windows"

repositories {
    maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
    mavenCentral()
}

dependencies {
    implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
    
    implementation "org.lwjgl:lwjgl"
    implementation "org.lwjgl:lwjgl-assimp"
    implementation "org.lwjgl:lwjgl-bgfx"
    implementation "org.lwjgl:lwjgl-glfw"
    implementation "org.lwjgl:lwjgl-nanovg"
    implementation "org.lwjgl:lwjgl-nuklear"
    implementation "org.lwjgl:lwjgl-openal"
    implementation "org.lwjgl:lwjgl-opengl"
    implementation "org.lwjgl:lwjgl-par"
    implementation "org.lwjgl:lwjgl-stb"
    implementation "org.lwjgl:lwjgl-vulkan"
    runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
    runtimeOnly "org.lwjgl:lwjgl-assimp::$lwjglNatives"
    runtimeOnly "org.lwjgl:lwjgl-bgfx::$lwjglNatives"
    runtimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives"
    runtimeOnly "org.lwjgl:lwjgl-nanovg::$lwjglNatives"
    runtimeOnly "org.lwjgl:lwjgl-nuklear::$lwjglNatives"
    runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives"
    runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
    runtimeOnly "org.lwjgl:lwjgl-par::$lwjglNatives"
    runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives"
    
    testCompile group: "junit", name: "junit", version: "4.12"
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

首先是plugins这段,这一段虽然重要但一般用不着特别操心,按照我的理解大概是语言支持的插件。

接下来是版本、JVM版本之类的,看着也很明白。

然后可以申明一些接下来会用到的常量。

repository告诉Gradle从哪里找库。常见的源有内置的函数,例如mavenCentral()jcenter()。如果是其他的Maven源也可以指定URL。比如说我这里用了阿里云的Maven镜像,在国内速度就会快上很多。

接下来是dependencies,这个是重头戏。

最常见的是implementation,这个后面一般跟库的Maven id。如果想直接引用本地文件可以用files(...),如果是一个平台一个版本的可以用platform(...)。基本上这就覆盖了99%的用途。

此外还有runtimeOnly,这个和implementation的区别就是runtimeOnly的库是不参与编译的,只在运行期有效。这一般都是用JNI的一众native库和一些二级库。

还有testCompile,用这个修饰的库是只在跑单元测试的时候依赖的,因此基本上都是一些测试有关的库。我人懒,平时懒得写单元测试,因此这个我基本上不用。

这些就是我目前摸索出来的Gradle的基本用法,目前的感觉就是把IDEA里面的很多GUI的操作文字化,非常舒适,省了很多麻烦。更复杂的用法例如自定义build task等都可以在官网上找到(文档很丰富也是Gradle比较吸引人的点)。

最后有一点点想吐槽,就是Groovy似乎单引号和双引号都可以表示字符串。双引号的字符串支持插值,这似乎是唯一的予以区别。IDE默认生成的是单引号,LWJGL的打包器生成的是双引号,似乎最通用的是双引号,自己到底是用双引号还是单引号呢?这种东西真的是万恶之源。