Skip to content

Reorganize build: SwiftKit has "swift kit" core, and SwiftKitExample #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,8 @@ jobs:
# distribution: 'zulu'
# java-version: '22'
# cache: 'gradle'
- name: Generate sources (make) (Temporary)
# TODO: this should be triggered by the respective builds
run: make jextract-run
- name: Gradle build
run: ./gradlew build --no-daemon
run: ./gradlew build --info --no-daemon

test-swift:
name: Swift tests (swift:${{ matrix.swift_version }} jdk:${{matrix.jdk_vendor}} os:${{ matrix.os_version }})
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ DerivedData/
.netrc
*.class
bin/
BuildLogic/out/

# Ignore gradle build artifacts
.gradle
**/build/
lib/

# Ignore package resolved
Package.resolved

# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
Expand All @@ -24,4 +29,4 @@ bin/
.gradletasknamecache

# Ignore generated sources
JavaSwiftKitDemo/src/main/java/com/example/swift/generated/*
**/generated/
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
//
//===----------------------------------------------------------------------===//

import java.util.*

plugins {
java
}
Expand Down Expand Up @@ -40,16 +42,44 @@ tasks.withType(JavaCompile::class).forEach {
it.options.compilerArgs.add("-Xlint:preview")
}


// FIXME: cannot share definition with 'buildSrc' so we duplicated the impl here
fun javaLibraryPaths(): List<String> {
val osName = System.getProperty("os.name")
val osArch = System.getProperty("os.arch")
val isLinux = osName.lowercase(Locale.getDefault()).contains("linux")

return listOf(
if (isLinux) {
if (osArch.equals("x86_64") || osArch.equals("amd64")) {
"$rootDir/.build/x86_64-unknown-linux-gnu/debug/"
} else {
"$rootDir/.build/$osArch-unknown-linux-gnu/debug/"
}
} else {
if (osArch.equals("aarch64")) {
"$rootDir/.build/arm64-apple-macosx/debug/"
} else {
"$rootDir/.build/$osArch-apple-macosx/debug/"
}
},
if (isLinux) {
"/usr/lib/swift/linux"
} else {
// assume macOS
"/usr/lib/swift/"
}
)
}


// Configure paths for native (Swift) libraries
tasks.test {
jvmArgs(
"--enable-native-access=ALL-UNNAMED",

// Include the library paths where our dylibs are that we want to load and call
"-Djava.library.path=" + listOf(
"""$rootDir/.build/arm64-apple-macosx/debug/""",
"/usr/lib/swift/"
).joinToString(File.pathSeparator)
"-Djava.library.path=" + javaLibraryPaths().joinToString(File.pathSeparator)
)
}

Expand All @@ -60,14 +90,15 @@ tasks.withType<Test> {
}


val buildSwiftJExtract = tasks.register<Exec>("buildSwiftJExtract") {
description = "Builds Swift targets, including jextract-swift"

workingDir("..")
commandLine("make")
}

tasks.build {
dependsOn(buildSwiftJExtract)
}
// TODO: This is a crude workaround, we'll remove 'make' soon and properly track build dependencies
// val buildSwiftJExtract = tasks.register<Exec>("buildMake") {
// description = "Triggers 'make' build"
//
// workingDir(rootDir)
// commandLine("make")
// }
//
// tasks.build {
// dependsOn(buildSwiftJExtract)
// }

32 changes: 17 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,15 @@ BUILD_DIR := .build/$(ARCH_SUBDIR)-apple-macosx
LIB_SUFFIX := dylib
endif

SAMPLES_DIR := "Samples"

all: generate-all

$(BUILD_DIR)/debug/libJavaKit.$(LIB_SUFFIX) $(BUILD_DIR)/debug/libJavaKitExample.$(LIB_SUFFIX) $(BUILD_DIR)/debug/Java2Swift:
$(BUILD_DIR)/debug/libJavaKit.$(LIB_SUFFIX) $(BUILD_DIR)/debug/Java2Swift:
swift build

./JavaSwiftKitDemo/build/classes/java/main/com/example/swift/HelloSubclass.class: JavaSwiftKitDemo/src/main/java/com/example/swift
./gradlew build

run: $(BUILD_DIR)/debug/libJavaKit.$(LIB_SUFFIX) $(BUILD_DIR)/debug/libJavaKitExample.$(LIB_SUFFIX) JavaSwiftKitDemo/src/main/java/com/example/swift
java -cp JavaSwiftKitDemo/build/classes/java/main -Djava.library.path=$(BUILD_DIR)/debug/ com.example.swift.HelloSwift
run: $(BUILD_DIR)/debug/libJavaKit.$(LIB_SUFFIX) $(BUILD_DIR)/debug/libExampleSwiftLibrary.$(LIB_SUFFIX)
./gradlew Samples:JavaKitSampleApp:run

Java2Swift: $(BUILD_DIR)/debug/Java2Swift

Expand All @@ -70,7 +68,8 @@ generate-JavaKitNetwork: Java2Swift generate-JavaKit
generate-all: generate-JavaKit generate-JavaKitReflection generate-JavaKitJar generate-JavaKitNetwork \
jextract-swift
clean:
rm -rf .build
rm -rf .build; \
rm -rf Samples/SwiftKitExampleApp/src/generated/java/*

format:
swift format --recursive . -i
Expand All @@ -81,7 +80,6 @@ format:

JEXTRACT_BUILD_DIR="$(BUILD_DIR)/jextract"

# Parameter: Swift source file
define make_swiftinterface
$(eval $@_MODULE = $(1))
$(eval $@_FILENAME = $(2))
Expand All @@ -99,17 +97,21 @@ jextract-swift: generate-JExtract-interface-files

generate-JExtract-interface-files: $(BUILD_DIR)/debug/libJavaKit.$(LIB_SUFFIX)
echo "Generate .swiftinterface files..."
@$(call make_swiftinterface, "JavaKitExample", "MySwiftLibrary")
@$(call make_swiftinterface, "JavaKitExample", "SwiftKit")
@$(call make_swiftinterface, "ExampleSwiftLibrary", "MySwiftLibrary")
@$(call make_swiftinterface, "SwiftKitSwift", "SwiftKit")

jextract-run: jextract-swift generate-JExtract-interface-files
swift run jextract-swift \
--package-name com.example.swift.generated \
--swift-module JavaKitExample \
--output-directory JavaSwiftKitDemo/src/main/java \
$(BUILD_DIR)/jextract/JavaKitExample/MySwiftLibrary.swiftinterface \
$(BUILD_DIR)/jextract/JavaKitExample/SwiftKit.swiftinterface
--swift-module ExampleSwiftLibrary \
--output-directory ${SAMPLES_DIR}/SwiftKitSampleApp/src/generated/java \
$(BUILD_DIR)/jextract/ExampleSwiftLibrary/MySwiftLibrary.swiftinterface; \
swift run jextract-swift \
--package-name org.swift.swiftkit.generated \
--swift-module SwiftKitSwift \
--output-directory ${SAMPLES_DIR}/SwiftKitSampleApp/src/generated/java \
$(BUILD_DIR)/jextract/SwiftKitSwift/SwiftKit.swiftinterface


jextract-run-java: jextract-swift generate-JExtract-interface-files
./gradlew run
./gradlew Samples:SwiftKitSampleApp:run
32 changes: 0 additions & 32 deletions Package.resolved

This file was deleted.

60 changes: 47 additions & 13 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func findJavaHome() -> String {
// This is a workaround for envs (some IDEs) which have trouble with
// picking up env variables during the build process
let path = "\(FileManager.default.homeDirectoryForCurrentUser.path()).java_home"
if let home = try? String(contentsOfFile: path) {
if let home = try? String(contentsOfFile: path, encoding: .utf8) {
if let lastChar = home.last, lastChar.isNewline {
return String(home.dropLast())
}
Expand All @@ -36,8 +36,8 @@ let javaIncludePath = "\(javaHome)/include"
#elseif os(macOS)
let javaPlatformIncludePath = "\(javaIncludePath)/darwin"
#else
// TODO: Handle windows as well
#error("Currently only macOS and Linux platforms are supported, this may change in the future.")
// TODO: Handle windows as well
#endif

let package = Package(
Expand All @@ -50,6 +50,7 @@ let package = Package(
.macCatalyst(.v13),
],
products: [
// ==== JavaKit (i.e. calling Java directly Swift utilities)
.library(
name: "JavaKit",
targets: ["JavaKit"]
Expand All @@ -70,12 +71,6 @@ let package = Package(
targets: ["JavaKitReflection"]
),

.library(
name: "JavaKitExample",
type: .dynamic,
targets: ["JavaKitExample"]
),

.library(
name: "JavaKitVM",
targets: ["JavaKitVM"]
Expand All @@ -86,20 +81,43 @@ let package = Package(
targets: ["JavaTypes"]
),

.library(
name: "JExtractSwift",
targets: ["JExtractSwift"]
),

.executable(
name: "Java2Swift",
targets: ["Java2Swift"]
),

// ==== jextract-swift (extract Java accessors from Swift interface files)

.executable(
name: "jextract-swift",
targets: ["JExtractSwiftTool"]
),

// Support library written in Swift for SwiftKit "Java"
.library(
name: "SwiftKitSwift",
type: .dynamic,
targets: ["SwiftKitSwift"]
),

.library(
name: "JExtractSwift",
targets: ["JExtractSwift"]
),

// ==== Examples

.library(
name: "JavaKitExample",
type: .dynamic,
targets: ["JavaKitExample"]
),
.library(
name: "ExampleSwiftLibrary",
type: .dynamic,
targets: ["ExampleSwiftLibrary"]
),

],
dependencies: [
.package(url: "https://github.com/swiftlang/swift-syntax.git", branch: "main"),
Expand Down Expand Up @@ -187,6 +205,22 @@ let package = Package(
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
]
),
.target(
name: "ExampleSwiftLibrary",
dependencies: [],
swiftSettings: [
.swiftLanguageMode(.v5),
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
]
),
.target(
name: "SwiftKitSwift",
dependencies: [],
swiftSettings: [
.swiftLanguageMode(.v5),
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
]
),

.target(
name: "JavaRuntime",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
//
//===----------------------------------------------------------------------===//

import org.swift.swiftkit.gradle.BuildUtils

plugins {
id("build-logic.java-application-conventions")
}
Expand All @@ -30,6 +32,8 @@ java {
}

dependencies {
implementation(project(':SwiftKit'))

testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
}
Expand All @@ -39,25 +43,18 @@ tasks.test {
}

application {
mainClass = "org.example.HelloJava2Swift"
mainClass = "com.example.swift.JavaKitSampleMain"

// In order to silence:
// WARNING: A restricted method in java.lang.foreign.SymbolLookup has been called
// WARNING: java.lang.foreign.SymbolLookup::libraryLookup has been called by org.example.swift.JavaKitExample in an unnamed module
// WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
// WARNING: Restricted methods will be blocked in a future release unless native access is enabled
// FIXME: Find out the proper solution to this
applicationDefaultJvmArgs = listOf(
"--enable-native-access=ALL-UNNAMED",

// Include the library paths where our dylibs are that we want to load and call
"-Djava.library.path=" + listOf(
"""$rootDir/.build/arm64-apple-macosx/debug/""",
"/usr/lib/swift/"
).joinToString(":"),

// Enable tracing downcalls (to Swift)
"-Djextract.trace.downcalls=true"
)
}
applicationDefaultJvmArgs = [
"--enable-native-access=ALL-UNNAMED",

// Include the library paths where our dylibs are that we want to load and call
"-Djava.library.path=" + BuildUtils.javaLibraryPaths(rootDir).join(":")
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

package com.example.swift;

import com.example.swift.HelloSwift;

public class HelloSubclass extends HelloSwift {
private String greeting;

Expand Down
Loading