JetBrains-Research / jbr

JBR Genome Browser
https://doi.org/10.1093/bioinformatics/btab376
11 stars 0 forks source link

Switch Windows distrib building on jpackage #284

Open olegs opened 1 day ago

olegs commented 1 day ago
def createUnpackZipTask(File downloadFile, String jdkName) {
    def unpackDir = "${downloadFile.parent}\\${jdkName - ".zip"}\\"
    def downloadTaskName = "download${jdkName.capitalize()}"
    def unpackTasksName = "unpack${jdkName.capitalize()}"
    assert os() == "windows"
    task(unpackTasksName, type: Copy, dependsOn: downloadTaskName, group: "amazon-corretto") {
        inputs.file(downloadFile)
        // outputs is destination folder
        doFirst {
            Files.createDirectories(Paths.get(unpackDir))
            delete "$unpackDir\\jdk"
        }
        from zipTree(downloadFile)
        into { unpackDir }
        includeEmptyDirs = false
        doLast {
            // Unpacked Jdk folder
            def jdkFolder = ""
            new File(unpackDir).eachDir { jdkFolder = it.name }
            file("$unpackDir\\$jdkFolder").renameTo(file("$unpackDir\\jdk"))
        }
    }
    cleanSetupAmazonCorretteChainToJLink.dependsOn("cleanUnpack${jdkName.capitalize()}")
    file("$unpackDir\\jdk")
}

// ---------------------------------------------------------------------------------------------------------------------
// ---------- Windows Distribution -------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
// Tasks pipeline when doSignApp() is
// false
//      createWinExe -> createWinDistrib
// true
//      createWinExe -> signWinExe -> createWinDistrib
//
def createWinExeTask(File fullJdkPath, String jdkName, String os, String arch) {
    if (os != "windows") {
        return
    }
    def unpackTaskName = "unpack${jdkName.capitalize()}"

    String jpackage = getJPackagePath(os, fullJdkPath)
    def appDir = "${project.buildDir}\\${project.distsDirName}\\winexe"
    def exePath = "${appDir}\\${project.appName}.exe"

    def newTask = task("createWinExe", type: Exec, group: "distribution", dependsOn: [shadowJar, unpackTaskName]) {
        description "Create exe using standard Java jpackage commands."

        def jarPath = project.tasks.shadowJar.outputs.files.asPath

        inputs.dir(fullJdkPath)
        inputs.file(jarPath)
        outputs.file(exePath)

        doFirst {
            delete exePath
        }
        commandLine jpackage,
                "--type", "exe",
                "--name", project.appName,
                "--input", "${project.buildDir}\\libs\\",
                "--main-jar", project.tasks.shadowJar.archiveName,
                "--dest", "${exePath}",
                "--icon", "${projectDir}\\src\\main\\resources\\icons\\JBR.icns",
                "--jlink-options", "--strip-native-commands --no-header-files --no-man-pages --strip-debug",
                "--add-modules", project.JBR_JLINK_MODULES,
                "--app-version", project.version,
                "--description", "JBR Genome Browser ${fullVersion()}",
                "--vendor", "JetBrains Research",
                "--copyright", "Copyright JetBrains s.r.o., 2024",
                "--java-options",
                "-Xmx${project.project.appMaxHeapSize}M -ea -XX:+UseCompressedOops " +
                        "-XX:+HeapDumpOnOutOfMemoryError " +
                        "-XX:ErrorFile=\$USER_HOME\\jbr_java_error%p.log " +
                        "-XX:HeapDumpPath=\$USER_HOME\\jbr_java_error.hprof " +
                        "-splash:\$APPDIR\\icons\\jbr_splash@2x.png",
                "--file-associations", "${projectDir}\\src\\main\\resources\\FAsession.properties"
        doLast {
            println "=================================================================================================="
            println "JPackage exe: ${exePath}"
            println "=================================================================================================="
        }
    }
    newTask
}

if (os() == "windows") {
    def os = os()
    def arch = arch()
    def (url, md5) = getAmazonCorrettoUrlMd5(os, arch)
    def jdkName = url.substring(url.lastIndexOf("/") + 1)
    def unpackTask = project.tasks.findByName("unpack${jdkName.capitalize()}")
    def fullJdkPath = ""
    if (unpackTask) {
        fullJdkPath = unpackTask.outputs.files.singleFile
        // Copy zip declares output dir as output
        if (!fullJdkPath.toString().endsWith("\\jdk")) {
            fullJdkPath = file("${fullJdkPath}\\jdk")
        }
    } else {
        throw new GradleException("Unpacked JDK not found")
    }

    createWinExeTask(fullJdkPath, jdkName, os, arch)

    task signWinExe(group: "jetsign", dependsOn: [createWinExe, lazyDownloadJetSign]) {
        description "Sign windows exe file"

        def exeFile = project.tasks.createWinExe.outputs.files.singleFile
        inputs.dir(exeFile)
        outputs.dir(exeFile)
        doLast {
            signWinApplication(exeFile)
        }
    }

    task createWinDistrib(type: Copy, group: "distribution") {
        description "Creates *.exe and copies it to distributions folder."

        def exePath = null
        if (doSignApp()) {
            dependsOn signWinExe
            exePath = project.tasks.signWinExe.outputs.files.singleFile
        } else {
            dependsOn createWinExe
            exePath = project.tasks.createWinExe.outputs.files.singleFile
        }
        def outDir = "${project.buildDir}\\${project.distsDirName}\\win"

        from exePath.parent
        include exePath.name
        destinationDir file(outDir)
    }

    clean.dependsOn(cleanSetupAmazonCorretteChainToJLink)

    task winDistrib(dependsOn: [clean, createWinDistrib], group: "distribution") {
        description = "Creates Windows distributive. Files are singed if signing is enabled."
    }
}

However jpackage requires Wix to be able to create exe file (https://wixtoolset.org/docs/intro/). So stick with launch4j gradle plugin for now.