суббота, 2 мая 2015 г.

Speed up libgdx gradle build in Intellij IDEA

This article describes how to exclude running unnessary tools when building for concrete platform. Here I will make an example for desktop and Android platform, but builds for other platforms can be optimized that way too. The main idea is to move all gradle staff, related to project to it's gradle's build file. So, the way it's designed. Nothing new. While this post may be outdated, see complete and update example project on github . I'm using Android Studio, but IDEA may be used too. And yes, only gradle is here and no Eclipse. I'm a professional programmer and I believe, that Android Studio is far way better than Eclipse if it is set up well.

So, here are the steps to make IDE build fast.
Package name everywhere must be your libGDX project package, as usual.
1. Create a new libgdx projects. We need it to get all the latest dependencies versions.
2. Create new Android Application. Targeting 4.0 you'll target > 90 % of devices in the world. Name main class DesktopLauncher, like in project, we created in (1) step.
3. File -> New submodule -> Other (More) -> Java library. Name it "core". "MainGame" is for class name.
4. Now, copy all the source code from MainGame.java from (1) to our new MainGame.java. See, compiler complains? Ok, we are going the right way.
5. Open core/build.gradle and copy all the dependencies from build.gradle (1), you need project(":core") section. It will look something like this:
project(":core") {
    apply plugin: "java"


    dependencies {
        compile "com.badlogicgames.gdx:gdx:$gdxVersion"
        compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
        compile "com.badlogicgames.box2dlights:box2dlights:$box2DLightsVersion"
        compile "com.badlogicgames.ashley:ashley:$ashleyVersion"
        compile "com.badlogicgames.gdx:gdx-ai:$aiVersion"
        compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
        compile "com.badlogicgames.gdx:gdx-bullet:$gdxVersion"
    }
}
Just copy all the dependencies from here to your new core/build.gradle file in the root. Do not place it under any other tag.
6. As you see, you'll need versions, copy them too. You'll end up with something like that in core/build.gradle:
buildscript {
    ext {
        kotlin_version = '0.11.91.4'
        gdxVersion = '1.5.2'
        box2DLightsVersion = '1.3'
        ashleyVersion = '1.3.1'
        aiVersion = '1.4.0'
    }
}
7. Click "gradle sync" button (green in circle with an arrow). If MainGame.java still not compiling, add the repo dependencies to core/build.gradle:
repositories {
    mavenCentral()
}
8. Now it must compile well. You'll get something like that:
apply plugin: 'java'

buildscript {
    ext {
        gdxVersion = '1.5.2'
        box2DLightsVersion = '1.3'
        ashleyVersion = '1.3.1'
        aiVersion = '1.4.0'
    }
}
repositories {
    mavenCentral()
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    compile "com.badlogicgames.gdx:gdx:$gdxVersion"
    compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
    compile "com.badlogicgames.box2dlights:box2dlights:$box2DLightsVersion"
    compile "com.badlogicgames.ashley:ashley:$ashleyVersion"
    compile "com.badlogicgames.gdx:gdx-ai:$aiVersion"
    compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
    compile "com.badlogicgames.gdx:gdx-bullet:$gdxVersion"
}
9. Repeat steps 4-8 to android (app) project: copy code in AndroidLauncher.java from (1). And don't copy natives. You'll get something like that in android/build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "com.gamelift.koten"
        minSdkVersion 14
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

buildscript {
    ext {
        gdxVersion = '1.5.2'
        box2DLightsVersion = '1.3'
        ashleyVersion = '1.3.1'
        aiVersion = '1.4.0'
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(':core')
    compile "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
    compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
    compile "com.badlogicgames.box2dlights:box2dlights:$box2DLightsVersion"
    compile "com.badlogicgames.ashley:ashley:$ashleyVersion"
    compile "com.badlogicgames.gdx:gdx-ai:$aiVersion"
    compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
    compile "com.badlogicgames.gdx:gdx-bullet:$gdxVersion"
}

10. Copy application theme to res/values/styles.xml. You'll get something like this:
<resources>

    <style name="AppTheme" parent="android:Theme">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:colorBackgroundCacheHint">@null</item>
        <item name="android:windowAnimationStyle">@android:style/Animation</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowFullscreen">true</item>
    </style>

</resources>

11. Update AndroidManifest.xml according manifest from (1). It will look like:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gamelift.koten.android" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".AndroidLauncher"
            android:label="@string/app_name"
            android:screenOrientation="landscape"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
12. Now android should compile.
13. If you run your app now (just by clicking "run" (green button on the top)) it'll crash. It's because we've not copied libraries, implemented in "c" language. You may just copy all files from android/libs (1) to android/src/main/jniLibs like that is done in Unity when you export android project :) Running now you will see badlogic's standart smile on red screen.
13. For desktop project we create File -> New submodule -> Other (More) -> Java library project.
14. "desktop" is for name. "DesktopLauncher" is for class name to create automatically.
15. Repeat steps 4-8 to desktop. You must get something like that in desktop/build.gradle:

apply plugin: 'java'

buildscript {
    ext {
        gdxVersion = '1.5.2'
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(":core")
    compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"
    compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
    compile "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop"
    compile "com.badlogicgames.gdx:gdx-tools:$gdxVersion"
    compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
    compile "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-desktop"
}
16. To run desktop configuration go to run... -> Edit configurations... -> Click "+" -> Application (Java) and provide the following:
<packages>.DesktopLauncher for main class
../android/src/main/assets for working directory
and name it "desktop" for example
17. (optional) If you want to rename "app" -> "android" it's not straitforward. The most safe way is to shutdown Android Studio. Delete .idea and all *.iml files. Now, rename directory "app" -> "android". Open settings.gradle in text editor and change ":app" to ":android". You'll get something like:

include ':android', ':core', ':desktop'

Now start Android Studio. Import project (gradle). It will take more time, than usual.

Working project can be found on my github. So, what we've archived? As I said earlier we don't waste time waiting for some plugins or dependencies to be downloaded, indexed, etc. We just run for concrete platform and concrete plugins are loaded and used to compile and run. On my Core i3 pc I've got about 10 times increased build time. And now I don't need to make a cup of coffee while AS is opening my project.

Let's think, what drawbacks were in old build.gradle files. At the time of writing this post libgdx has one main build.gradle at the root of the project and many build.gradle specified per each platform (one in android, one in desktop...).

1. So, main build.gradle contains all the plugins:
buildscript {
    dependencies {
        classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
        classpath 'com.android.tools.build:gradle:1.0.0'
        classpath 'org.robovm:robovm-gradle-plugin:1.0.0-beta-01'
    }
}
I don't need all those plugins when I just want to build desktop for example.

2. And allprojects section, which apply some plugins too:

allprojects {
    apply plugin: "eclipse"
    apply plugin: "idea"
}

"eclipse" is not needed. "idea"'s modern plugin implementation is used by default.
See complete (and updated) example on github

Комментариев нет:

Отправить комментарий