diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 9d858dfed..24a2fee0f 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -221,7 +221,7 @@ jobs: 'JavaKitSampleApp', 'JavaProbablyPrime', 'JavaSieve', - 'SwiftAndJavaJarSampleLib', + 'SwiftAndJavaJarFFMSampleLib', 'SwiftJavaExtractFFMSampleApp', 'SwiftJavaExtractJNISampleApp', ] @@ -249,7 +249,7 @@ jobs: 'JavaKitSampleApp', 'JavaProbablyPrime', 'JavaSieve', - 'SwiftAndJavaJarSampleLib', + 'SwiftAndJavaJarFFMSampleLib', 'SwiftJavaExtractFFMSampleApp', 'SwiftJavaExtractJNISampleApp', ] diff --git a/BuildLogic/src/main/kotlin/build-logic.java-common-conventions.gradle.kts b/BuildLogic/src/main/kotlin/build-logic.java-common-conventions.gradle.kts index 199a3b633..c70674469 100644 --- a/BuildLogic/src/main/kotlin/build-logic.java-common-conventions.gradle.kts +++ b/BuildLogic/src/main/kotlin/build-logic.java-common-conventions.gradle.kts @@ -23,7 +23,7 @@ plugins { java { toolchain { - languageVersion = JavaLanguageVersion.of(25) + languageVersion = JavaLanguageVersion.of((gradle.extra.properties["swiftJavaJdk"] as? Int) ?: 25) } } diff --git a/Samples/SwiftAndJavaJarSampleLib/gradle.properties b/Samples/GradlePluginSampleApp/gradle.properties similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/gradle.properties rename to Samples/GradlePluginSampleApp/gradle.properties diff --git a/Samples/SwiftAndJavaJarSampleLib/Example.java b/Samples/SwiftAndJavaJarFFMSampleLib/Example.java similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/Example.java rename to Samples/SwiftAndJavaJarFFMSampleLib/Example.java diff --git a/Samples/SwiftAndJavaJarSampleLib/LICENSE.txt b/Samples/SwiftAndJavaJarFFMSampleLib/LICENSE.txt similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/LICENSE.txt rename to Samples/SwiftAndJavaJarFFMSampleLib/LICENSE.txt diff --git a/Samples/SwiftAndJavaJarSampleLib/Package.swift b/Samples/SwiftAndJavaJarFFMSampleLib/Package.swift similarity index 96% rename from Samples/SwiftAndJavaJarSampleLib/Package.swift rename to Samples/SwiftAndJavaJarFFMSampleLib/Package.swift index 68bc6354e..ecd69517c 100644 --- a/Samples/SwiftAndJavaJarSampleLib/Package.swift +++ b/Samples/SwiftAndJavaJarFFMSampleLib/Package.swift @@ -5,7 +5,7 @@ import CompilerPluginSupport import PackageDescription let package = Package( - name: "SwiftAndJavaJarSampleLib", + name: "SwiftAndJavaJarFFMSampleLib", platforms: [ .macOS(.v15), .iOS(.v18), diff --git a/Samples/SwiftAndJavaJarSampleLib/Sources/MySwiftLibrary/MySwiftClass.swift b/Samples/SwiftAndJavaJarFFMSampleLib/Sources/MySwiftLibrary/MySwiftClass.swift similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/Sources/MySwiftLibrary/MySwiftClass.swift rename to Samples/SwiftAndJavaJarFFMSampleLib/Sources/MySwiftLibrary/MySwiftClass.swift diff --git a/Samples/SwiftAndJavaJarSampleLib/Sources/MySwiftLibrary/MySwiftLibrary.swift b/Samples/SwiftAndJavaJarFFMSampleLib/Sources/MySwiftLibrary/MySwiftLibrary.swift similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/Sources/MySwiftLibrary/MySwiftLibrary.swift rename to Samples/SwiftAndJavaJarFFMSampleLib/Sources/MySwiftLibrary/MySwiftLibrary.swift diff --git a/Samples/SwiftAndJavaJarSampleLib/Sources/MySwiftLibrary/swift-java.config b/Samples/SwiftAndJavaJarFFMSampleLib/Sources/MySwiftLibrary/swift-java.config similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/Sources/MySwiftLibrary/swift-java.config rename to Samples/SwiftAndJavaJarFFMSampleLib/Sources/MySwiftLibrary/swift-java.config diff --git a/Samples/SwiftAndJavaJarSampleLib/build.gradle.kts b/Samples/SwiftAndJavaJarFFMSampleLib/build.gradle.kts similarity index 90% rename from Samples/SwiftAndJavaJarSampleLib/build.gradle.kts rename to Samples/SwiftAndJavaJarFFMSampleLib/build.gradle.kts index 33f77c70e..6912f51be 100644 --- a/Samples/SwiftAndJavaJarSampleLib/build.gradle.kts +++ b/Samples/SwiftAndJavaJarFFMSampleLib/build.gradle.kts @@ -32,7 +32,7 @@ repositories { java { toolchain { - languageVersion.set(JavaLanguageVersion.of(25)) + languageVersion.set(JavaLanguageVersion.of((gradle.extra.properties["swiftJavaJdk"] as? Int) ?: 17)) } } @@ -85,13 +85,13 @@ tasks.jar.configure { } base { - archivesName = "swift-and-java-jar-sample-lib" + archivesName = "swift-and-java-jar-ffm-sample-lib" } publishing { publications { create("maven") { - artifactId = "swift-and-java-jar-sample-lib" + artifactId = "swift-and-java-jar-ffm-sample-lib" from(components["java"]) } } diff --git a/Samples/SwiftAndJavaJarSampleLib/ci-validate.sh b/Samples/SwiftAndJavaJarFFMSampleLib/ci-validate.sh similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/ci-validate.sh rename to Samples/SwiftAndJavaJarFFMSampleLib/ci-validate.sh diff --git a/Samples/SwiftAndJavaJarFFMSampleLib/gradle.properties b/Samples/SwiftAndJavaJarFFMSampleLib/gradle.properties new file mode 120000 index 000000000..7677fb73b --- /dev/null +++ b/Samples/SwiftAndJavaJarFFMSampleLib/gradle.properties @@ -0,0 +1 @@ +../gradle.properties \ No newline at end of file diff --git a/Samples/SwiftAndJavaJarSampleLib/gradlew b/Samples/SwiftAndJavaJarFFMSampleLib/gradlew similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/gradlew rename to Samples/SwiftAndJavaJarFFMSampleLib/gradlew diff --git a/Samples/SwiftAndJavaJarSampleLib/gradlew.bat b/Samples/SwiftAndJavaJarFFMSampleLib/gradlew.bat similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/gradlew.bat rename to Samples/SwiftAndJavaJarFFMSampleLib/gradlew.bat diff --git a/Samples/SwiftAndJavaJarSampleLib/src/jmh/java/org/swift/swiftkit/ffm/JavaToSwiftBenchmark.java b/Samples/SwiftAndJavaJarFFMSampleLib/src/jmh/java/org/swift/swiftkit/ffm/JavaToSwiftBenchmark.java similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/src/jmh/java/org/swift/swiftkit/ffm/JavaToSwiftBenchmark.java rename to Samples/SwiftAndJavaJarFFMSampleLib/src/jmh/java/org/swift/swiftkit/ffm/JavaToSwiftBenchmark.java diff --git a/Samples/SwiftAndJavaJarSampleLib/src/main/java/com/example/swift/HelloJava2Swift.java b/Samples/SwiftAndJavaJarFFMSampleLib/src/main/java/com/example/swift/HelloJava2Swift.java similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/src/main/java/com/example/swift/HelloJava2Swift.java rename to Samples/SwiftAndJavaJarFFMSampleLib/src/main/java/com/example/swift/HelloJava2Swift.java diff --git a/Samples/SwiftAndJavaJarSampleLib/src/test/java/com/example/swift/MySwiftClassTest.java b/Samples/SwiftAndJavaJarFFMSampleLib/src/test/java/com/example/swift/MySwiftClassTest.java similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/src/test/java/com/example/swift/MySwiftClassTest.java rename to Samples/SwiftAndJavaJarFFMSampleLib/src/test/java/com/example/swift/MySwiftClassTest.java diff --git a/Samples/SwiftAndJavaJarSampleLib/src/test/java/com/example/swift/MySwiftLibraryTest.java b/Samples/SwiftAndJavaJarFFMSampleLib/src/test/java/com/example/swift/MySwiftLibraryTest.java similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/src/test/java/com/example/swift/MySwiftLibraryTest.java rename to Samples/SwiftAndJavaJarFFMSampleLib/src/test/java/com/example/swift/MySwiftLibraryTest.java diff --git a/Samples/SwiftAndJavaJarSampleLib/src/test/java/org/swift/swiftkit/ffm/MySwiftClassTest.java b/Samples/SwiftAndJavaJarFFMSampleLib/src/test/java/org/swift/swiftkit/ffm/MySwiftClassTest.java similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/src/test/java/org/swift/swiftkit/ffm/MySwiftClassTest.java rename to Samples/SwiftAndJavaJarFFMSampleLib/src/test/java/org/swift/swiftkit/ffm/MySwiftClassTest.java diff --git a/Samples/SwiftAndJavaJarSampleLib/src/test/java/org/swift/swiftkit/ffm/SwiftArenaTest.java b/Samples/SwiftAndJavaJarFFMSampleLib/src/test/java/org/swift/swiftkit/ffm/SwiftArenaTest.java similarity index 100% rename from Samples/SwiftAndJavaJarSampleLib/src/test/java/org/swift/swiftkit/ffm/SwiftArenaTest.java rename to Samples/SwiftAndJavaJarFFMSampleLib/src/test/java/org/swift/swiftkit/ffm/SwiftArenaTest.java diff --git a/Samples/SwiftJavaExtractFFMSampleApp/build.gradle.kts b/Samples/SwiftJavaExtractFFMSampleApp/build.gradle.kts index 5fec886d2..6a4d752a2 100644 --- a/Samples/SwiftJavaExtractFFMSampleApp/build.gradle.kts +++ b/Samples/SwiftJavaExtractFFMSampleApp/build.gradle.kts @@ -29,7 +29,7 @@ repositories { java { toolchain { - languageVersion.set(JavaLanguageVersion.of(25)) + languageVersion.set(JavaLanguageVersion.of((gradle.extra.properties["swiftJavaJdk"] as? Int) ?: 25)) } } diff --git a/Samples/SwiftJavaExtractJNISampleApp/build.gradle.kts b/Samples/SwiftJavaExtractJNISampleApp/build.gradle.kts index 48e2560e2..d6416bafb 100644 --- a/Samples/SwiftJavaExtractJNISampleApp/build.gradle.kts +++ b/Samples/SwiftJavaExtractJNISampleApp/build.gradle.kts @@ -29,7 +29,7 @@ repositories { java { toolchain { - languageVersion.set(JavaLanguageVersion.of(25)) + languageVersion.set(JavaLanguageVersion.of((gradle.extra.properties["swiftJavaJdk"] as? Int) ?: 17)) } } diff --git a/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/MultipleTypesFromSingleFileTest.java b/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/MultipleTypesFromSingleFileTest.java index ae02b8727..5ac947759 100644 --- a/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/MultipleTypesFromSingleFileTest.java +++ b/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/MultipleTypesFromSingleFileTest.java @@ -18,7 +18,6 @@ import org.swift.swiftkit.core.ConfinedSwiftMemorySession; import org.swift.swiftkit.core.SwiftArena; -import java.lang.foreign.Arena; import java.util.Optional; import java.util.OptionalInt; diff --git a/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/VehicleEnumTest.java b/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/VehicleEnumTest.java index c533603a2..25bc415c8 100644 --- a/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/VehicleEnumTest.java +++ b/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/VehicleEnumTest.java @@ -18,7 +18,6 @@ import org.swift.swiftkit.core.ConfinedSwiftMemorySession; import org.swift.swiftkit.core.SwiftArena; -import java.lang.foreign.Arena; import java.util.Optional; import java.util.OptionalInt; diff --git a/SwiftKitCore/build.gradle.kts b/SwiftKitCore/build.gradle.kts index 91dea2e3f..ec5dfd2ae 100644 --- a/SwiftKitCore/build.gradle.kts +++ b/SwiftKitCore/build.gradle.kts @@ -43,12 +43,12 @@ publishing { java { toolchain { - languageVersion.set(JavaLanguageVersion.of(25)) + languageVersion.set(JavaLanguageVersion.of((gradle.extra.properties["swiftJavaJdk"] as? Int) ?: 25)) } } tasks.withType().configureEach { - // Support Java 11 + // SwiftKitCore is consumable down to Java 11 options.release.set(11) } diff --git a/SwiftKitFFM/build.gradle.kts b/SwiftKitFFM/build.gradle.kts index 973198442..1659da750 100644 --- a/SwiftKitFFM/build.gradle.kts +++ b/SwiftKitFFM/build.gradle.kts @@ -43,7 +43,7 @@ publishing { java { toolchain { - languageVersion.set(JavaLanguageVersion.of(25)) + languageVersion.set(JavaLanguageVersion.of((gradle.extra.properties["swiftJavaJdk"] as? Int) ?: 25)) } } diff --git a/gradle.properties b/gradle.properties index 182db452b..018c38280 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -org.gradle.java.installations.fromEnv=JAVA_HOME_25,JAVA_HOME_25_X64,JAVA_HOME_25_ARM64 \ No newline at end of file +org.gradle.java.installations.fromEnv=JAVA_HOME_25,JAVA_HOME_25_X64,JAVA_HOME_25_ARM64,JAVA_HOME_21,JAVA_HOME_21_X64,JAVA_HOME_21_ARM64,JAVA_HOME_17,JAVA_HOME_17_X64,JAVA_HOME_17_ARM64 \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index a360e0786..b2b9c1be6 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -18,16 +18,78 @@ pluginManagement { rootProject.name = "swift-java" +// ==== ----------------------------------------------------------------------- +// MARK: JDK detection +// +// Some modules require JDK 25+ (FFM API). When the active toolchain is +// older we exclude those modules so developers with only JDK 17 can still +// build the JDK-17-compatible subset (currently SwiftKitCore). +// +// Resolution order: +// 1. -PswiftJavaJdk= Gradle property (explicit override) +// 2. JAVA_HOME_25* env vars listed in gradle.properties (treated as 25) +// 3. JAVA_HOME/release file's JAVA_VERSION +// 4. Default: 25 + +fun detectJdkMajor(): Int { + settings.providers.gradleProperty("swiftJavaJdk").orNull?.toIntOrNull()?.let { return it } + + val env = System.getenv() + if (listOf("JAVA_HOME_25", "JAVA_HOME_25_X64", "JAVA_HOME_25_ARM64").any { env[it] != null }) { + return 25 + } + + env["JAVA_HOME"]?.let { javaHome -> + val release = File(javaHome, "release") + if (release.isFile) { + release.readLines().firstOrNull { it.startsWith("JAVA_VERSION=") }?.let { line -> + val raw = line.substringAfter("=").trim().trim('"') + val major = raw.substringBefore(".").toIntOrNull() + ?: raw.substringBefore("-").toIntOrNull() + if (major != null) return major + } + } + } + return 25 +} + +val swiftJavaJdk = detectJdkMajor() +gradle.extra["swiftJavaJdk"] = swiftJavaJdk + +val ffmCapable = swiftJavaJdk >= 22 + +// Modules and samples that depend on the FFM API (java.lang.foreign.*) +val ffmModules = setOf( + "SwiftKitFFM", + "SwiftJavaExtractFFMSampleApp", + "SwiftAndJavaJarFFMSampleLib", +) + +val skipped = mutableListOf() + include("SwiftKitCore") -include("SwiftKitFFM") +if (ffmCapable) { + include("SwiftKitFFM") +} else { + skipped += "SwiftKitFFM" +} // Include sample apps -- you can run them via `gradle Name:run` if (!(settings.providers.gradleProperty("skipSamples").orNull.toBoolean())) { - File(rootDir, "Samples").listFiles().forEach { + File(rootDir, "Samples").listFiles()?.forEach { if (it.isDirectory && (File(it, "build.gradle").exists() || File(it, "build.gradle.kts").exists())) { - include(":Samples:${it.name}") + val name = it.name + if (name in ffmModules && !ffmCapable) { + skipped += "Samples:$name" + } else { + include(":Samples:$name") + } } } } +if (skipped.isNotEmpty()) { + println("[swift-java] JDK $swiftJavaJdk detected — skipping: ${skipped.joinToString(", ")}") +} + enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")