Skip to content

Commit bdd3f01

Browse files
committed
C library for Pkl
This introduces native C bindings for Pkl. Dynamic Library --------------- Using `org.graalvm.nativeimage` and the `native-image` binary we produce a dynamic library (for each OS/Arch variant) that provides a way to initialise itself with a `graal_isolatethread_t`. Methods are annotated with `@CEntryPoint` and exported. This change results in an architecture and OS-specific directory being created which now produces the headers for our shared library functions: ``` ❯ ll libpkl/build/libs/macos-aarch64/ graal_isolate_dynamic.h graal_isolate.h libpkl-internal_dynamic.h libpkl-internal-macos-aarch64_dynamic.h libpkl-internal-macos-aarch64.dylib libpkl-internal-macos-aarch64.h libpkl-internal.dylib libpkl-internal.h ``` `libpkl` -------- The produced `libpkl` dynamic library wraps the GraalVM C interface into something that is future-friendly for the needs of a Pkl integrator. It exports an interface which aligns with SPICE-0015[1]. ``` ❯ ll libpkl/build/libs/macos-aarch64/ graal_isolate_dynamic.h graal_isolate.h libpkl-internal_dynamic.h libpkl-internal-macos-aarch64_dynamic.h libpkl-internal-macos-aarch64.dylib libpkl-internal-macos-aarch64.h libpkl-internal.dylib libpkl-internal.h libpkl.dylib <--- this is new libpkl.h <--- this is new ``` JNA --- Testing of the produced `libpkl` dynamic library is done using Java Native Access[2] for ease. We provide an `interface` in Kotlin which JNA transposes against the `libpkl` dynamic library discoverable at the path that is discoverable with `jna.library.path`. Load in `projects.pklCommonsCli` to deal with `UnsupportedFeatureException` --------------------------------------------------------------------------- This is to deal with the following error: ``` Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: Detected a started Thread in the image heap. Thread name: main. Threads running in the image generator are no longer running at image runtime. If these objects should not be stored in the image heap, you can use '--trace-object-instantiation=java.lang.Thread' ``` [1] apple/pkl-evolution#16 Rename to `LibPklLibrary` Remove `lib` prefix from `.h` and `.c` files Add doxygen-style comments to `pkl.h` file Move pointer next to variable name Add TODO comment to clean this up once on a feature-branch Add `@SuppressWarnings("unused")` annotation to `LibPkl` class Move `LibPkl` constructor between fields and methods Add `package-info.java` for `org.pkl.libpkl` package Propagate param `handlerContext` so users can trace messages This allows a user to provide a pointer, and have it be passed through and back to their `PklMessageResponseHandler` handler for them track as part of their own bookkeeping. Drop the OS and Arch name from the `native-image` shared library TODO: Provide a meaningful error to user if `cb == null` Log exceptions in `NativeTransport` Address PR comments Gradle adjustments for libpkl (#1081) * Move native tests into `nativeTest` source set; they are now run with `./gradlew testNative` and skipped in `./gradlew test`. * Fix native tests to be platform independent * In `NativeImageBuild`: Add `abstract val sharedLibrary: Property<Boolean>` property to `NativeImageBuild` * In `NativeImageBuild`: Make `mainClass` optional * Introduce enum class `Target`, which enumerates over all the target machines that we support building * Simplify build logic (move common logic into `configure()` extension methods) * Remove `LibPkl.main`, which is no longer needed * Run `libpkl` tests in CircleCI (let's run these for now on this branch, but let's remove it prior to merging). Make libpkl tests use AbstractServerTest (#1084) * Move AbstractServerTest and its dependencies into pkl-commons-test * Make LibPklTest implement AbstractServerTest * Rename "NativeTest" -> "LibPklTest" * Rename "LibPklLibrary" -> "LibPklJNA" Fix `pkl.h` header include path for `Exec.configureCompile` (#1123) Otherwise the main interface `pkl.h` won't be present in the generated library directory. Expose version of Pkl within native library using `pkl_version` (#1124) * Be consistent: use `userData` as parameter name, as per SPICE * Expose version of Pkl within native library using `pkl_version` This allows consumers of the native library to know which version of Pkl they're using, e.g. to build version-specific gates around newer functionality. Run `graal_attach_thread` ahead of all calls (#1131) * Rename `isolatethread` to `graal_isolatethread` * Run `graal_attach_thread` ahead of all calls This is to deal with the case when using a language like Golang, where a Goroutine is managed by the runtime, and can be moved to an arbitrary system thread behind the scenes.
1 parent fe06496 commit bdd3f01

File tree

33 files changed

+2123
-301
lines changed

33 files changed

+2123
-301
lines changed

.circleci/config.pkl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import "jobs/GradleCheckJob.pkl"
2121
import "jobs/DeployJob.pkl"
2222
import "jobs/SimpleGradleJob.pkl"
2323

24-
local prbJobs: Listing<String> = gradleCheckJobs.keys.toListing()
24+
local prbJobs: Listing<String> = (gradleCheckJobs.keys + buildNativeJobs.keys.filter((it) -> it.startsWith("libpkl") && it.endsWith("snapshot"))).toListing()
2525

2626
local buildAndTestJobs = (prbJobs) {
2727
"bench"
@@ -81,14 +81,15 @@ triggerPackageDocsBuild = "release"
8181

8282
local buildNativeJobs: Mapping<String, BuildNativeJob> = new {
8383
for (_dist in List("release", "snapshot")) {
84-
for (_project in List("pkl-cli", "pkl-doc")) {
84+
for (_project in List("pkl-cli", "pkl-doc", "libpkl")) {
8585
for (_arch in List("amd64", "aarch64")) {
8686
for (_os in List("macOS", "linux")) {
8787
["\(_project)-\(_os)-\(_arch)-\(_dist)"] {
8888
arch = _arch
8989
os = _os
9090
isRelease = _dist == "release"
9191
project = _project
92+
buildDir = if (_project == "libpkl") "libpkl/build/native-libs/" else "\(_project)/build/executable/"
9293
}
9394
}
9495
}
@@ -98,12 +99,14 @@ local buildNativeJobs: Mapping<String, BuildNativeJob> = new {
9899
musl = true
99100
isRelease = _dist == "release"
100101
project = _project
102+
buildDir = if (_project == "libpkl") "libpkl/build/native-libs/" else "\(_project)/build/executable/"
101103
}
102104
["\(_project)-windows-amd64-\(_dist)"] {
103105
arch = "amd64"
104106
os = "windows"
105107
isRelease = _dist == "release"
106108
project = _project
109+
buildDir = if (_project == "libpkl") "libpkl/build/native-libs/" else "\(_project)/build/executable/"
107110
}
108111
}
109112
}

0 commit comments

Comments
 (0)