From ddae2f3a85839fa11696aac76fc400724bfaf2ad Mon Sep 17 00:00:00 2001 From: Hiroshi Miura Date: Sun, 29 Dec 2024 17:53:53 +0900 Subject: [PATCH] chore: move launch4j configurations into windows-conventions.gradle Signed-off-by: Hiroshi Miura --- build-logic/build.gradle | 1 + .../org.omegat.windows-conventions.gradle | 52 +++++ build.gradle | 207 +----------------- 3 files changed, 54 insertions(+), 206 deletions(-) create mode 100644 build-logic/src/main/groovy/org.omegat.windows-conventions.gradle diff --git a/build-logic/build.gradle b/build-logic/build.gradle index 4d8d4d6e68..78bf6e570f 100644 --- a/build-logic/build.gradle +++ b/build-logic/build.gradle @@ -10,4 +10,5 @@ dependencies { implementation 'com.github.ben-manes:gradle-versions-plugin:0.51.0' implementation 'com.github.spotbugs.snom:spotbugs-gradle-plugin:6.0.26' implementation 'com.diffplug.spotless:spotless-plugin-gradle:7.0.0.BETA4' + implementation 'edu.sc.seis.launch4j:launch4j:3.0.6' } diff --git a/build-logic/src/main/groovy/org.omegat.windows-conventions.gradle b/build-logic/src/main/groovy/org.omegat.windows-conventions.gradle new file mode 100644 index 0000000000..e3c805eb0d --- /dev/null +++ b/build-logic/src/main/groovy/org.omegat.windows-conventions.gradle @@ -0,0 +1,52 @@ +plugins { + id 'edu.sc.seis.launch4j' + id 'org.omegat.version-conventions' +} + +// Read in all our custom messages and massage them for inclusion in the .iss +ext.getInnoSetupCustomMessages = { + // Don't include languages that InnoSetup doesn't have strings for + def blacklist = ['cy', 'ia', 'mfe'] + // Sort files to ensure English comes first, to set fallback + fileTree(dir: 'release/win32-specific', include: 'CustomMessages*.ini') + .sort() + .collect { file -> + def match = file.name =~ /CustomMessages_?([^\.]*).ini/ + if (match) { + def capture = match.group(1) + def lang = capture.empty ? 'en' : capture + if (!blacklist.contains(lang)) { + file.text.replaceAll(/(?m)^([^=]+)/) { "$lang.${it[0]}" } + } + } + }.findAll() + .join(System.lineSeparator()) +} + +/* + * Configuration of launch4j java launcher. + * OmegaT uses it as launcher for windows. + */ +launch4j { + libraryDir = "." // assume OmegaT.jar is located as same folder as OmegaT.exe + dontWrapJar = true + downloadUrl = 'https://adoptium.net/' + supportUrl = 'https://omegat.org/support' + icon = "${projectDir}/images/OmegaT.ico" + errTitle = 'OmegaT' + headerType = 'gui' + jreMinVersion = '11.0' + jreMaxVersion = '21.1' + copyConfigurable = [] // hack: don't copy dependencies to $libraryDir + // assume bundled JRE in jre/, fallback to JAVA_HOME env then PATH + bundledJrePath = 'jre;%JAVA_HOME%;%PATH%' + requires64Bit = false // support 32bit distribution + copyright = "The GNU General Public License, Version 3.0" + version = omtVersion.version + textVersion = omtVersion.version + companyName = distAppVendor + fileDescription = shortDescription + restartOnCrash = false + stayAlive = false + priority = 'normal' +} diff --git a/build.gradle b/build.gradle index 06c816e150..baa0d13191 100644 --- a/build.gradle +++ b/build.gradle @@ -7,6 +7,7 @@ plugins { id 'org.omegat.main-utilities' id 'org.omegat.java-conventions' id 'org.omegat.jaxb-conventions' + id 'org.omegat.windows-conventions' id 'org.omegat.jpkg-conventions' id 'application' id 'jvm-test-suite' @@ -14,7 +15,6 @@ plugins { id 'maven-publish' id 'signing' id 'jacoco-report-aggregation' - alias(libs.plugins.launch4j) alias(libs.plugins.ssh) } @@ -318,34 +318,6 @@ def omegatJarFilename = jar.archiveFileName.get() project(":machinetranslators") {jar.enabled = false} project(":spellchecker") {jar.enabled = false} -/* - * Configuration of launch4j java launcher. - * OmegaT uses it as launcher for windows. - */ -launch4j { - libraryDir = "." // assume OmegaT.jar is located as same folder as OmegaT.exe - dontWrapJar = true - downloadUrl = 'https://adoptium.net/' - supportUrl = 'https://omegat.org/support' - icon = "${projectDir}/images/OmegaT.ico" - errTitle = 'OmegaT' - headerType = 'gui' - jreMinVersion = '11.0' - jreMaxVersion = '21.1' - copyConfigurable = [] // hack: don't copy dependencies to $libraryDir - // assume bundled JRE in jre/, fallback to JAVA_HOME env then PATH - bundledJrePath = 'jre;%JAVA_HOME%;%PATH%' - requires64Bit = false // support 32bit distribution - copyright = "The GNU General Public License, Version 3.0" - version = omtVersion.version - textVersion = omtVersion.version - companyName = distAppVendor - fileDescription = shortDescription - restartOnCrash = false - stayAlive = false - priority = 'normal' -} - tasks.register('genMac') { def appbundlerClasspath = configurations.genMac.asPath def outDir = layout.buildDirectory.file("appbundler").get().toString() @@ -783,188 +755,11 @@ startScripts.enabled = false // installDist insists on destination executable directory even when disable start script. application.executableDir = "" -// Read in all our custom messages and massage them for inclusion in the .iss -ext.getInnoSetupCustomMessages = { - // Don't include languages that InnoSetup doesn't have strings for - def blacklist = ['cy', 'ia', 'mfe'] - // Sort files to ensure English comes first, to set fallback - fileTree(dir: 'release/win32-specific', include: 'CustomMessages*.ini') - .sort() - .collect { file -> - def match = file.name =~ /CustomMessages_?([^\.]*).ini/ - if (match) { - def capture = match.group(1) - def lang = capture.empty ? 'en' : capture - if (!blacklist.contains(lang)) { - file.text.replaceAll(/(?m)^([^=]+)/) { "$lang.${it[0]}" } - } - } - }.findAll() - .join(System.lineSeparator()) -} - tasks.register('win') { description = 'Build the Windows distributions.' group = 'omegat distribution' } -ext.makeWinTask = { args -> - def fullVersion = project.version + omtVersion.beta - def installerBasename = "OmegaT_${fullVersion}_${args.suffix}" - def installerWinExe = base.distsDirectory.file("${installerBasename}.exe") - def signedWinExe = base.distsDirectory.file("${installerBasename}_Signed.exe") - def prepDistsTaskName = "${args.name}Prep" - def genDistsTaskName = "${args.name}Gen" - def distsTaskName = "${args.name}" - def signedTaskName = "${args.name}Signed" - def signedTaskCommandArgs = { arg2 -> - def exe = exePresent('osslsigncode') ? 'osslsigncode' : file('ci/osslsigncode').toString() - def commandArgs = [exe, 'sign'] - if (project.hasProperty('pkcs11module')) { - commandArgs.addAll('-pkcs11module', project.property('pkcs11module')) - } - if (project.hasProperty('winCodesignCert')) { - commandArgs.addAll('-certs', project.property('winCodesignCert')) - } - if (project.hasProperty('pkcs11cert')) { - commandArgs.addAll('-pkcs11cert', project.property('pkcs11cert')) - } - if (project.hasProperty('winCodesignPassword')) { - commandArgs.addAll('-pass', project.property('winCodesignPassword')) - } - if (project.hasProperty('winCodesignDevice')) { - envVars['USBDEV'] = project.property('winCodesignDevice') - } - commandArgs.addAll( - '-t', project.hasProperty('winCodesignTimestampUrl') ? project.property('winCodesignTimestampUrl') : - 'http://time.certum.pl/', - '-n', application.applicationName, '-i', omtWebsite, '-h', 'sha256', - '-in', installerWinExe.get().asFile, - '-out', signedWinExe.get().asFile - ) - return commandArgs - } - - tasks.register(prepDistsTaskName, Sync) { - onlyIf { - conditions([!args.jrePath || !args.jrePath.empty, 'JRE not found'], - [exePresent('iscc') || exePresent('docker') || exePresent('nerdctl'), - 'InnoSetup or Docker not installed']) - } - doFirst { - delete "$destinationDir/jre" - delete installerWinExe - } - with distributions.main.contents - destinationDir = file(layout.buildDirectory.file("innosetup/${args.name}")) - outputs.upToDateWhen { - // detect up-to-date when OmegaT.jar exists and newer than libs/OmegaT.jar - def f1 = layout.buildDirectory.file("innosetup/${args.name}/OmegaT.jar").get().asFile - def f2 = base.libsDirectory.file('OmegaT.jar').get().asFile - f1.exists() && f2.exists() && f1.lastModified() > f2.lastModified() - } - from('release/win32-specific') { - include 'OmegaT.l4J.ini' - include 'OmegaT.iss' - filter(ReplaceTokens, tokens: [ - VERSION_NUMBER_SUBST : fullVersion, - OUTPUT_BASENAME_SUBST: installerBasename.toString(), - CUSTOM_MESSAGES_SUBST: getInnoSetupCustomMessages(), - ARCHITECTURE_SUBST : args.arch ?: '' - ]) - filter(FixCrLfFilter, eol: FixCrLfFilter.CrLf.newInstance('crlf')) - filteringCharset = 'UTF-8' - } - from('build/launch4j') { - include '*.exe' - } - if (args.jrePath && !args.jrePath.empty) { - from(zipTree(args.jrePath.singleFile)) { - includeEmptyDirs = false - eachFile { - replaceRelativePathSegment(it, /jdk.*-jre/, 'jre') - } - } - } - dependsOn createAllExecutables - } - - tasks.register(genDistsTaskName, Exec) { - onlyIf { - conditions([!args.jrePath || !args.jrePath.empty, 'JRE not found'], - [exePresent('iscc') || exePresent('docker') || exePresent('nerdctl'), - 'InnoSetup or Docker not installed']) - } - dependsOn prepDistsTaskName - inputs.files( - layout.buildDirectory.file("innosetup/${args.name}/OmegaT.jar"), - layout.buildDirectory.file("innosetup/${args.name}/OmegaT.iss"), - layout.buildDirectory.file("innosetup/${args.name}/OmegaT.l4j.ini"), - ) - // You'd think we could just set the PATH, but there be dragons here - // https://github.com/palantir/gradle-docker/issues/162 - def exe = exePresent('iscc') ? 'iscc' : file('ci/iscc') - def iss = layout.buildDirectory.file("innosetup/${args.name}/OmegaT.iss").get().asFile - logging.captureStandardOutput LogLevel.INFO - commandLine exe, '/Qp', iss - outputs.file layout.buildDirectory.file("innosetup/${args.name}/${installerBasename}.exe") - doLast { - println "" - def f3 = layout.buildDirectory.file("innosetup/${args.name}/${installerBasename}.exe").get().asFile - logger.info('Built ' + f3.toString() + "(" + f3.length() + ")") - } - } - - tasks.register(distsTaskName, Copy) { - description = "Create a Windows installer for ${args.name} distro. " + - 'Requires Inno Setup (http://www.jrsoftware.org/isinfo.php).' - onlyIf { - conditions([!args.jrePath || !args.jrePath.empty, 'JRE not found'], - [exePresent('iscc') || exePresent('docker') || exePresent('nerdctl'), - 'InnoSetup or Docker not installed']) - } - from layout.buildDirectory.file("innosetup/${args.name}/${installerBasename}.exe") - into base.distsDirectory - outputs.file installerWinExe - dependsOn genDistsTaskName - } - - tasks.register(signedTaskName, Exec) { - group = 'omegat distribution' - inputs.file installerWinExe skipWhenEmpty() - outputs.file signedWinExe - // Starting from Nov 2022, certification provider force to use HSM to - // store private keys. Starting on June 1, 2023, at 00:00 UTC, industry - // standards will require private keys for standard code signing - // certificates to be stored on hardware certified as FIPS 140 Level 2, - // Common Criteria EAL 4+, or equivalent. - // #1179 build/release: Windows binary signature with PKCS#11 HSM - // https://sourceforge.net/p/omegat/bugs/1179/ - // requires osslsigncode version 2.5 or later. - onlyIf { - // Set these in e.g. local.properties - def props = ['pkcs11module', 'winCodesignPassword'] - conditions([props.every { project.hasProperty(it) }, 'Code signing properties not set'], - [exePresent('osslsigncode'), 'osslsigncode is not installed']) - // note: container image amake/innosetup has osslsigntool 1.7 which don't work. - // [exePresent('osslsigncode') || exePresent('docker') || exePresent('nerdctl'), - // 'neither osslsigncode or docker/nerdctl is not installed']) - } - doFirst { - delete signedWinExe - } - def envVars = [:] - commandLine(signedTaskCommandArgs()) - environment(envVars) - dependsOn distsTaskName - } - assemble.dependsOn args.name, signedTaskName - win.dependsOn args.name, signedTaskName -} -makeWinTask(name: 'winNoJRE', suffix: 'Windows_without_JRE') -makeWinTask(name: 'winJRE64', suffix: 'Windows_64', jrePath: windowsJRE, arch: 'x64') -makeWinTask(name: 'winJRE', suffix: 'Windows', jrePath: windowsJRE32) - // Disable .tar distributions for everyone but Linux tasks.findAll { it.name =~ /[dD]istTar$/ && !it.name.contains('linux') }.each { it.enabled = false } // Disable .zip distributions for Linux