Skip to content

Unlock Java CI, disable Java tests which rely on mangled names #40

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

Closed
wants to merge 5 commits into from
Closed
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
26 changes: 24 additions & 2 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ jobs:
- 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
- name: Gradle test
run: ./gradlew test --no-daemon

test-swift:
name: Swift tests (swift:${{ matrix.swift_version }} jdk:${{matrix.jdk_vendor}} os:${{ matrix.os_version }})
Expand All @@ -71,3 +71,25 @@ jobs:
run: "make jextract-run"
- name: Test Swift
run: "swift test"

make:
name: Make build (swift:${{ matrix.swift_version }} jdk:${{matrix.jdk_vendor}} os:${{ matrix.os_version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
swift_version: [ 'nightly-main' ]
os_version: [ 'jammy' ]
jdk_vendor: [ 'Corretto' ]
container:
image: ${{ (contains(matrix.swift_version, 'nightly') && 'swiftlang/swift') || 'swift' }}:${{ matrix.swift_version }}-${{ matrix.os_version }}
env:
JAVA_HOME: "/usr/lib/jvm/default-jdk"
steps:
- uses: actions/checkout@v4
- name: Install Make
run: apt-get -qq update && apt-get -qq install -y make
- name: Install JDK
run: "bash -xc 'JDK_VENDOR=${{ matrix.jdk_vendor }} ./docker/install_jdk.sh'"
- name: Make (default target)
run: "make"
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@
//
//===----------------------------------------------------------------------===//

import org.gradle.api.tasks.testing.logging.*
import java.util.*

plugins {
java
}

java {
toolchain {
languageVersion = JavaLanguageVersion.of(22)
}
}
//java {
// toolchain {
// languageVersion = JavaLanguageVersion.of(22)
// }
//}

repositories {
mavenCentral()
Expand All @@ -40,22 +43,61 @@ tasks.withType(JavaCompile::class).forEach {
it.options.compilerArgs.add("-Xlint:preview")
}

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 (osName.lowercase(Locale.getDefault()).contains("linux")) {
"""$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)
)
}

tasks.withType<Test> {
this.testLogging {
this.showStandardStreams = true
showStandardStreams = true
exceptionFormat = TestExceptionFormat.FULL

// set options for log level LIFECYCLE
events = setOf(TestLogEvent.FAILED,
TestLogEvent.PASSED,
TestLogEvent.SKIPPED,
TestLogEvent.STANDARD_OUT)
showExceptions = true
showCauses = true
showStackTraces = true

beforeTest(closureOf<TestDescriptor> {
logger.lifecycle("Test: ${this.className} > ${this.displayName}: ...")
})
afterTest(KotlinClosure2({ descriptor: TestDescriptor, result: TestResult ->
logger.lifecycle("Test: ${descriptor.className} > ${descriptor.displayName}: ${result.resultType}")
}))
}
}

Expand Down
17 changes: 17 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,23 @@ A good patch is:
3. Documented, adding API documentation as needed to cover new functions and properties.
4. Accompanied by a great commit message, using our commit message template.

### Developing in Docker

You can develop in Docker in order to test Linux behaviors while developing on a Mac.


First build the image:

```
docker build --tag swift-java docker
```

And run a development container:

```
docker run --rm -it -v$(pwd):/code swift-java /bin/bash
```

### Run CI checks locally

You can run the Github Actions workflows locally using
Expand Down
31 changes: 27 additions & 4 deletions JavaSwiftKitDemo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
//
//===----------------------------------------------------------------------===//

import java.util.*

plugins {
id("build-logic.java-application-conventions")
}
Expand All @@ -38,6 +40,30 @@ tasks.test {
useJUnitPlatform()
}

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 (osName.lowercase(Locale.getDefault()).contains("linux")) {
"""$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/"
}
)
}

application {
mainClass = "org.example.HelloJava2Swift"

Expand All @@ -51,10 +77,7 @@ application {
"--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(":"),
"-Djava.library.path=" + javaLibraryPaths().joinToString(File.pathSeparator),

// Enable tracing downcalls (to Swift)
"-Djextract.trace.downcalls=true"
Expand Down
10 changes: 1 addition & 9 deletions JavaSwiftKitDemo/src/main/java/org/example/HelloJava2Swift.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,10 @@

import com.example.swift.generated.JavaKitExample;
import com.example.swift.generated.MySwiftClass;
import org.example.swift.ManualJavaKitExample;
import org.example.swift.ManualMySwiftClass;
import org.swift.javakit.*;
import org.swift.swiftkit.SwiftKit;

// Import swift-extract generated sources
import static com.example.swift.generated.JavaKitExample.*;
import static com.example.swift.generated.MySwiftClass.*;

import java.lang.foreign.*;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// ==== Extra convenience APIs -------------------------------------------------------------------------------------
// TODO: Think about offering these or not, perhaps only as an option?

import org.swift.javakit.ManagedSwiftType;
import org.swift.swiftkit.ManagedSwiftType;

import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//

package org.swift.javakit;
package org.swift.swiftkit;

import java.lang.foreign.MemorySegment;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

package org.swift.swiftkit;

import org.swift.javakit.SwiftKit;

import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.util.concurrent.ConcurrentSkipListSet;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@

import java.lang.foreign.MemorySegment;

public interface SwiftHeapObject {
public interface SwiftHeapObject extends ManagedSwiftType {
MemorySegment $self();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
//
//===----------------------------------------------------------------------===//

package org.swift.javakit;

import org.swift.swiftkit.SwiftHeapObject;
package org.swift.swiftkit;

import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
Expand All @@ -25,8 +23,7 @@

public class SwiftKit {

// FIXME: why do we need to hardcore the path, seems it can't find by name
private static final String STDLIB_DYLIB_NAME = "swiftCore";
private static final String STDLIB_DYLIB_NAME = "swiftCore";
private static final String STDLIB_DYLIB_PATH = "/usr/lib/swift/libswiftCore.dylib";

private static final Arena LIBRARY_ARENA = Arena.ofAuto();
Expand All @@ -36,19 +33,37 @@ public class SwiftKit {
System.loadLibrary(STDLIB_DYLIB_NAME);
}

public static final AddressLayout SWIFT_POINTER = ValueLayout.ADDRESS
.withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE));

static final SymbolLookup SYMBOL_LOOKUP =
// FIXME: why does this not find just by name?
getSymbolLookup();

private static SymbolLookup getSymbolLookup() {
if (isMacOS()) {
// FIXME: why does this not find just by name on macOS?
// SymbolLookup.libraryLookup(System.mapLibraryName(STDLIB_DYLIB_NAME), LIBRARY_ARENA)
SymbolLookup.libraryLookup(STDLIB_DYLIB_PATH, LIBRARY_ARENA)
return SymbolLookup.libraryLookup(STDLIB_DYLIB_PATH, LIBRARY_ARENA)
.or(SymbolLookup.loaderLookup())
.or(Linker.nativeLinker().defaultLookup());
} else {
return SymbolLookup.loaderLookup()
.or(Linker.nativeLinker().defaultLookup());
}
}

public SwiftKit() {
}

public static boolean isLinux() {
return System.getProperty("os.name").toLowerCase().contains("linux");
}

public static boolean isMacOS() {
return System.getProperty("os.name").toLowerCase().contains("mac");
}

public static boolean isWindows() {
return System.getProperty("os.name").toLowerCase().contains("windows");
}

static void traceDowncall(String name, Object... args) {
String traceArgs = Arrays.stream(args)
.map(Object::toString)
Expand Down Expand Up @@ -153,6 +168,7 @@ public static long release(SwiftHeapObject object) {
}

// ==== ------------------------------------------------------------------------------------------------------------
// swift_getTypeByName

/**
* {@snippet lang=swift :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,43 +18,38 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import static com.example.swift.generated.JavaKitExample.*;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.opentest4j.TestSkippedException;
import org.swift.swiftkit.SwiftKit;

import static org.junit.jupiter.api.Assertions.*;

public class GlobalFunctionsTest {
@BeforeAll
static void beforeAll() {
System.out.printf("java.library.path = %s\n", System.getProperty("java.library.path"));

System.loadLibrary("swiftCore");
System.loadLibrary("JavaKitExample");

System.setProperty("jextract.trace.downcalls", "true");
}

@Test
@DisabledOnOs(OS.LINUX) // FIXME: enable on Linux when we get new compiler with mangled names in swift interfaces
void call_helloWorld() {
helloWorld();
JavaKitExample.helloWorld();

assertNotNull(helloWorld$address());
assertNotNull(JavaKitExample.helloWorld$address());
}

@Test
@DisabledOnOs(OS.LINUX) // FIXME: enable on Linux when we get new compiler with mangled names in swift interfaces
void call_globalTakeInt() {
JavaKitExample.globalTakeInt(12);

assertNotNull(globalTakeInt$address());
assertNotNull(JavaKitExample.globalTakeInt$address());
}

// @Test
// void call_globalCallJavaCallback() {
// var num = 0;
//
// JavaKitExample.globalCallJavaCallback(new Runnable() {
// @Override
// public void run() {
// num += 1;
// }
// });
//
// assertEquals(1, num);
// }
}
Loading
Loading