nPn
nPn

Reputation: 16758

How do I create distributions with different dependencies using Gradle application/distribution plugin?

I am building a small Kotlin project in IntelliJ, Idea, and trying to figure out how to create multiple tar/zip files with customizations for each OS I want to support.

It seems like the distribution plugin (which is included when you use the application plugin) is the right direction, but I can't seem to figure out how to get it to do what I want.

I have read the documentation on the plugin, which can be found here, but it's not really clear to me how to accomplish what I want to do.

Here is an example build.gradle that shows at least the idea of what I want to do, that is to have a base application setup and then have some minor tailoring for each of the 3 OSs.

For example each of the 3 OSs need a unique version of the SWT library. The macos version needs a specific JVM setting, and for the linux version, I need to tailor the startup script to add some environment variables.

Is this possible with the distribution plugin? If not can someone suggest a different solution?

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.2.61'
}

apply plugin: 'application'

mainClassName = "MainKt"

version '1.0-SNAPSHOT'

repositories {
    // my common required repos
}

dependencies {
    // my common dependencies    
}

distributions {
    macos {
        contents { from 'src' }
        applicationDefaultJvmArgs.push("-XstartOnFirstThread")
        dependencies {
            implementation "org.eclipse.swt:org.eclipse.swt.cocoa.macosx.x86_64:4.5.2"
        }
    }
    linux {
        contents { from 'src' }
        dependencies {
            implementation "org.eclipse.swt:org.eclipse.swt.gtk.linux.x86_64:4.5.2"
        }
        startScripts.doLast {
            def lines = unixScript.text.readLines()
            println lines.add(1, '# add some stuff')
            println lines.add(2, '# add some more stuff')
            unixScript.text = lines.join("\n")
        }
    }
    windows {
        contents { from 'src' }
        dependencies {
            implementation "org.eclipse.swt:org.eclipse.swt.win32.win32.x86_64:4.5.2"
        }
    }
}



compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

Update

This is what I am doing now, but I would like to improve on this.

I have a variable

def deploy = false
if (!deploy) {
    applicationDefaultJvmArgs.push("-XstartOnFirstThread")
    dependencies {
        implementation "org.eclipse.swt:org.eclipse.swt.cocoa.macosx.x86_64:4.5.2"
    }
} else {
    dependencies {
        implementation "org.eclipse.swt:org.eclipse.swt.gtk.linux.x86_64:4.5.2"
    }
    startScripts.doLast {
        def lines = unixScript.text.readLines()
        println lines.add(1, 'export foo=foo')
        println lines.add(2, 'export bar=bar')
    }
}

Right now I develop on my mac and set deploy to false. When I want to generate the distribution for linux I set deploy to true. I could add more code and do the same thing for windows, but I would like to just generate all the code in one task, and have it in different tar/zip files.

Upvotes: 1

Views: 1664

Answers (1)

nPn
nPn

Reputation: 16758

Opal provided some very good suggestions in the question comments that I tried, but in the end, I was not able to really get what I wanted.

Here is my current workaround solution it does pretty much what I was hoping I could have done with the distribution plugin.

Basically I create an osType property and set it's "default" to the os I am developing on, in this case macos. Then I have all my common dependencies in one dependency closure and add in the the os specific stuff in a groovy switch statement. I then just coded up a short shell script that overrides the osType property to each of the os's I want to support and calls the gradle task to build each in turn.

Here is my build.gradle file.

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.2.61'
    id 'application'
}

ext {
    swtVersion = "4.5.2"
}

ext.osType = project.properties['osType'] ?: 'macos'
println "building for ${osType}"

mainClassName = "MainKt"

repositories {
    mavenCentral()
    maven { url "http://maven-eclipse.github.io/maven" }
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
}

switch(osType) {
    case 'macos':
        dependencies {
            implementation "org.eclipse.swt:org.eclipse.swt.cocoa.macosx.x86_64:${swtVersion}"
        }
        applicationDefaultJvmArgs.push("-XstartOnFirstThread")
        break
    case 'linux':
        dependencies {
            implementation "org.eclipse.swt:org.eclipse.swt.gtk.linux.x86_64:${swtVersion}"
        }
        startScripts.doLast {
            def lines = unixScript.text.readLines()
            println lines.add(1, 'export FOO=foo')
            println lines.add(2, 'export BAR=bar')
            unixScript.text = lines.join("\n")
        }
        break
    case 'windows':
        dependencies {
            implementation "org.eclipse.swt:org.eclipse.swt.win32.win32.x86_64:${swtVersion}"
        }
}

version "${osType}-1.0-SNAPSHOT"

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"

and here is my shell script (buildAll.sh) that I run from the terminal in Idea.

#!/bin/sh
./gradlew -PosType=macos distTar
./gradlew -PosType=linux distTar
./gradlew -PosType=windows distTar
./gradlew -PosType=windows distZip

Upvotes: 2

Related Questions