From 7551eca7c278c7c47d52eee7d6d9161574558b94 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Sat, 19 Apr 2025 12:36:42 +0200 Subject: [PATCH 1/3] Change for `includeJDK` to grab the running JDK --- app/build.gradle.kts | 57 ++++++++++------------------ app/src/processing/app/Platform.java | 11 ++---- build/shared/include.jdk | 0 3 files changed, 25 insertions(+), 43 deletions(-) create mode 100644 build/shared/include.jdk diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 865296d135..215f43e5c5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,3 +1,4 @@ +import org.gradle.internal.jvm.Jvm import org.gradle.kotlin.dsl.support.zipTo import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform import org.jetbrains.compose.desktop.application.dsl.TargetFormat @@ -250,7 +251,6 @@ tasks.register("generateSnapConfiguration"){ - openjdk-17-jre override-prime: | snapcraftctl prime - chmod -R +x opt/processing/lib/app/resources/jdk-* rm -vf usr/lib/jvm/java-17-openjdk-*/lib/security/cacerts """.trimIndent() dir.file("../snapcraft.yaml").asFile.writeText(content) @@ -322,40 +322,26 @@ tasks.register("includeJavaMode") { into(composeResources("modes/java/mode")) duplicatesStrategy = DuplicatesStrategy.EXCLUDE } -tasks.register("includeJdk") { - val os = DefaultNativePlatform.getCurrentOperatingSystem() - val arch = when (System.getProperty("os.arch")) { - "amd64", "x86_64" -> "x64" - else -> System.getProperty("os.arch") - } - val platform = when { - os.isWindows -> "windows" - os.isMacOsX -> "mac" - else -> "linux" - } - - val javaVersion = System.getProperty("java.version").split(".")[0] - val imageType = "jdk" - - src("https://api.adoptium.net/v3/binary/latest/" + - "$javaVersion/ga/" + - "$platform/" + - "$arch/" + - "$imageType/" + - "hotspot/normal/eclipse?project=jdk") - - val extension = if (os.isWindows) "zip" else "tar.gz" - val jdk = layout.buildDirectory.file("tmp/jdk-$platform-$arch.$extension") - dest(jdk) - overwrite(false) - doLast { - copy { - val archive = if (os.isWindows) { zipTree(jdk) } else { tarTree(jdk) } - from(archive){ eachFile{ permissions{ unix("755") } } } - into(composeResources("")) +tasks.register("includeJdk") { + dependsOn("createDistributable") + doFirst { + val jdk = Jvm.current().javaHome.absolutePath + val target = layout.buildDirectory.dir("compose/binaries").get().asFileTree.matching { include("**/include.jdk") } + .files + .firstOrNull() + ?.parentFile + ?.resolve("jdk") + ?.absolutePath + ?: error("Could not find include.jdk") + + val isWindows = System.getProperty("os.name").lowercase().contains("win") + val command = if (isWindows) { + listOf("xcopy", "/E", "/I", "/Q", jdk, target) + } else { + listOf("cp", "-a", jdk, target) } + ProcessBuilder(command).inheritIO().start().waitFor() } - finalizedBy("prepareAppResources") } tasks.register("includeSharedAssets"){ from("../build/shared/") @@ -427,7 +413,6 @@ tasks.register("signResources"){ dependsOn( "includeCore", "includeJavaMode", - "includeJdk", "includeSharedAssets", "includeProcessingExamples", "includeProcessingWebsiteExamples", @@ -540,7 +525,7 @@ afterEvaluate { } } tasks.named("createDistributable").configure { - dependsOn("signResources", "includeJdk") - finalizedBy("setExecutablePermissions") + dependsOn("signResources") + finalizedBy( "includeJdk","setExecutablePermissions") } } diff --git a/app/src/processing/app/Platform.java b/app/src/processing/app/Platform.java index 2af96bfd12..b911d7e0ae 100644 --- a/app/src/processing/app/Platform.java +++ b/app/src/processing/app/Platform.java @@ -391,17 +391,14 @@ static public File getContentFile(String name) { static public File getJavaHome() { var resourcesDir = System.getProperty("compose.application.resources.dir"); if(resourcesDir != null) { - var jdkFolder = Arrays.stream(new File(resourcesDir).listFiles((dir, name) -> dir.isDirectory() && name.startsWith("jdk-"))) - .findFirst() - .orElse(null); - if(Platform.isMacOS()){ - return new File(jdkFolder, "Contents/Home"); - } + var jdkFolder = new File(resourcesDir,"jdk"); + if(jdkFolder.exists()){ return jdkFolder; + } } var home = System.getProperty("java.home"); - if(home != null && new File(home, "bin/java").exists()){ + if(home != null){ return new File(home); } if (Platform.isMacOS()) { diff --git a/build/shared/include.jdk b/build/shared/include.jdk new file mode 100644 index 0000000000..e69de29bb2 From 858c6b6b149ddfcad18c77b41a69b045c731d6fb Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Tue, 22 Apr 2025 13:51:00 +0200 Subject: [PATCH 2/3] Fix error with macOS builds not being completely signed --- app/build.gradle.kts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 215f43e5c5..aadb1715fd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,10 +1,8 @@ import org.gradle.internal.jvm.Jvm -import org.gradle.kotlin.dsl.support.zipTo import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.compose.desktop.application.tasks.AbstractJPackageTask import org.jetbrains.compose.internal.de.undercouch.gradle.tasks.download.Download -import org.jetbrains.kotlin.fir.scopes.impl.overrides import java.io.FileOutputStream import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream @@ -279,12 +277,13 @@ tasks.register("zipDistributable"){ } afterEvaluate{ + // Override the default DMG task to use our custom one tasks.named("packageDmg").configure{ dependsOn("packageCustomDmg") group = "compose desktop" actions = emptyList() } - + // Override the default MSI task to use our custom one tasks.named("packageMsi").configure{ dependsOn("packageCustomMsi") group = "compose desktop" @@ -335,12 +334,26 @@ tasks.register("includeJdk") { ?: error("Could not find include.jdk") val isWindows = System.getProperty("os.name").lowercase().contains("win") + val isMacOS = System.getProperty("os.name").lowercase().contains("mac") val command = if (isWindows) { listOf("xcopy", "/E", "/I", "/Q", jdk, target) } else { listOf("cp", "-a", jdk, target) } ProcessBuilder(command).inheritIO().start().waitFor() + + if(org.gradle.internal.os.OperatingSystem.current().isMacOsX + && compose.desktop.application.nativeDistributions.macOS.notarization.appleID.isPresent + ) { + // Sign the main binary again since changed it. + val app = layout.buildDirectory.dir("compose/binaries").get().asFileTree.matching { include("**/*.app") } + .files + .firstOrNull() + ?.parentFile ?: error("Could not find Info.plist") + val signCommand = listOf("codesign", "--timestamp", "--force", "--deep","--options=runtime", "--sign", "Developer ID Application", app.absolutePath) + ProcessBuilder(signCommand).inheritIO().start().waitFor() + } + } } tasks.register("includeSharedAssets"){ @@ -526,6 +539,6 @@ afterEvaluate { } tasks.named("createDistributable").configure { dependsOn("signResources") - finalizedBy( "includeJdk","setExecutablePermissions") + finalizedBy( "includeJdk", "setExecutablePermissions") } } From 527bdedeafc5ae2cd1ddc77c3822c85a67b861a6 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Tue, 22 Apr 2025 15:04:51 +0200 Subject: [PATCH 3/3] Switched to a normal copy operation and updated permissions --- app/build.gradle.kts | 145 +++++++++++++++------------------------ build/shared/include.jdk | 0 2 files changed, 55 insertions(+), 90 deletions(-) delete mode 100644 build/shared/include.jdk diff --git a/app/build.gradle.kts b/app/build.gradle.kts index aadb1715fd..63554140b0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,4 +1,5 @@ import org.gradle.internal.jvm.Jvm +import org.gradle.internal.os.OperatingSystem import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.compose.desktop.application.tasks.AbstractJPackageTask @@ -135,11 +136,11 @@ tasks.compileJava{ val version = if(project.version == "unspecified") "1.0.0" else project.version tasks.register("installCreateDmg") { - onlyIf { org.gradle.internal.os.OperatingSystem.current().isMacOsX } + onlyIf { OperatingSystem.current().isMacOsX } commandLine("arch", "-arm64", "brew", "install", "--quiet", "create-dmg") } tasks.register("packageCustomDmg"){ - onlyIf { org.gradle.internal.os.OperatingSystem.current().isMacOsX } + onlyIf { OperatingSystem.current().isMacOsX } group = "compose desktop" val distributable = tasks.named("createDistributable").get() @@ -169,8 +170,6 @@ tasks.register("packageCustomDmg"){ extra.add("25") } - commandLine("brew", "install", "--quiet", "create-dmg") - commandLine("create-dmg", "--volname", packageName, "--volicon", file("macos/volume.icns"), @@ -187,7 +186,7 @@ tasks.register("packageCustomDmg"){ } tasks.register("packageCustomMsi"){ - onlyIf { org.gradle.internal.os.OperatingSystem.current().isWindows } + onlyIf { OperatingSystem.current().isWindows } dependsOn("createDistributable") workingDir = file("windows") group = "compose desktop" @@ -203,20 +202,22 @@ tasks.register("packageCustomMsi"){ ) } -val snapname = findProperty("snapname") ?: rootProject.name -val snaparch = when (System.getProperty("os.arch")) { - "amd64", "x86_64" -> "amd64" - "aarch64" -> "arm64" - else -> System.getProperty("os.arch") -} + tasks.register("generateSnapConfiguration"){ - onlyIf { org.gradle.internal.os.OperatingSystem.current().isLinux } + val name = findProperty("snapname") ?: rootProject.name + val arch = when (System.getProperty("os.arch")) { + "amd64", "x86_64" -> "amd64" + "aarch64" -> "arm64" + else -> System.getProperty("os.arch") + } + + onlyIf { OperatingSystem.current().isLinux } val distributable = tasks.named("createDistributable").get() dependsOn(distributable) val dir = distributable.destinationDir.get() val content = """ - name: $snapname + name: $name version: $version base: core22 summary: A creative coding editor @@ -243,7 +244,7 @@ tasks.register("generateSnapConfiguration"){ parts: processing: plugin: dump - source: deb/processing_$version-1_$snaparch.deb + source: deb/processing_$version-1_$arch.deb source-type: deb stage-packages: - openjdk-17-jre @@ -255,7 +256,7 @@ tasks.register("generateSnapConfiguration"){ } tasks.register("packageSnap"){ - onlyIf { org.gradle.internal.os.OperatingSystem.current().isLinux } + onlyIf { OperatingSystem.current().isLinux } dependsOn("packageDeb", "generateSnapConfiguration") group = "compose desktop" @@ -290,7 +291,7 @@ afterEvaluate{ actions = emptyList() } tasks.named("packageDistributionForCurrentOS").configure { - if(org.gradle.internal.os.OperatingSystem.current().isMacOsX + if(OperatingSystem.current().isMacOsX && compose.desktop.application.nativeDistributions.macOS.notarization.appleID.isPresent ){ dependsOn("notarizeDmg") @@ -321,40 +322,9 @@ tasks.register("includeJavaMode") { into(composeResources("modes/java/mode")) duplicatesStrategy = DuplicatesStrategy.EXCLUDE } -tasks.register("includeJdk") { - dependsOn("createDistributable") - doFirst { - val jdk = Jvm.current().javaHome.absolutePath - val target = layout.buildDirectory.dir("compose/binaries").get().asFileTree.matching { include("**/include.jdk") } - .files - .firstOrNull() - ?.parentFile - ?.resolve("jdk") - ?.absolutePath - ?: error("Could not find include.jdk") - - val isWindows = System.getProperty("os.name").lowercase().contains("win") - val isMacOS = System.getProperty("os.name").lowercase().contains("mac") - val command = if (isWindows) { - listOf("xcopy", "/E", "/I", "/Q", jdk, target) - } else { - listOf("cp", "-a", jdk, target) - } - ProcessBuilder(command).inheritIO().start().waitFor() - - if(org.gradle.internal.os.OperatingSystem.current().isMacOsX - && compose.desktop.application.nativeDistributions.macOS.notarization.appleID.isPresent - ) { - // Sign the main binary again since changed it. - val app = layout.buildDirectory.dir("compose/binaries").get().asFileTree.matching { include("**/*.app") } - .files - .firstOrNull() - ?.parentFile ?: error("Could not find Info.plist") - val signCommand = listOf("codesign", "--timestamp", "--force", "--deep","--options=runtime", "--sign", "Developer ID Application", app.absolutePath) - ProcessBuilder(signCommand).inheritIO().start().waitFor() - } - - } +tasks.register("includeJdk") { + from(Jvm.current().javaHome.absolutePath) + destinationDir = composeResources("jdk").get().asFile } tasks.register("includeSharedAssets"){ from("../build/shared/") @@ -400,6 +370,7 @@ tasks.register("includeJavaModeResources") { from(java.layout.buildDirectory.dir("resources-bundled")) into(composeResources("../")) } +// TODO: Move to java mode tasks.register("renameWindres") { dependsOn("includeSharedAssets","includeJavaModeResources") val dir = composeResources("modes/java/application/launch4j/bin/") @@ -416,14 +387,9 @@ tasks.register("renameWindres") { duplicatesStrategy = DuplicatesStrategy.INCLUDE into(dir) } -tasks.register("signResources"){ - onlyIf { - org.gradle.internal.os.OperatingSystem.current().isMacOsX - && - compose.desktop.application.nativeDistributions.macOS.signing.sign.get() - } - group = "compose desktop" +tasks.register("includeProcessingResources"){ dependsOn( + "includeJdk", "includeCore", "includeJavaMode", "includeSharedAssets", @@ -432,12 +398,18 @@ tasks.register("signResources"){ "includeJavaModeResources", "renameWindres" ) - finalizedBy("prepareAppResources") + finalizedBy("signResources") +} +tasks.register("signResources"){ + onlyIf { + OperatingSystem.current().isMacOsX + && + compose.desktop.application.nativeDistributions.macOS.signing.sign.get() + } + group = "compose desktop" val resourcesPath = composeResources("") - - // find jars in the resources directory val jars = mutableListOf() doFirst{ @@ -470,7 +442,7 @@ tasks.register("signResources"){ include("**/*x86_64*") include("**/*ffmpeg*") include("**/ffmpeg*/**") - exclude("jdk-*/**") + exclude("jdk/**") exclude("*.jar") exclude("*.so") exclude("*.dll") @@ -506,39 +478,32 @@ tasks.register("signResources"){ } -afterEvaluate { - tasks.named("prepareAppResources").configure { - dependsOn( - "includeCore", - "includeJavaMode", - "includeSharedAssets", - "includeProcessingExamples", - "includeProcessingWebsiteExamples", - "includeJavaModeResources", - "renameWindres" - ) - } - tasks.register("setExecutablePermissions") { - description = "Sets executable permissions on binaries in Processing.app resources" - group = "compose desktop" +tasks.register("setExecutablePermissions") { + description = "Sets executable permissions on binaries in Processing.app resources" + group = "compose desktop" - doLast { - val resourcesPath = layout.buildDirectory.dir("compose/binaries") - fileTree(resourcesPath) { - include("**/resources/**/bin/**") - include("**/resources/**/*.sh") - include("**/resources/**/*.dylib") - include("**/resources/**/*.so") - include("**/resources/**/*.exe") - }.forEach { file -> - if (file.isFile) { - file.setExecutable(true, false) - } + doLast { + val resourcesPath = layout.buildDirectory.dir("compose/binaries") + fileTree(resourcesPath) { + include("**/resources/**/bin/**") + include("**/resources/**/lib/**") + include("**/resources/**/*.sh") + include("**/resources/**/*.dylib") + include("**/resources/**/*.so") + include("**/resources/**/*.exe") + }.forEach { file -> + if (file.isFile) { + file.setExecutable(true, false) } } } +} + +afterEvaluate { + tasks.named("prepareAppResources").configure { + dependsOn("includeProcessingResources") + } tasks.named("createDistributable").configure { - dependsOn("signResources") - finalizedBy( "includeJdk", "setExecutablePermissions") + finalizedBy("setExecutablePermissions") } } diff --git a/build/shared/include.jdk b/build/shared/include.jdk deleted file mode 100644 index e69de29bb2..0000000000