Skip to content

Conversation

@KushalP
Copy link

@KushalP KushalP commented Mar 18, 2025

This adds a new SPICE to provide native bindings for Pkl.

Relevant discussions/issues

@KushalP KushalP marked this pull request as ready for review March 18, 2025 15:36
KushalP added a commit to KushalP/pkl that referenced this pull request Apr 24, 2025
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
KushalP added a commit to KushalP/pkl that referenced this pull request May 7, 2025
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
KushalP added a commit to KushalP/pkl that referenced this pull request May 27, 2025
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
bioball pushed a commit to KushalP/pkl that referenced this pull request May 28, 2025
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
bioball pushed a commit to apple/pkl that referenced this pull request May 28, 2025
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
@KushalP KushalP force-pushed the c-library-for-pkl branch from 72860f1 to beeaa06 Compare June 3, 2025 13:15
@KushalP KushalP mentioned this pull request Jul 22, 2025
6 tasks
KushalP added a commit to apple/pkl that referenced this pull request Jul 22, 2025
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.
This was referenced Jul 22, 2025
KushalP added a commit to KushalP/pkl that referenced this pull request Jul 23, 2025
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 (apple#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 (apple#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` (apple#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` (apple#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 (apple#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.
KushalP added a commit to KushalP/pkl that referenced this pull request Jul 25, 2025
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
KushalP added a commit to KushalP/pkl that referenced this pull request Jul 25, 2025
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
bioball pushed a commit to bioball/pkl that referenced this pull request Oct 3, 2025
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
bioball pushed a commit to bioball/pkl that referenced this pull request Oct 14, 2025
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants