mirror of
https://github.com/apple/pkl.git
synced 2026-08-03 18:58:40 +02:00
Introduce C library for Pkl (#1238)
This uses native-image to generate a C library for Pkl. This generated library from native-image is wrapped with our own library, in `pkl.h`. This produces a static and a dynamic library for each os/arch variant that Pkl currently supports. Co-authored-by: Kushal Pisavadia <kushal.p@apple.com> Co-authored-by: Jen Basch <jbasch94@gmail.com> Co-authored-by: Islon Scherer <i_desouzascherer@apple.com>
This commit is contained in:
co-authored by
Kushal Pisavadia
Jen Basch
Islon Scherer
parent
175e2b6273
commit
67df676359
+4
-1
@@ -61,13 +61,14 @@ local gradleCheckJobs: PklJobs = new {
|
||||
|
||||
local buildNativeJobs: Mapping<String, BuildNativeJob> = new {
|
||||
for (_dist in List("release", "snapshot")) {
|
||||
for (_project in List("pkl-cli", "pkl-doc")) {
|
||||
for (_project in List("pkl-cli", "pkl-doc", "libpkl")) {
|
||||
for (_arch in List("amd64", "aarch64")) {
|
||||
["\(_project)-linux-\(_arch)-\(_dist)"] {
|
||||
arch = _arch
|
||||
os = "linux"
|
||||
isRelease = _dist == "release"
|
||||
project = _project
|
||||
buildDir = if (_project == "libpkl") "libpkl/build/native-libs/**/*" else "\(_project)*/build/executable/**/*"
|
||||
}
|
||||
}
|
||||
["\(_project)-macOS-aarch64-\(_dist)"] {
|
||||
@@ -82,12 +83,14 @@ local buildNativeJobs: Mapping<String, BuildNativeJob> = new {
|
||||
musl = true
|
||||
isRelease = _dist == "release"
|
||||
project = _project
|
||||
buildDir = if (_project == "libpkl") "libpkl*/build/distributions/**/*" else "\(_project)*/build/executable/**/*"
|
||||
}
|
||||
["\(_project)-windows-amd64-\(_dist)"] {
|
||||
arch = "amd64"
|
||||
os = "windows"
|
||||
isRelease = _dist == "release"
|
||||
project = _project
|
||||
buildDir = if (_project == "libpkl") "libpkl*/build/distributions/**/*" else "\(_project)*/build/executable/**/*"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
extends "GradleJob.pkl"
|
||||
|
||||
import "@gha/catalog.pkl"
|
||||
import "@gha/context.pkl"
|
||||
|
||||
/// Whether to link to musl. Otherwise, links to glibc.
|
||||
musl: Boolean(implies(module.os == "linux")) = false
|
||||
@@ -9,6 +8,11 @@ musl: Boolean(implies(module.os == "linux")) = false
|
||||
/// The Gradle project under which to generate the executable
|
||||
project: String
|
||||
|
||||
/// Path pattern for artifact uploads (glob passed to actions/upload-artifact)
|
||||
buildDir: String = "\(project)*/build/executable/**/*"
|
||||
|
||||
local needsCCompiler = project == "libpkl"
|
||||
|
||||
extraGradleArgs {
|
||||
when (musl) {
|
||||
"-Dpkl.musl=true"
|
||||
@@ -40,22 +44,28 @@ steps {
|
||||
run = #"git status || git config --system --add safe.directory "$GITHUB_WORKSPACE""#
|
||||
}
|
||||
}
|
||||
when (needsCCompiler && os == "windows") {
|
||||
new {
|
||||
name = "Set up MSVC"
|
||||
uses = "ilammy/msvc-dev-cmd@v1"
|
||||
}
|
||||
}
|
||||
new {
|
||||
name = "gradle buildNative"
|
||||
shell = "bash"
|
||||
run = "./gradlew \(module.gradleArgs) \(project):buildNative"
|
||||
}
|
||||
(catalog.`actions/upload-artifact@v5`) {
|
||||
name = "Upload executable artifacts"
|
||||
name = "Upload built artifacts"
|
||||
with {
|
||||
name =
|
||||
if (musl)
|
||||
"executable-\(project)-alpine-\(module.os)-\(module.arch)"
|
||||
"artifacts-\(project)-alpine-\(module.os)-\(module.arch)"
|
||||
else
|
||||
"executable-\(project)-\(module.os)-\(module.arch)"
|
||||
"artifacts-\(project)-\(module.os)-\(module.arch)"
|
||||
// Need to insert a wildcard to make actions/upload-artifact preserve the folder hierarchy.
|
||||
// See https://github.com/actions/upload-artifact/issues/206
|
||||
path = "\(project)*/build/executable/**/*"
|
||||
path = module.buildDir
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+2
@@ -38,3 +38,5 @@ jobs:
|
||||
uses: gradle/actions/dependency-submission@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6
|
||||
- name: gradle/actions/setup-gradle@v5
|
||||
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
- name: ilammy/msvc-dev-cmd@v1
|
||||
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1
|
||||
|
||||
Generated
+336
-20
@@ -239,10 +239,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-linux-amd64
|
||||
name: artifacts-pkl-cli-linux-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -289,10 +289,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-linux-aarch64
|
||||
name: artifacts-pkl-cli-linux-aarch64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -338,10 +338,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-macOS-aarch64
|
||||
name: artifacts-pkl-cli-macOS-aarch64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -455,10 +455,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-alpine-linux-amd64
|
||||
name: artifacts-pkl-cli-alpine-linux-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -500,10 +500,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-windows-amd64
|
||||
name: artifacts-pkl-cli-windows-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -548,10 +548,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-linux-amd64
|
||||
name: artifacts-pkl-doc-linux-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -598,10 +598,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-linux-aarch64
|
||||
name: artifacts-pkl-doc-linux-aarch64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -647,10 +647,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-macOS-aarch64
|
||||
name: artifacts-pkl-doc-macOS-aarch64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -764,10 +764,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-alpine-linux-amd64
|
||||
name: artifacts-pkl-doc-alpine-linux-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -809,10 +809,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-windows-amd64
|
||||
name: artifacts-pkl-doc-windows-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -827,6 +827,317 @@ jobs:
|
||||
name: test-results-html-pkl-doc-windows-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-linux-amd64-snapshot:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Fix git ownership
|
||||
run: git status || git config --system --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-linux-amd64
|
||||
path: libpkl/build/native-libs/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-linux-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-linux-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
container:
|
||||
image: redhat/ubi8:8.10
|
||||
libpkl-linux-aarch64-snapshot:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: aarch64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Fix git ownership
|
||||
run: git status || git config --system --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-linux-aarch64
|
||||
path: libpkl/build/native-libs/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-linux-aarch64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-linux-aarch64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
container:
|
||||
image: redhat/ubi8:8.10
|
||||
libpkl-macOS-aarch64-snapshot:
|
||||
if: github.repository_owner == 'apple'
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- macos
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: aarch64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-macOS-aarch64
|
||||
path: libpkl*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-macOS-aarch64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-macOS-aarch64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-alpine-linux-amd64-snapshot:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Install musl and zlib
|
||||
run: |
|
||||
set -e
|
||||
mkdir -p ~/staticdeps/
|
||||
|
||||
ZLIB_VERSION="1.2.13"
|
||||
MUSL_VERSION="1.2.5"
|
||||
|
||||
# install zlib
|
||||
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
|
||||
# Download zlib tarball and signature
|
||||
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
|
||||
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
|
||||
|
||||
# Import zlib GPG key
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
|
||||
|
||||
# Verify GPG signature
|
||||
echo "Verifying zlib GPG signature..."
|
||||
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
|
||||
|
||||
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
|
||||
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
|
||||
# shellcheck disable=SC2002
|
||||
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: configure..."
|
||||
./configure --static --prefix="$HOME"/staticdeps > /dev/null
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: make..."
|
||||
make -s -j4
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: make install..."
|
||||
make -s install
|
||||
|
||||
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
|
||||
fi
|
||||
|
||||
# install musl
|
||||
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
|
||||
# Download musl tarball and signature
|
||||
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
|
||||
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
|
||||
|
||||
# Import musl GPG key
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
|
||||
|
||||
# Verify GPG signature
|
||||
echo "Verifying musl GPG signature..."
|
||||
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
|
||||
|
||||
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
cd "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
|
||||
# shellcheck disable=SC2002
|
||||
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
|
||||
|
||||
echo "musl-${MUSL_VERSION}: configure..."
|
||||
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
|
||||
|
||||
echo "musl-${MUSL_VERSION}: make..."
|
||||
make -s -j4
|
||||
|
||||
echo "musl-${MUSL_VERSION}: make install..."
|
||||
make -s install
|
||||
|
||||
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
|
||||
# native-image expects to find an executable at this path.
|
||||
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
|
||||
fi
|
||||
|
||||
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-alpine-linux-amd64
|
||||
path: libpkl*/build/distributions/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-alpine-linux-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-alpine-linux-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-windows-amd64-snapshot:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
JAVA_HOME: /jdk
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Set up MSVC
|
||||
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-windows-amd64
|
||||
path: libpkl*/build/distributions/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-windows-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-windows-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
publish-test-results:
|
||||
if: '!cancelled()'
|
||||
needs:
|
||||
@@ -844,6 +1155,11 @@ jobs:
|
||||
- pkl-doc-macOS-aarch64-snapshot
|
||||
- pkl-doc-alpine-linux-amd64-snapshot
|
||||
- pkl-doc-windows-amd64-snapshot
|
||||
- libpkl-linux-amd64-snapshot
|
||||
- libpkl-linux-aarch64-snapshot
|
||||
- libpkl-macOS-aarch64-snapshot
|
||||
- libpkl-alpine-linux-amd64-snapshot
|
||||
- libpkl-windows-amd64-snapshot
|
||||
permissions:
|
||||
checks: write
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
Generated
+346
-20
@@ -237,10 +237,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-linux-amd64
|
||||
name: artifacts-pkl-cli-linux-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -287,10 +287,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-linux-aarch64
|
||||
name: artifacts-pkl-cli-linux-aarch64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -336,10 +336,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-macOS-aarch64
|
||||
name: artifacts-pkl-cli-macOS-aarch64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -453,10 +453,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-alpine-linux-amd64
|
||||
name: artifacts-pkl-cli-alpine-linux-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -498,10 +498,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-windows-amd64
|
||||
name: artifacts-pkl-cli-windows-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -546,10 +546,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-linux-amd64
|
||||
name: artifacts-pkl-doc-linux-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -596,10 +596,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-linux-aarch64
|
||||
name: artifacts-pkl-doc-linux-aarch64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -645,10 +645,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-macOS-aarch64
|
||||
name: artifacts-pkl-doc-macOS-aarch64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -762,10 +762,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-alpine-linux-amd64
|
||||
name: artifacts-pkl-doc-alpine-linux-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -807,10 +807,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-windows-amd64
|
||||
name: artifacts-pkl-doc-windows-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -825,6 +825,317 @@ jobs:
|
||||
name: test-results-html-pkl-doc-windows-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-linux-amd64-snapshot:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Fix git ownership
|
||||
run: git status || git config --system --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-linux-amd64
|
||||
path: libpkl/build/native-libs/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-linux-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-linux-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
container:
|
||||
image: redhat/ubi8:8.10
|
||||
libpkl-linux-aarch64-snapshot:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: aarch64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Fix git ownership
|
||||
run: git status || git config --system --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-linux-aarch64
|
||||
path: libpkl/build/native-libs/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-linux-aarch64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-linux-aarch64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
container:
|
||||
image: redhat/ubi8:8.10
|
||||
libpkl-macOS-aarch64-snapshot:
|
||||
if: github.repository_owner == 'apple'
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- macos
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: aarch64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-macOS-aarch64
|
||||
path: libpkl*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-macOS-aarch64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-macOS-aarch64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-alpine-linux-amd64-snapshot:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Install musl and zlib
|
||||
run: |
|
||||
set -e
|
||||
mkdir -p ~/staticdeps/
|
||||
|
||||
ZLIB_VERSION="1.2.13"
|
||||
MUSL_VERSION="1.2.5"
|
||||
|
||||
# install zlib
|
||||
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
|
||||
# Download zlib tarball and signature
|
||||
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
|
||||
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
|
||||
|
||||
# Import zlib GPG key
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
|
||||
|
||||
# Verify GPG signature
|
||||
echo "Verifying zlib GPG signature..."
|
||||
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
|
||||
|
||||
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
|
||||
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
|
||||
# shellcheck disable=SC2002
|
||||
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: configure..."
|
||||
./configure --static --prefix="$HOME"/staticdeps > /dev/null
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: make..."
|
||||
make -s -j4
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: make install..."
|
||||
make -s install
|
||||
|
||||
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
|
||||
fi
|
||||
|
||||
# install musl
|
||||
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
|
||||
# Download musl tarball and signature
|
||||
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
|
||||
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
|
||||
|
||||
# Import musl GPG key
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
|
||||
|
||||
# Verify GPG signature
|
||||
echo "Verifying musl GPG signature..."
|
||||
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
|
||||
|
||||
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
cd "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
|
||||
# shellcheck disable=SC2002
|
||||
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
|
||||
|
||||
echo "musl-${MUSL_VERSION}: configure..."
|
||||
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
|
||||
|
||||
echo "musl-${MUSL_VERSION}: make..."
|
||||
make -s -j4
|
||||
|
||||
echo "musl-${MUSL_VERSION}: make install..."
|
||||
make -s install
|
||||
|
||||
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
|
||||
# native-image expects to find an executable at this path.
|
||||
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
|
||||
fi
|
||||
|
||||
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-alpine-linux-amd64
|
||||
path: libpkl*/build/distributions/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-alpine-linux-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-alpine-linux-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-windows-amd64-snapshot:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
JAVA_HOME: /jdk
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Set up MSVC
|
||||
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-windows-amd64
|
||||
path: libpkl*/build/distributions/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-windows-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-windows-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
deploy-snapshot:
|
||||
needs:
|
||||
- gradle-check
|
||||
@@ -842,6 +1153,11 @@ jobs:
|
||||
- pkl-doc-macOS-aarch64-snapshot
|
||||
- pkl-doc-alpine-linux-amd64-snapshot
|
||||
- pkl-doc-windows-amd64-snapshot
|
||||
- libpkl-linux-amd64-snapshot
|
||||
- libpkl-linux-aarch64-snapshot
|
||||
- libpkl-macOS-aarch64-snapshot
|
||||
- libpkl-alpine-linux-amd64-snapshot
|
||||
- libpkl-windows-amd64-snapshot
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
@@ -911,6 +1227,11 @@ jobs:
|
||||
- pkl-doc-macOS-aarch64-snapshot
|
||||
- pkl-doc-alpine-linux-amd64-snapshot
|
||||
- pkl-doc-windows-amd64-snapshot
|
||||
- libpkl-linux-amd64-snapshot
|
||||
- libpkl-linux-aarch64-snapshot
|
||||
- libpkl-macOS-aarch64-snapshot
|
||||
- libpkl-alpine-linux-amd64-snapshot
|
||||
- libpkl-windows-amd64-snapshot
|
||||
permissions:
|
||||
checks: write
|
||||
runs-on: ubuntu-latest
|
||||
@@ -949,6 +1270,11 @@ jobs:
|
||||
- pkl-doc-macOS-aarch64-snapshot
|
||||
- pkl-doc-alpine-linux-amd64-snapshot
|
||||
- pkl-doc-windows-amd64-snapshot
|
||||
- libpkl-linux-amd64-snapshot
|
||||
- libpkl-linux-aarch64-snapshot
|
||||
- libpkl-macOS-aarch64-snapshot
|
||||
- libpkl-alpine-linux-amd64-snapshot
|
||||
- libpkl-windows-amd64-snapshot
|
||||
- deploy-snapshot
|
||||
- dependency-submission
|
||||
- publish-test-results
|
||||
|
||||
Generated
+345
-20
@@ -123,10 +123,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-linux-amd64
|
||||
name: artifacts-pkl-cli-linux-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -175,10 +175,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-linux-aarch64
|
||||
name: artifacts-pkl-cli-linux-aarch64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -225,10 +225,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-macOS-aarch64
|
||||
name: artifacts-pkl-cli-macOS-aarch64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -344,10 +344,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-alpine-linux-amd64
|
||||
name: artifacts-pkl-cli-alpine-linux-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -391,10 +391,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-windows-amd64
|
||||
name: artifacts-pkl-cli-windows-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -441,10 +441,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-linux-amd64
|
||||
name: artifacts-pkl-doc-linux-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -493,10 +493,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-linux-aarch64
|
||||
name: artifacts-pkl-doc-linux-aarch64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -543,10 +543,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-macOS-aarch64
|
||||
name: artifacts-pkl-doc-macOS-aarch64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -662,10 +662,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-alpine-linux-amd64
|
||||
name: artifacts-pkl-doc-alpine-linux-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -709,10 +709,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-windows-amd64
|
||||
name: artifacts-pkl-doc-windows-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -728,6 +728,326 @@ jobs:
|
||||
name: test-results-html-pkl-doc-windows-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-linux-amd64-snapshot:
|
||||
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-libpkl]') || contains(github.event.pull_request.body, '[native-libpkl-linux]') || contains(github.event.pull_request.body, '[native-libpkl-linux-amd64]') || contains(github.event.pull_request.body, '[native-libpkl-linux-amd64]')
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Fix git ownership
|
||||
run: git status || git config --system --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-linux-amd64
|
||||
path: libpkl/build/native-libs/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-linux-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
if-no-files-found: ignore
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-linux-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
container:
|
||||
image: redhat/ubi8:8.10
|
||||
libpkl-linux-aarch64-snapshot:
|
||||
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-libpkl]') || contains(github.event.pull_request.body, '[native-libpkl-linux]') || contains(github.event.pull_request.body, '[native-libpkl-linux-aarch64]') || contains(github.event.pull_request.body, '[native-libpkl-linux-aarch64]')
|
||||
runs-on: ubuntu-24.04-arm
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: aarch64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Fix git ownership
|
||||
run: git status || git config --system --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-linux-aarch64
|
||||
path: libpkl/build/native-libs/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-linux-aarch64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
if-no-files-found: ignore
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-linux-aarch64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
container:
|
||||
image: redhat/ubi8:8.10
|
||||
libpkl-macOS-aarch64-snapshot:
|
||||
if: (contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-libpkl]') || contains(github.event.pull_request.body, '[native-libpkl-macOS]') || contains(github.event.pull_request.body, '[native-libpkl-macOS-aarch64]') || contains(github.event.pull_request.body, '[native-libpkl-macOS-aarch64]')) && github.repository_owner == 'apple'
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- macos
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: aarch64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-macOS-aarch64
|
||||
path: libpkl*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-macOS-aarch64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
if-no-files-found: ignore
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-macOS-aarch64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-alpine-linux-amd64-snapshot:
|
||||
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-libpkl]') || contains(github.event.pull_request.body, '[native-libpkl-linux]') || contains(github.event.pull_request.body, '[native-libpkl-linux-amd64]') || contains(github.event.pull_request.body, '[native-libpkl-linux-amd64]') || contains(github.event.pull_request.body, '[native-libpkl-alpine-linux-amd64]')
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Install musl and zlib
|
||||
run: |
|
||||
set -e
|
||||
mkdir -p ~/staticdeps/
|
||||
|
||||
ZLIB_VERSION="1.2.13"
|
||||
MUSL_VERSION="1.2.5"
|
||||
|
||||
# install zlib
|
||||
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
|
||||
# Download zlib tarball and signature
|
||||
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
|
||||
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
|
||||
|
||||
# Import zlib GPG key
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
|
||||
|
||||
# Verify GPG signature
|
||||
echo "Verifying zlib GPG signature..."
|
||||
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
|
||||
|
||||
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
|
||||
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
|
||||
# shellcheck disable=SC2002
|
||||
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: configure..."
|
||||
./configure --static --prefix="$HOME"/staticdeps > /dev/null
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: make..."
|
||||
make -s -j4
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: make install..."
|
||||
make -s install
|
||||
|
||||
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
|
||||
fi
|
||||
|
||||
# install musl
|
||||
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
|
||||
# Download musl tarball and signature
|
||||
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
|
||||
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
|
||||
|
||||
# Import musl GPG key
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
|
||||
|
||||
# Verify GPG signature
|
||||
echo "Verifying musl GPG signature..."
|
||||
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
|
||||
|
||||
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
cd "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
|
||||
# shellcheck disable=SC2002
|
||||
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
|
||||
|
||||
echo "musl-${MUSL_VERSION}: configure..."
|
||||
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
|
||||
|
||||
echo "musl-${MUSL_VERSION}: make..."
|
||||
make -s -j4
|
||||
|
||||
echo "musl-${MUSL_VERSION}: make install..."
|
||||
make -s install
|
||||
|
||||
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
|
||||
# native-image expects to find an executable at this path.
|
||||
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
|
||||
fi
|
||||
|
||||
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-alpine-linux-amd64
|
||||
path: libpkl*/build/distributions/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-alpine-linux-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
if-no-files-found: ignore
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-alpine-linux-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-windows-amd64-snapshot:
|
||||
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-libpkl]') || contains(github.event.pull_request.body, '[native-libpkl-windows]') || contains(github.event.pull_request.body, '[native-libpkl-windows-amd64]') || contains(github.event.pull_request.body, '[native-libpkl-windows-amd64]')
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
JAVA_HOME: /jdk
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Set up MSVC
|
||||
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-windows-amd64
|
||||
path: libpkl*/build/distributions/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-windows-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
if-no-files-found: ignore
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-windows-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
verdict:
|
||||
if: always()
|
||||
needs:
|
||||
@@ -744,6 +1064,11 @@ jobs:
|
||||
- pkl-doc-macOS-aarch64-snapshot
|
||||
- pkl-doc-alpine-linux-amd64-snapshot
|
||||
- pkl-doc-windows-amd64-snapshot
|
||||
- libpkl-linux-amd64-snapshot
|
||||
- libpkl-linux-aarch64-snapshot
|
||||
- libpkl-macOS-aarch64-snapshot
|
||||
- libpkl-alpine-linux-amd64-snapshot
|
||||
- libpkl-windows-amd64-snapshot
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Failure verdict
|
||||
|
||||
Generated
+341
-20
@@ -237,10 +237,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-linux-amd64
|
||||
name: artifacts-pkl-cli-linux-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -287,10 +287,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-linux-aarch64
|
||||
name: artifacts-pkl-cli-linux-aarch64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -336,10 +336,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-macOS-aarch64
|
||||
name: artifacts-pkl-cli-macOS-aarch64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -453,10 +453,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-alpine-linux-amd64
|
||||
name: artifacts-pkl-cli-alpine-linux-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -498,10 +498,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-windows-amd64
|
||||
name: artifacts-pkl-cli-windows-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -546,10 +546,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-linux-amd64
|
||||
name: artifacts-pkl-doc-linux-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -596,10 +596,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-linux-aarch64
|
||||
name: artifacts-pkl-doc-linux-aarch64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -645,10 +645,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-macOS-aarch64
|
||||
name: artifacts-pkl-doc-macOS-aarch64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -762,10 +762,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-alpine-linux-amd64
|
||||
name: artifacts-pkl-doc-alpine-linux-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -807,10 +807,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-windows-amd64
|
||||
name: artifacts-pkl-doc-windows-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -825,6 +825,317 @@ jobs:
|
||||
name: test-results-html-pkl-doc-windows-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-linux-amd64-snapshot:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Fix git ownership
|
||||
run: git status || git config --system --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-linux-amd64
|
||||
path: libpkl/build/native-libs/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-linux-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-linux-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
container:
|
||||
image: redhat/ubi8:8.10
|
||||
libpkl-linux-aarch64-snapshot:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: aarch64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Fix git ownership
|
||||
run: git status || git config --system --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-linux-aarch64
|
||||
path: libpkl/build/native-libs/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-linux-aarch64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-linux-aarch64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
container:
|
||||
image: redhat/ubi8:8.10
|
||||
libpkl-macOS-aarch64-snapshot:
|
||||
if: github.repository_owner == 'apple'
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- macos
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: aarch64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-macOS-aarch64
|
||||
path: libpkl*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-macOS-aarch64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-macOS-aarch64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-alpine-linux-amd64-snapshot:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Install musl and zlib
|
||||
run: |
|
||||
set -e
|
||||
mkdir -p ~/staticdeps/
|
||||
|
||||
ZLIB_VERSION="1.2.13"
|
||||
MUSL_VERSION="1.2.5"
|
||||
|
||||
# install zlib
|
||||
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
|
||||
# Download zlib tarball and signature
|
||||
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
|
||||
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
|
||||
|
||||
# Import zlib GPG key
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
|
||||
|
||||
# Verify GPG signature
|
||||
echo "Verifying zlib GPG signature..."
|
||||
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
|
||||
|
||||
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
|
||||
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
|
||||
# shellcheck disable=SC2002
|
||||
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: configure..."
|
||||
./configure --static --prefix="$HOME"/staticdeps > /dev/null
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: make..."
|
||||
make -s -j4
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: make install..."
|
||||
make -s install
|
||||
|
||||
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
|
||||
fi
|
||||
|
||||
# install musl
|
||||
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
|
||||
# Download musl tarball and signature
|
||||
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
|
||||
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
|
||||
|
||||
# Import musl GPG key
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
|
||||
|
||||
# Verify GPG signature
|
||||
echo "Verifying musl GPG signature..."
|
||||
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
|
||||
|
||||
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
cd "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
|
||||
# shellcheck disable=SC2002
|
||||
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
|
||||
|
||||
echo "musl-${MUSL_VERSION}: configure..."
|
||||
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
|
||||
|
||||
echo "musl-${MUSL_VERSION}: make..."
|
||||
make -s -j4
|
||||
|
||||
echo "musl-${MUSL_VERSION}: make install..."
|
||||
make -s install
|
||||
|
||||
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
|
||||
# native-image expects to find an executable at this path.
|
||||
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
|
||||
fi
|
||||
|
||||
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-alpine-linux-amd64
|
||||
path: libpkl*/build/distributions/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-alpine-linux-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-alpine-linux-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-windows-amd64-snapshot:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
JAVA_HOME: /jdk
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with: {}
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Set up MSVC
|
||||
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-windows-amd64
|
||||
path: libpkl*/build/distributions/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-windows-amd64-snapshot
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-windows-amd64-snapshot
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
publish-test-results:
|
||||
if: '!cancelled()'
|
||||
needs:
|
||||
@@ -842,6 +1153,11 @@ jobs:
|
||||
- pkl-doc-macOS-aarch64-snapshot
|
||||
- pkl-doc-alpine-linux-amd64-snapshot
|
||||
- pkl-doc-windows-amd64-snapshot
|
||||
- libpkl-linux-amd64-snapshot
|
||||
- libpkl-linux-aarch64-snapshot
|
||||
- libpkl-macOS-aarch64-snapshot
|
||||
- libpkl-alpine-linux-amd64-snapshot
|
||||
- libpkl-windows-amd64-snapshot
|
||||
permissions:
|
||||
checks: write
|
||||
runs-on: ubuntu-latest
|
||||
@@ -880,6 +1196,11 @@ jobs:
|
||||
- pkl-doc-macOS-aarch64-snapshot
|
||||
- pkl-doc-alpine-linux-amd64-snapshot
|
||||
- pkl-doc-windows-amd64-snapshot
|
||||
- libpkl-linux-amd64-snapshot
|
||||
- libpkl-linux-aarch64-snapshot
|
||||
- libpkl-macOS-aarch64-snapshot
|
||||
- libpkl-alpine-linux-amd64-snapshot
|
||||
- libpkl-windows-amd64-snapshot
|
||||
- publish-test-results
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
Generated
+351
-20
@@ -239,10 +239,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-linux-amd64
|
||||
name: artifacts-pkl-cli-linux-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -290,10 +290,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-linux-aarch64
|
||||
name: artifacts-pkl-cli-linux-aarch64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -340,10 +340,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-macOS-aarch64
|
||||
name: artifacts-pkl-cli-macOS-aarch64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -458,10 +458,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.musl=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-alpine-linux-amd64
|
||||
name: artifacts-pkl-cli-alpine-linux-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -504,10 +504,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-cli-windows-amd64
|
||||
name: artifacts-pkl-cli-windows-amd64
|
||||
path: pkl-cli*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -553,10 +553,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-linux-amd64
|
||||
name: artifacts-pkl-doc-linux-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -604,10 +604,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-linux-aarch64
|
||||
name: artifacts-pkl-doc-linux-aarch64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -654,10 +654,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-macOS-aarch64
|
||||
name: artifacts-pkl-doc-macOS-aarch64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -772,10 +772,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.musl=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-alpine-linux-amd64
|
||||
name: artifacts-pkl-doc-alpine-linux-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -818,10 +818,10 @@ jobs:
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
|
||||
- name: Upload executable artifacts
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: executable-pkl-doc-windows-amd64
|
||||
name: artifacts-pkl-doc-windows-amd64
|
||||
path: pkl-doc*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
@@ -836,6 +836,322 @@ jobs:
|
||||
name: test-results-html-pkl-doc-windows-amd64-release
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-linux-amd64-release:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with:
|
||||
cache-disabled: true
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Fix git ownership
|
||||
run: git status || git config --system --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-linux-amd64
|
||||
path: libpkl/build/native-libs/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-linux-amd64-release
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-linux-amd64-release
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
container:
|
||||
image: redhat/ubi8:8.10
|
||||
libpkl-linux-aarch64-release:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: aarch64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with:
|
||||
cache-disabled: true
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Fix git ownership
|
||||
run: git status || git config --system --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-linux-aarch64
|
||||
path: libpkl/build/native-libs/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-linux-aarch64-release
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-linux-aarch64-release
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
container:
|
||||
image: redhat/ubi8:8.10
|
||||
libpkl-macOS-aarch64-release:
|
||||
if: github.repository_owner == 'apple'
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- macos
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: aarch64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with:
|
||||
cache-disabled: true
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-macOS-aarch64
|
||||
path: libpkl*/build/executable/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-macOS-aarch64-release
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-macOS-aarch64-release
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-alpine-linux-amd64-release:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with:
|
||||
cache-disabled: true
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Install musl and zlib
|
||||
run: |
|
||||
set -e
|
||||
mkdir -p ~/staticdeps/
|
||||
|
||||
ZLIB_VERSION="1.2.13"
|
||||
MUSL_VERSION="1.2.5"
|
||||
|
||||
# install zlib
|
||||
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
|
||||
# Download zlib tarball and signature
|
||||
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
|
||||
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
|
||||
|
||||
# Import zlib GPG key
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
|
||||
|
||||
# Verify GPG signature
|
||||
echo "Verifying zlib GPG signature..."
|
||||
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
|
||||
|
||||
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
|
||||
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
|
||||
# shellcheck disable=SC2002
|
||||
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: configure..."
|
||||
./configure --static --prefix="$HOME"/staticdeps > /dev/null
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: make..."
|
||||
make -s -j4
|
||||
|
||||
echo "zlib-${ZLIB_VERSION}: make install..."
|
||||
make -s install
|
||||
|
||||
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
|
||||
fi
|
||||
|
||||
# install musl
|
||||
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
|
||||
# Download musl tarball and signature
|
||||
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
|
||||
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
|
||||
|
||||
# Import musl GPG key
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
|
||||
|
||||
# Verify GPG signature
|
||||
echo "Verifying musl GPG signature..."
|
||||
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
|
||||
|
||||
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
cd "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
|
||||
# shellcheck disable=SC2002
|
||||
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
|
||||
|
||||
echo "musl-${MUSL_VERSION}: configure..."
|
||||
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
|
||||
|
||||
echo "musl-${MUSL_VERSION}: make..."
|
||||
make -s -j4
|
||||
|
||||
echo "musl-${MUSL_VERSION}: make install..."
|
||||
make -s install
|
||||
|
||||
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
|
||||
|
||||
# native-image expects to find an executable at this path.
|
||||
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
|
||||
fi
|
||||
|
||||
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.musl=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-alpine-linux-amd64
|
||||
path: libpkl*/build/distributions/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-alpine-linux-amd64-release
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-alpine-linux-amd64-release
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
libpkl-windows-amd64-release:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
JAVA_HOME: /jdk
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: temurin
|
||||
architecture: x64
|
||||
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
|
||||
with:
|
||||
cache-disabled: true
|
||||
- name: Set DEBUG_ARGS env var
|
||||
env:
|
||||
RUNNER_DEBUG: ${{ runner.debug }}
|
||||
shell: bash
|
||||
run: |-
|
||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Set up MSVC
|
||||
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1
|
||||
- name: gradle buildNative
|
||||
shell: bash
|
||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true libpkl:buildNative
|
||||
- name: Upload built artifacts
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: artifacts-libpkl-windows-amd64
|
||||
path: libpkl*/build/distributions/**/*
|
||||
- name: Upload Test Result XML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-xml-libpkl-windows-amd64-release
|
||||
path: '**/build/test-results/**/*.xml'
|
||||
- name: Upload Test Result HTML
|
||||
if: '!cancelled()'
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
||||
with:
|
||||
name: test-results-html-libpkl-windows-amd64-release
|
||||
path: '**/build/reports/tests/**/*'
|
||||
if-no-files-found: ignore
|
||||
deploy-release:
|
||||
needs:
|
||||
- gradle-check
|
||||
@@ -853,6 +1169,11 @@ jobs:
|
||||
- pkl-doc-macOS-aarch64-release
|
||||
- pkl-doc-alpine-linux-amd64-release
|
||||
- pkl-doc-windows-amd64-release
|
||||
- libpkl-linux-amd64-release
|
||||
- libpkl-linux-aarch64-release
|
||||
- libpkl-macOS-aarch64-release
|
||||
- libpkl-alpine-linux-amd64-release
|
||||
- libpkl-windows-amd64-release
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LANG: en_US.UTF-8
|
||||
@@ -934,6 +1255,11 @@ jobs:
|
||||
- pkl-doc-macOS-aarch64-release
|
||||
- pkl-doc-alpine-linux-amd64-release
|
||||
- pkl-doc-windows-amd64-release
|
||||
- libpkl-linux-amd64-release
|
||||
- libpkl-linux-aarch64-release
|
||||
- libpkl-macOS-aarch64-release
|
||||
- libpkl-alpine-linux-amd64-release
|
||||
- libpkl-windows-amd64-release
|
||||
permissions:
|
||||
checks: write
|
||||
runs-on: ubuntu-latest
|
||||
@@ -972,6 +1298,11 @@ jobs:
|
||||
- pkl-doc-macOS-aarch64-release
|
||||
- pkl-doc-alpine-linux-amd64-release
|
||||
- pkl-doc-windows-amd64-release
|
||||
- libpkl-linux-amd64-release
|
||||
- libpkl-linux-aarch64-release
|
||||
- libpkl-macOS-aarch64-release
|
||||
- libpkl-alpine-linux-amd64-release
|
||||
- libpkl-windows-amd64-release
|
||||
- deploy-release
|
||||
- github-release
|
||||
- publish-test-results
|
||||
|
||||
+3
@@ -96,6 +96,9 @@
|
||||
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="SameParameterValue" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="ShellCheck" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<shellcheck_settings value="SC2129" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||
<option name="processCode" value="true" />
|
||||
<option name="processLiterals" value="true" />
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||
|
||||
import Target.Arch
|
||||
import Target.OS
|
||||
import java.io.File
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.VersionCatalog
|
||||
import org.gradle.api.artifacts.VersionCatalogsExtension
|
||||
@@ -102,29 +105,31 @@ open class BuildInfo(private val project: Project) {
|
||||
val installDir: File by lazy { File(homeDir, baseName) }
|
||||
|
||||
val baseDir: String by lazy {
|
||||
if (os.isMacOsX) "$installDir/Contents/Home" else installDir.toString()
|
||||
if (os.isMacOS) "$installDir/Contents/Home" else installDir.toString()
|
||||
}
|
||||
}
|
||||
|
||||
/** The target machine to build, defaulting to the host system machine. */
|
||||
val targetMachine: Target by lazy { Target.from(os = os, arch = targetArch, musl = musl) }
|
||||
|
||||
/** The target architecture to build, defaulting to the system architecture. */
|
||||
val targetArch by lazy { System.getProperty("pkl.targetArch") ?: arch }
|
||||
val targetArch: Arch by lazy { System.getProperty("pkl.targetArch")?.let(Arch::fromName) ?: arch }
|
||||
|
||||
/** Tells if this is a cross-arch build (e.g. targeting amd64 when on an aarch64 machine). */
|
||||
val isCrossArch by lazy { arch != targetArch }
|
||||
|
||||
/** Tells if cross-arch builds are supported on this machine. */
|
||||
val isCrossArchSupported by lazy { os.isMacOsX }
|
||||
val isCrossArchSupported by lazy { os.isMacOS }
|
||||
|
||||
/** Whether to build native executables using the musl toolchain or not. */
|
||||
val musl: Boolean by lazy { java.lang.Boolean.getBoolean("pkl.musl") }
|
||||
|
||||
/** Same logic as [org.gradle.internal.os.OperatingSystem#arch], which is protected. */
|
||||
val arch: String by lazy {
|
||||
val arch: Arch by lazy {
|
||||
when (val arch = System.getProperty("os.arch")) {
|
||||
"x86" -> "i386"
|
||||
"x86_64" -> "amd64"
|
||||
"powerpc" -> "ppc"
|
||||
else -> arch
|
||||
"x86_64",
|
||||
"amd64" -> Arch.AMD64
|
||||
"aarch64" -> Arch.AARCH64
|
||||
else -> throw GradleException("Cannot build Pkl on arch: $arch")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,10 +140,10 @@ open class BuildInfo(private val project: Project) {
|
||||
private fun createGraalVm(arch: String): GraalVm {
|
||||
val osName =
|
||||
when {
|
||||
os.isMacOsX -> "macos"
|
||||
os.isMacOS -> "macos"
|
||||
os.isLinux -> "linux"
|
||||
os.isWindows -> "windows"
|
||||
else -> throw RuntimeException("Unsupported OS for GraalVM: ${os.canonicalName}")
|
||||
else -> throw RuntimeException("Unsupported OS for GraalVM: ${os.name}")
|
||||
}
|
||||
val version = libs.findVersion("graalVm").get().toString()
|
||||
val graalJdkVersion = libs.findVersion("graalVmJdkVersion").get().toString()
|
||||
@@ -378,7 +383,15 @@ open class BuildInfo(private val project: Project) {
|
||||
File(System.getProperty("user.home"), "staticdeps/bin/x86_64-linux-musl-gcc").exists()
|
||||
}
|
||||
|
||||
val os: OperatingSystem by lazy { OperatingSystem.current() }
|
||||
val os: OS by lazy {
|
||||
val currentOs = OperatingSystem.current()
|
||||
when {
|
||||
currentOs.isMacOsX -> OS.MacOS
|
||||
currentOs.isLinux -> OS.Linux
|
||||
currentOs.isWindows -> OS.Windows
|
||||
else -> throw GradleException("Cannot build on ${currentOs.name}")
|
||||
}
|
||||
}
|
||||
|
||||
// could be `commitId: Provider<String> = project.provider { ... }`
|
||||
val commitId: String by lazy {
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Target.OS
|
||||
import javax.inject.Inject
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.process.ExecOperations
|
||||
|
||||
/**
|
||||
* Task for creating static libraries from object files.
|
||||
*
|
||||
* Supports both Unix `ar` and Windows `lib.exe`.
|
||||
*/
|
||||
abstract class CArchive : DefaultTask() {
|
||||
/** The object files to archive. */
|
||||
@get:InputFiles abstract val objectFiles: ConfigurableFileCollection
|
||||
|
||||
/** The output static library file. */
|
||||
@get:OutputFile abstract val outputFile: RegularFileProperty
|
||||
|
||||
@get:Inject protected abstract val execOperations: ExecOperations
|
||||
|
||||
private val buildInfo: BuildInfo = project.extensions.getByType(BuildInfo::class.java)
|
||||
|
||||
init {
|
||||
group = "build"
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun archive() {
|
||||
outputFile.get().asFile.delete()
|
||||
when (buildInfo.os) {
|
||||
OS.Linux,
|
||||
OS.MacOS -> archiveWithAr()
|
||||
OS.Windows -> archiveWithLib()
|
||||
}
|
||||
logger.info("Created static library -> ${outputFile.get().asFile.name}")
|
||||
}
|
||||
|
||||
private fun archiveWithAr() {
|
||||
val output = outputFile.get().asFile
|
||||
output.parentFile.mkdirs()
|
||||
|
||||
val args = buildList {
|
||||
add("ar")
|
||||
add("-rcs")
|
||||
add(output.absolutePath)
|
||||
objectFiles.files.forEach { file -> add(file.absolutePath) }
|
||||
}
|
||||
|
||||
execOperations.exec {
|
||||
workingDir = project.projectDir
|
||||
commandLine(args)
|
||||
}
|
||||
}
|
||||
|
||||
private fun archiveWithLib() {
|
||||
val output = outputFile.get().asFile
|
||||
output.parentFile.mkdirs()
|
||||
|
||||
val args = buildList {
|
||||
add("lib.exe")
|
||||
add("/OUT:${output.absolutePath}")
|
||||
objectFiles.files.forEach { file -> add(file.absolutePath) }
|
||||
}
|
||||
|
||||
execOperations.exec {
|
||||
workingDir = project.projectDir
|
||||
commandLine(args)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Target.OS
|
||||
import javax.inject.Inject
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.MapProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.process.ExecOperations
|
||||
|
||||
/**
|
||||
* Task for compiling C source files to object files or executables. Supports both GCC/Clang and
|
||||
* MSVC compilers.
|
||||
*/
|
||||
abstract class CCompile : DefaultTask() {
|
||||
/** The C source files to compile. */
|
||||
@get:InputFiles abstract val sourceFiles: ConfigurableFileCollection
|
||||
|
||||
/** The include directories for compilation. */
|
||||
@get:InputFiles abstract val includeDirs: ConfigurableFileCollection
|
||||
|
||||
/** Preprocessor definitions. */
|
||||
@get:Input @get:Optional abstract val defines: MapProperty<String, String>
|
||||
|
||||
/** C standard version (e.g., "c11", "c17", "gnu11"). */
|
||||
@get:Input @get:Optional abstract val cStandard: Property<String>
|
||||
|
||||
/** Optimization level (e.g., "0", "1", "2", "3", "s", "fast"). */
|
||||
@get:Input @get:Optional abstract val optimizationLevel: Property<String>
|
||||
|
||||
/** Whether to include debug symbols. */
|
||||
@get:Input abstract val debugSymbols: Property<Boolean>
|
||||
|
||||
/** Whether to generate position-independent code (GCC/Clang only). */
|
||||
@get:Input abstract val positionIndependentCode: Property<Boolean>
|
||||
|
||||
/** Warning flags (GCC/Clang: prefixed with -W, e.g., "all", "extra"). */
|
||||
@get:Input abstract val warningFlags: ListProperty<String>
|
||||
|
||||
/** Warning level for MSVC (0-4). */
|
||||
@get:Input @get:Optional abstract val warningLevel: Property<Int>
|
||||
|
||||
/** Feature flags (GCC/Clang only, prefixed with -f). */
|
||||
@get:Input abstract val featureFlags: ListProperty<String>
|
||||
|
||||
/** Machine-specific flags (GCC/Clang only, prefixed with -m). */
|
||||
@get:Input abstract val machineFlags: ListProperty<String>
|
||||
|
||||
/** Runtime library for MSVC (e.g., "MT", "MD", "MTd", "MDd"). */
|
||||
@get:Input @get:Optional abstract val runtimeLibrary: Property<String>
|
||||
|
||||
/** Additional compiler arguments. */
|
||||
@get:Input abstract val compilerArgs: ListProperty<String>
|
||||
|
||||
/** The architecture to compile for (macOS only). */
|
||||
@get:Input @get:Optional abstract val arch: Property<Target.Arch>
|
||||
|
||||
// ===== Linking properties =====
|
||||
|
||||
/** Whether to link into an executable (true) or just compile to object files (false). */
|
||||
@get:Input abstract val link: Property<Boolean>
|
||||
|
||||
/** Library search paths. */
|
||||
@get:InputFiles @get:Optional abstract val libraryPaths: ConfigurableFileCollection
|
||||
|
||||
/** Libraries to link by name. */
|
||||
@get:Input @get:Optional abstract val libraries: ListProperty<String>
|
||||
|
||||
/** Direct library files to link. */
|
||||
@get:InputFiles @get:Optional abstract val libraryFiles: ConfigurableFileCollection
|
||||
|
||||
/** Linker flags. */
|
||||
@get:Input @get:Optional abstract val linkerFlags: ListProperty<String>
|
||||
|
||||
/** macOS frameworks to link (GCC/Clang only). */
|
||||
@get:Input @get:Optional abstract val frameworks: ListProperty<String>
|
||||
|
||||
/** Output file when linking (executable name). */
|
||||
@get:OutputFile @get:Optional abstract val outputFile: RegularFileProperty
|
||||
|
||||
/** Create a shared library (dll, dylib, so). */
|
||||
@get:Input abstract val sharedLibrary: Property<Boolean>
|
||||
|
||||
/** The output directory for object files (when not linking). */
|
||||
@get:OutputDirectory @get:Optional abstract val outputDir: DirectoryProperty
|
||||
|
||||
@get:Inject protected abstract val execOperations: ExecOperations
|
||||
|
||||
private val buildInfo: BuildInfo = project.extensions.getByType(BuildInfo::class.java)
|
||||
|
||||
init {
|
||||
group = "build"
|
||||
// Defaults
|
||||
link.convention(false)
|
||||
debugSymbols.convention(false)
|
||||
positionIndependentCode.convention(false)
|
||||
sharedLibrary.convention(false)
|
||||
warningFlags.convention(listOf("all", "extra"))
|
||||
warningLevel.convention(3)
|
||||
featureFlags.convention(emptyList())
|
||||
machineFlags.convention(emptyList())
|
||||
compilerArgs.convention(emptyList())
|
||||
defines.convention(emptyMap())
|
||||
libraries.convention(emptyList())
|
||||
linkerFlags.convention(emptyList())
|
||||
frameworks.convention(emptyList())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun compile() {
|
||||
if (link.get()) {
|
||||
compileAndLink()
|
||||
} else {
|
||||
compileOnly()
|
||||
}
|
||||
}
|
||||
|
||||
private fun compileOnly() {
|
||||
val outputDirectory = outputDir.get().asFile
|
||||
outputDirectory.mkdirs()
|
||||
|
||||
val cFiles = sourceFiles.files.filter { it.extension == "c" }
|
||||
|
||||
if (cFiles.isEmpty()) {
|
||||
logger.info("No C files to compile")
|
||||
return
|
||||
}
|
||||
|
||||
cFiles.forEach { cFile ->
|
||||
when (buildInfo.targetMachine.os) {
|
||||
OS.Linux,
|
||||
OS.MacOS -> compileFileGCC(cFile, outputDirectory)
|
||||
OS.Windows -> compileFileMSVC(cFile, outputDirectory)
|
||||
}
|
||||
}
|
||||
cFiles.forEach { cFile ->
|
||||
val objectFile = outputDirectory.resolve("${cFile.nameWithoutExtension}.o")
|
||||
logger.info("Compiled ${cFile.name} -> ${objectFile.name}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun compileFileGCC(cFile: java.io.File, outputDirectory: java.io.File) {
|
||||
val objectFile = outputDirectory.resolve("${cFile.nameWithoutExtension}.o")
|
||||
|
||||
val args = buildList {
|
||||
add("cc")
|
||||
add("-c")
|
||||
addAll(buildCompilerFlagsGCC())
|
||||
add(cFile.absolutePath)
|
||||
add("-o")
|
||||
add(objectFile.absolutePath)
|
||||
}
|
||||
|
||||
execOperations.exec {
|
||||
workingDir = project.projectDir
|
||||
commandLine(args)
|
||||
}
|
||||
}
|
||||
|
||||
private fun compileFileMSVC(cFile: java.io.File, outputDirectory: java.io.File) {
|
||||
val objectFile = outputDirectory.resolve("${cFile.nameWithoutExtension}.obj")
|
||||
|
||||
val args = buildList {
|
||||
add("cl.exe")
|
||||
add("/c")
|
||||
addAll(buildCompilerFlagsMSVC())
|
||||
add("/Fo${objectFile.absolutePath}")
|
||||
add(cFile.absolutePath)
|
||||
}
|
||||
|
||||
execOperations.exec {
|
||||
workingDir = project.projectDir
|
||||
commandLine(args)
|
||||
}
|
||||
}
|
||||
|
||||
private fun compileAndLink() {
|
||||
when (buildInfo.targetMachine.os) {
|
||||
OS.Linux,
|
||||
OS.MacOS -> compileAndLinkGCC()
|
||||
OS.Windows -> compileAndLinkMSVC()
|
||||
}
|
||||
|
||||
logger.info("Compiled and linked -> ${outputFile.get().asFile.name}")
|
||||
}
|
||||
|
||||
private fun compileAndLinkGCC() {
|
||||
val output = outputFile.get().asFile
|
||||
|
||||
val args = buildList {
|
||||
add("cc")
|
||||
addAll(buildCompilerFlagsGCC())
|
||||
|
||||
// Add source/object files
|
||||
sourceFiles.files.forEach { file -> add(file.absolutePath) }
|
||||
|
||||
// Library search paths
|
||||
libraryPaths.files.forEach { dir -> add("-L${dir.absolutePath}") }
|
||||
|
||||
// Direct library files. These must come before `-l` libraries below: GNU ld resolves
|
||||
// symbols in a single left-to-right pass, so a static `-lz` etc. must appear after the
|
||||
// archives (e.g. libpkl.a) whose undefined symbols it resolves, or those symbols are
|
||||
// never pulled in.
|
||||
libraryFiles.files.forEach { file -> add(file.absolutePath) }
|
||||
|
||||
// Libraries by name
|
||||
libraries.get().forEach { lib -> add("-l${lib}") }
|
||||
|
||||
// Linker flags
|
||||
if (linkerFlags.get().isNotEmpty()) {
|
||||
add("-Wl,${linkerFlags.get().joinToString(",")}")
|
||||
}
|
||||
|
||||
// macOS frameworks
|
||||
if (buildInfo.os.isMacOS) {
|
||||
frameworks.get().forEach { framework ->
|
||||
add("-framework")
|
||||
add(framework)
|
||||
}
|
||||
}
|
||||
|
||||
if (sharedLibrary.get()) {
|
||||
add("-shared")
|
||||
}
|
||||
|
||||
// Output file
|
||||
add("-o")
|
||||
add(output.absolutePath)
|
||||
}
|
||||
|
||||
output.parentFile.mkdirs()
|
||||
|
||||
execOperations.exec {
|
||||
workingDir = project.projectDir
|
||||
commandLine(args)
|
||||
}
|
||||
}
|
||||
|
||||
private fun compileAndLinkMSVC() {
|
||||
val output = outputFile.get().asFile
|
||||
output.parentFile.mkdirs()
|
||||
|
||||
val args = buildList {
|
||||
add("cl.exe")
|
||||
addAll(buildCompilerFlagsMSVC())
|
||||
|
||||
// Output executable
|
||||
add("/Fe${output.absolutePath}")
|
||||
|
||||
// Add source/object files
|
||||
sourceFiles.files.forEach { file -> add(file.absolutePath) }
|
||||
|
||||
// Linker section
|
||||
if (
|
||||
libraryPaths.files.isNotEmpty() ||
|
||||
libraries.get().isNotEmpty() ||
|
||||
libraryFiles.files.isNotEmpty() ||
|
||||
linkerFlags.get().isNotEmpty()
|
||||
) {
|
||||
add("/link")
|
||||
|
||||
if (sharedLibrary.get()) {
|
||||
add("/DLL")
|
||||
}
|
||||
|
||||
// Library search paths
|
||||
libraryPaths.files.forEach { dir -> add("/LIBPATH:${dir.absolutePath}") }
|
||||
|
||||
// Library files by name
|
||||
libraries.get().forEach { lib -> add("lib${lib}.lib") }
|
||||
|
||||
// Direct library files
|
||||
libraryFiles.files.forEach { file -> add(file.absolutePath) }
|
||||
|
||||
// Additional linker flags
|
||||
addAll(linkerFlags.get())
|
||||
}
|
||||
}
|
||||
|
||||
execOperations.exec {
|
||||
workingDir = project.projectDir
|
||||
commandLine(args)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildCompilerFlagsGCC(): List<String> = buildList {
|
||||
// Warning flags
|
||||
warningFlags.get().forEach { flag -> add("-W${flag}") }
|
||||
|
||||
// Include directories
|
||||
includeDirs.files.forEach { dir -> add("-I${dir.absolutePath}") }
|
||||
|
||||
// Preprocessor definitions
|
||||
defines.get().forEach { (key, value) ->
|
||||
if (value.isEmpty()) {
|
||||
add("-D${key}")
|
||||
} else {
|
||||
add("-D${key}=${value}")
|
||||
}
|
||||
}
|
||||
|
||||
// C standard
|
||||
if (cStandard.isPresent) {
|
||||
add("-std=${cStandard.get()}")
|
||||
}
|
||||
|
||||
// Optimization level
|
||||
if (optimizationLevel.isPresent) {
|
||||
add("-O${optimizationLevel.get()}")
|
||||
}
|
||||
|
||||
// Debug symbols
|
||||
if (debugSymbols.get()) {
|
||||
add("-g")
|
||||
}
|
||||
|
||||
// Position-independent code
|
||||
if (positionIndependentCode.get()) {
|
||||
add("-fPIC")
|
||||
}
|
||||
|
||||
// Feature flags
|
||||
featureFlags.get().forEach { flag -> add("-f${flag}") }
|
||||
|
||||
// Machine flags
|
||||
machineFlags.get().forEach { flag -> add("-m${flag}") }
|
||||
|
||||
// Platform-specific flags
|
||||
if (buildInfo.os.isMacOS && arch.isPresent) {
|
||||
add("-arch")
|
||||
add(arch.get().cCompilerName)
|
||||
}
|
||||
|
||||
// Additional compiler arguments
|
||||
addAll(compilerArgs.get())
|
||||
}
|
||||
|
||||
private fun buildCompilerFlagsMSVC(): List<String> = buildList {
|
||||
// Warning level
|
||||
if (warningLevel.isPresent) {
|
||||
add("/W${warningLevel.get()}")
|
||||
}
|
||||
|
||||
// Include directories
|
||||
includeDirs.files.forEach { dir -> add("/I${dir.absolutePath}") }
|
||||
|
||||
// Preprocessor definitions
|
||||
defines.get().forEach { (key, value) ->
|
||||
if (value.isEmpty()) {
|
||||
add("/D${key}")
|
||||
} else {
|
||||
add("/D${key}=${value}")
|
||||
}
|
||||
}
|
||||
|
||||
// C standard
|
||||
if (cStandard.isPresent) {
|
||||
add("/std:${cStandard.get()}")
|
||||
}
|
||||
|
||||
// Optimization level
|
||||
if (optimizationLevel.isPresent) {
|
||||
when (optimizationLevel.get().lowercase()) {
|
||||
"0",
|
||||
"d" -> add("/Od")
|
||||
"1" -> add("/O1")
|
||||
"2" -> add("/O2")
|
||||
"x",
|
||||
"fast" -> add("/Ox")
|
||||
"s" -> add("/Os")
|
||||
"t" -> add("/Ot")
|
||||
}
|
||||
}
|
||||
|
||||
// Debug symbols
|
||||
if (debugSymbols.get()) {
|
||||
add("/Zi")
|
||||
}
|
||||
|
||||
// Runtime library
|
||||
if (runtimeLibrary.isPresent) {
|
||||
add("/${runtimeLibrary.get()}")
|
||||
}
|
||||
|
||||
// Additional compiler arguments
|
||||
addAll(compilerArgs.get())
|
||||
}
|
||||
}
|
||||
@@ -16,49 +16,64 @@
|
||||
import javax.inject.Inject
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.MapProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.services.BuildService
|
||||
import org.gradle.api.services.BuildServiceParameters
|
||||
import org.gradle.api.tasks.ClasspathNormalizer
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputFiles
|
||||
import org.gradle.api.tasks.PathSensitivity
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.registerIfAbsent
|
||||
import org.gradle.kotlin.dsl.withNormalizer
|
||||
import org.gradle.process.ExecOperations
|
||||
|
||||
enum class Architecture {
|
||||
AMD64,
|
||||
AARCH64,
|
||||
}
|
||||
|
||||
abstract class NativeImageBuildService : BuildService<BuildServiceParameters.None>
|
||||
|
||||
abstract class NativeImageBuild : DefaultTask() {
|
||||
@get:Input abstract val imageName: Property<String>
|
||||
@get:Input abstract val outputName: Property<String>
|
||||
|
||||
@get:Input abstract val extraNativeImageArgs: ListProperty<String>
|
||||
|
||||
@get:Input abstract val arch: Property<Architecture>
|
||||
@get:Input abstract val arch: Property<Target.Arch>
|
||||
|
||||
@get:Input abstract val mainClass: Property<String>
|
||||
/**
|
||||
* The main class entrypoint for the executable.
|
||||
*
|
||||
* This option is not necessary if [sharedLibrary] is true.
|
||||
*/
|
||||
@get:Optional @get:Input abstract val mainClass: Property<String>
|
||||
|
||||
/** Create a shared library, instead of an executable. */
|
||||
@get:Input abstract val sharedLibrary: Property<Boolean>
|
||||
|
||||
@get:InputFiles abstract val classpath: ConfigurableFileCollection
|
||||
|
||||
private val outputDir = project.layout.buildDirectory.dir("executable")
|
||||
@get:Input abstract val envVars: MapProperty<String, String>
|
||||
|
||||
@get:OutputFile val outputFile = outputDir.flatMap { it.file(imageName) }
|
||||
@get:InputFile @get:Optional abstract val nativeCompilerPath: RegularFileProperty
|
||||
|
||||
@get:Internal abstract val outputDir: DirectoryProperty
|
||||
|
||||
@get:Inject protected abstract val execOperations: ExecOperations
|
||||
|
||||
@get:Inject protected abstract val objectFactory: ObjectFactory
|
||||
|
||||
private val graalVm: Provider<BuildInfo.GraalVm> = arch.map { a ->
|
||||
when (a) {
|
||||
Architecture.AMD64 -> buildInfo.graalVmAmd64
|
||||
Architecture.AARCH64 -> buildInfo.graalVmAarch64
|
||||
Target.Arch.AMD64 -> buildInfo.graalVmAmd64
|
||||
Target.Arch.AARCH64 -> buildInfo.graalVmAarch64
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +103,10 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
// CPU resources).
|
||||
usesService(buildService)
|
||||
|
||||
sharedLibrary.convention(false)
|
||||
|
||||
outputDir.convention(project.layout.buildDirectory.dir("executable"))
|
||||
|
||||
group = "build"
|
||||
|
||||
inputs
|
||||
@@ -98,6 +117,51 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
.files(nativeImageExecutable)
|
||||
.withPropertyName("graalVmNativeImage")
|
||||
.withPathSensitivity(PathSensitivity.ABSOLUTE)
|
||||
if (nativeCompilerPath.isPresent) {
|
||||
inputs.file(nativeCompilerPath)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
@OutputFiles
|
||||
fun getEffectiveOutputFiles(): FileCollection {
|
||||
return objectFactory
|
||||
.fileCollection()
|
||||
.from(
|
||||
sharedLibrary.map { isLibrary ->
|
||||
val dir = outputDir.get()
|
||||
val libraryName = outputName.get()
|
||||
// if building a library, native-image outputs the shared library plus four headers
|
||||
// (and, on Windows, an import library); otherwise, it outputs just the one file
|
||||
if (isLibrary) {
|
||||
val sharedLibraryExtension = buildInfo.os.sharedLibraryExtension
|
||||
val staticLibraryExtension = buildInfo.os.staticLibraryExtension
|
||||
dir.files(
|
||||
buildList {
|
||||
add("$libraryName.$sharedLibraryExtension")
|
||||
if (buildInfo.os.isWindows) {
|
||||
// the DLL's import library, which consumers must link against instead of
|
||||
// the .dll itself
|
||||
add("$libraryName.$staticLibraryExtension")
|
||||
// a genuine, self-contained static archive with no runtime DLL dependency,
|
||||
// produced by build_windows.bat
|
||||
add("${libraryName}_s.$staticLibraryExtension")
|
||||
} else {
|
||||
// a genuine, self-contained static archive with no runtime dependency,
|
||||
// produced by build_unix.sh
|
||||
add("$libraryName.$staticLibraryExtension")
|
||||
}
|
||||
add("$libraryName.h")
|
||||
add("${libraryName}_dynamic.h")
|
||||
add("graal_isolate.h")
|
||||
add("graal_isolate_dynamic.h")
|
||||
}
|
||||
)
|
||||
} else {
|
||||
dir.file(libraryName)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
@@ -111,6 +175,7 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
workingDir(outputDir)
|
||||
|
||||
args = buildList {
|
||||
add("--color=always")
|
||||
// must be emitted before any experimental options are used
|
||||
add("-H:+UnlockExperimentalVMOptions")
|
||||
// currently gives a deprecation warning, but we've been told
|
||||
@@ -126,9 +191,14 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
add("-H:IncludeResourceBundles=org.pkl.core.errorMessages")
|
||||
add("-H:IncludeResourceBundles=org.pkl.parser.errorMessages")
|
||||
add("-H:IncludeResources=org/pkl/commons/cli/PklCARoots.pem")
|
||||
add("-H:Class=${mainClass.get()}")
|
||||
if (mainClass.isPresent) {
|
||||
add("-H:Class=${mainClass.get()}")
|
||||
}
|
||||
if (sharedLibrary.get()) {
|
||||
add("--shared")
|
||||
}
|
||||
add("-o")
|
||||
add(imageName.get())
|
||||
add(outputName.get())
|
||||
// the actual limit (currently) used by native-image is this number + 1400 (idea is to
|
||||
// compensate for Truffle's own nodes)
|
||||
add("-H:MaxRuntimeCompileMethods=1800")
|
||||
@@ -138,10 +208,11 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
// disable automatic support for JVM CLI options (puts our main class in full control of
|
||||
// argument parsing)
|
||||
add("-H:-ParseRuntimeOptions")
|
||||
// quick build mode: 40% faster compilation, 20% smaller (but presumably also slower)
|
||||
// executable
|
||||
if (!buildInfo.isReleaseBuild) {
|
||||
add("-Ob")
|
||||
// disable all optimizations
|
||||
add("-O0")
|
||||
// generate debugging information
|
||||
add("-g")
|
||||
}
|
||||
if (buildInfo.isNativeArch) {
|
||||
add("-march=native")
|
||||
@@ -157,8 +228,12 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
// make sure dev machine stays responsive (15% slowdown on my laptop)
|
||||
val processors =
|
||||
Runtime.getRuntime().availableProcessors() /
|
||||
if (buildInfo.os.isMacOsX && !buildInfo.isCiBuild) 4 else 1
|
||||
if (buildInfo.os.isMacOS && !buildInfo.isCiBuild) 4 else 1
|
||||
add("-J-XX:ActiveProcessorCount=${processors}")
|
||||
addAll(envVars.get().entries.map { "-E${it.key}=${it.value}" })
|
||||
if (nativeCompilerPath.isPresent) {
|
||||
add("--native-compiler-path=${nativeCompilerPath.get().asFile}")
|
||||
}
|
||||
// Pass through all `HOMEBREW_` prefixed environment variables to allow build with shimmed
|
||||
// tools.
|
||||
addAll(environment.keys.filter { it.startsWith("HOMEBREW_") }.map { "-E$it" })
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||
|
||||
/**
|
||||
* A build target when building native libraries or executables.
|
||||
*
|
||||
* Pkl only builds for the following listed targets.
|
||||
*/
|
||||
enum class Target(val os: OS, val arch: Arch, val musl: Boolean) {
|
||||
MacosAarch64(os = OS.MacOS, arch = Arch.AARCH64, musl = false),
|
||||
LinuxAarch64(os = OS.Linux, arch = Arch.AARCH64, musl = false),
|
||||
LinuxAmd64(os = OS.Linux, arch = Arch.AMD64, musl = false),
|
||||
AlpineLinuxAmd64(os = OS.Linux, arch = Arch.AMD64, musl = true),
|
||||
WindowsAmd64(os = OS.Windows, arch = Arch.AMD64, musl = false);
|
||||
|
||||
companion object {
|
||||
fun from(os: OS, arch: Arch, musl: Boolean): Target {
|
||||
for (target in entries) {
|
||||
if (target.os == os && target.arch == arch && target.musl == musl) {
|
||||
return target
|
||||
}
|
||||
}
|
||||
throw IllegalArgumentException("Cannot build for $os-$arch with musl: $musl")
|
||||
}
|
||||
}
|
||||
|
||||
val targetName: String
|
||||
get() {
|
||||
return if (musl) {
|
||||
assert(os == OS.Linux)
|
||||
"alpine-linux-$arch"
|
||||
} else "$os-$arch"
|
||||
}
|
||||
|
||||
enum class Arch(
|
||||
/** What we call this arch */
|
||||
val simpleName: String,
|
||||
/** What the C compiler calls this arch */
|
||||
val cCompilerName: String,
|
||||
) {
|
||||
AARCH64("aarch64", "arm64"),
|
||||
AMD64("amd64", "x86_64");
|
||||
|
||||
override fun toString() = simpleName
|
||||
|
||||
companion object {
|
||||
fun fromName(name: String): Arch =
|
||||
when (name) {
|
||||
"aarch64" -> AARCH64
|
||||
"amd64" -> AMD64
|
||||
else -> throw IllegalArgumentException("Unknown arch: $name")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class OS(
|
||||
val simpleName: String,
|
||||
val sharedLibraryExtension: String,
|
||||
val staticLibraryExtension: String,
|
||||
val objectFileExtension: String,
|
||||
val displayName: String,
|
||||
) {
|
||||
MacOS(
|
||||
simpleName = "macos",
|
||||
sharedLibraryExtension = "dylib",
|
||||
staticLibraryExtension = "a",
|
||||
objectFileExtension = "o",
|
||||
displayName = "macOS",
|
||||
),
|
||||
Linux(
|
||||
simpleName = "linux",
|
||||
sharedLibraryExtension = "so",
|
||||
staticLibraryExtension = "a",
|
||||
objectFileExtension = "o",
|
||||
displayName = "Linux",
|
||||
),
|
||||
Windows(
|
||||
simpleName = "windows",
|
||||
sharedLibraryExtension = "dll",
|
||||
staticLibraryExtension = "lib",
|
||||
objectFileExtension = "obj",
|
||||
displayName = "Windows",
|
||||
);
|
||||
|
||||
override fun toString(): String = simpleName
|
||||
|
||||
val isWindows: Boolean
|
||||
get() = this == Windows
|
||||
|
||||
val isMacOS: Boolean
|
||||
get() = this == MacOS
|
||||
|
||||
val isLinux: Boolean
|
||||
get() = this == Linux
|
||||
}
|
||||
}
|
||||
@@ -53,33 +53,40 @@ val nativeImageClasspath =
|
||||
val libs = the<LibrariesForLibs>()
|
||||
|
||||
dependencies {
|
||||
fun executableFile(suffix: String) =
|
||||
fun executableFile(target: Target) =
|
||||
files(
|
||||
layout.buildDirectory.dir("executable").map { dir ->
|
||||
dir.file(executableSpec.name.map { "$it-$suffix" })
|
||||
dir.file(
|
||||
executableSpec.name.map { name ->
|
||||
if (target.os.isWindows) "$name-${target.targetName}.exe"
|
||||
else "$name-${target.targetName}"
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
nativeImageClasspath(libs.truffleRuntime)
|
||||
nativeImageClasspath(libs.graalSdk)
|
||||
|
||||
stagedMacAarch64Executable(executableFile("macos-aarch64"))
|
||||
stagedLinuxAmd64Executable(executableFile("linux-amd64"))
|
||||
stagedLinuxAarch64Executable(executableFile("linux-aarch64"))
|
||||
stagedAlpineLinuxAmd64Executable(executableFile("alpine-linux-amd64"))
|
||||
stagedWindowsAmd64Executable(executableFile("windows-amd64.exe"))
|
||||
stagedMacAarch64Executable(executableFile(Target.MacosAarch64))
|
||||
stagedLinuxAarch64Executable(executableFile(Target.LinuxAarch64))
|
||||
stagedLinuxAmd64Executable(executableFile(Target.LinuxAmd64))
|
||||
stagedAlpineLinuxAmd64Executable(executableFile(Target.AlpineLinuxAmd64))
|
||||
stagedWindowsAmd64Executable(executableFile(Target.WindowsAmd64))
|
||||
}
|
||||
|
||||
private fun NativeImageBuild.amd64() {
|
||||
arch = Architecture.AMD64
|
||||
dependsOn(":installGraalVmAmd64")
|
||||
}
|
||||
private fun NativeImageBuild.configure(target: Target) {
|
||||
arch = target.arch
|
||||
|
||||
private fun NativeImageBuild.aarch64() {
|
||||
arch = Architecture.AARCH64
|
||||
dependsOn(":installGraalVmAarch64")
|
||||
}
|
||||
outputName = executableSpec.name.map { "$it-${target.targetName}" }
|
||||
mainClass = executableSpec.mainClass
|
||||
|
||||
if (target.arch == Target.Arch.AARCH64) {
|
||||
dependsOn(":installGraalVmAarch64")
|
||||
} else {
|
||||
dependsOn(":installGraalVmAmd64")
|
||||
}
|
||||
|
||||
private fun NativeImageBuild.setClasspath() {
|
||||
classpath.from(sourceSets.main.map { it.output })
|
||||
classpath.from(
|
||||
project(":pkl-commons-cli").extensions.getByType(SourceSetContainer::class)["svm"].output
|
||||
@@ -88,27 +95,14 @@ private fun NativeImageBuild.setClasspath() {
|
||||
}
|
||||
|
||||
val macExecutableAarch64 =
|
||||
tasks.register<NativeImageBuild>("macExecutableAarch64") {
|
||||
imageName = executableSpec.name.map { "$it-macos-aarch64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
aarch64()
|
||||
setClasspath()
|
||||
}
|
||||
tasks.register<NativeImageBuild>("macExecutableAarch64") { configure(Target.MacosAarch64) }
|
||||
|
||||
val linuxExecutableAmd64 =
|
||||
tasks.register<NativeImageBuild>("linuxExecutableAmd64") {
|
||||
imageName = executableSpec.name.map { "$it-linux-amd64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
}
|
||||
tasks.register<NativeImageBuild>("linuxExecutableAmd64") { configure(Target.LinuxAmd64) }
|
||||
|
||||
val linuxExecutableAarch64 =
|
||||
tasks.register<NativeImageBuild>("linuxExecutableAarch64") {
|
||||
imageName = executableSpec.name.map { "$it-linux-aarch64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
aarch64()
|
||||
setClasspath()
|
||||
configure(Target.LinuxAarch64)
|
||||
// Ensure compatibility for kernels with page size set to 4k, 16k and 64k
|
||||
// (e.g. Raspberry Pi 5, Asahi Linux)
|
||||
extraNativeImageArgs.add("-H:PageSize=65536")
|
||||
@@ -116,19 +110,14 @@ val linuxExecutableAarch64 =
|
||||
|
||||
val alpineExecutableAmd64 =
|
||||
tasks.register<NativeImageBuild>("alpineExecutableAmd64") {
|
||||
imageName = executableSpec.name.map { "$it-alpine-linux-amd64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
extraNativeImageArgs.addAll(listOf("--static", "--libc=musl"))
|
||||
configure(Target.AlpineLinuxAmd64)
|
||||
extraNativeImageArgs.addAll("--static", "--libc=musl")
|
||||
}
|
||||
|
||||
val windowsExecutableAmd64 =
|
||||
tasks.register<NativeImageBuild>("windowsExecutableAmd64") {
|
||||
imageName = executableSpec.name.map { "$it-windows-amd64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
configure(Target.WindowsAmd64)
|
||||
extraNativeImageArgs.add("-Dfile.encoding=UTF-8")
|
||||
}
|
||||
|
||||
val assembleNative = tasks.named("assembleNative")
|
||||
@@ -216,93 +205,51 @@ val assembleNativeAlpineLinuxAmd64 =
|
||||
val assembleNativeWindowsAmd64 =
|
||||
tasks.named("assembleNativeWindowsAmd64") { wraps(windowsExecutableAmd64) }
|
||||
|
||||
private fun MavenPublication.configurePublication(target: Target, configuration: Configuration) {
|
||||
artifactId = "${executableSpec.publicationName.get()}-${target.targetName}"
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-${target.targetName}"
|
||||
url = executableSpec.website
|
||||
artifact(configuration.singleFile) {
|
||||
classifier = null
|
||||
extension = if (target.os.isWindows) "exe" else "bin"
|
||||
builtBy(configuration)
|
||||
}
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
buildString {
|
||||
append("Native $name executable for ${target.os.displayName}/${target.arch}")
|
||||
if (target.musl) {
|
||||
append(" and statically linked to musl")
|
||||
}
|
||||
append(".")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
// need to put in `afterEvaluate` because `artifactId` cannot be set lazily.
|
||||
project.afterEvaluate {
|
||||
create<MavenPublication>("macExecutableAarch64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-macos-aarch64"
|
||||
artifact(stagedMacAarch64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedMacAarch64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-macos-aarch64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for macOS/aarch64."
|
||||
}
|
||||
}
|
||||
configurePublication(Target.MacosAarch64, stagedMacAarch64Executable)
|
||||
}
|
||||
|
||||
create<MavenPublication>("linuxExecutableAmd64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-linux-amd64"
|
||||
artifact(stagedLinuxAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedLinuxAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-linux-amd64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for linux/amd64."
|
||||
}
|
||||
}
|
||||
configurePublication(Target.LinuxAmd64, stagedLinuxAmd64Executable)
|
||||
}
|
||||
|
||||
create<MavenPublication>("linuxExecutableAarch64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-linux-aarch64"
|
||||
artifact(stagedLinuxAarch64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedLinuxAarch64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-linux-aarch64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for linux/aarch64."
|
||||
}
|
||||
}
|
||||
configurePublication(Target.LinuxAarch64, stagedLinuxAarch64Executable)
|
||||
}
|
||||
|
||||
create<MavenPublication>("alpineLinuxExecutableAmd64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-alpine-linux-amd64"
|
||||
artifact(stagedAlpineLinuxAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedAlpineLinuxAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-alpine-linux-amd64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for linux/amd64 and statically linked to musl."
|
||||
}
|
||||
}
|
||||
configurePublication(Target.AlpineLinuxAmd64, stagedAlpineLinuxAmd64Executable)
|
||||
}
|
||||
|
||||
create<MavenPublication>("windowsExecutableAmd64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-windows-amd64"
|
||||
artifact(stagedWindowsAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "exe"
|
||||
builtBy(stagedWindowsAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-windows-amd64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for windows/amd64."
|
||||
}
|
||||
}
|
||||
configurePublication(Target.WindowsAmd64, stagedWindowsAmd64Executable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,31 +46,20 @@ val assembleNative =
|
||||
tasks.register("assembleNative") {
|
||||
group = "build"
|
||||
|
||||
@Suppress("DuplicatedCode")
|
||||
if (!buildInfo.isCrossArchSupported && buildInfo.isCrossArch) {
|
||||
throw GradleException("Cross-arch builds are not supported on ${buildInfo.os.name}")
|
||||
doLast {
|
||||
throw GradleException("Cross-arch builds are not supported on ${buildInfo.os.name}")
|
||||
}
|
||||
}
|
||||
|
||||
when {
|
||||
buildInfo.os.isMacOsX && buildInfo.targetArch == "aarch64" -> {
|
||||
wraps(assembleNativeMacOsAarch64)
|
||||
}
|
||||
buildInfo.os.isLinux && buildInfo.targetArch == "aarch64" -> {
|
||||
wraps(assembleNativeLinuxAarch64)
|
||||
}
|
||||
buildInfo.os.isLinux && buildInfo.targetArch == "amd64" -> {
|
||||
if (buildInfo.musl) wraps(assembleNativeAlpineLinuxAmd64)
|
||||
else wraps(assembleNativeLinuxAmd64)
|
||||
}
|
||||
buildInfo.os.isWindows && buildInfo.targetArch == "amd64" -> {
|
||||
wraps(assembleNativeWindowsAmd64)
|
||||
}
|
||||
else -> {
|
||||
doLast {
|
||||
throw GradleException(
|
||||
"Cannot build targeting ${buildInfo.os.name}/${buildInfo.targetArch} with musl=${buildInfo.musl}"
|
||||
)
|
||||
}
|
||||
}
|
||||
@Suppress("DuplicatedCode")
|
||||
when (buildInfo.targetMachine) {
|
||||
Target.MacosAarch64 -> wraps(assembleNativeMacOsAarch64)
|
||||
Target.LinuxAarch64 -> wraps(assembleNativeLinuxAarch64)
|
||||
Target.LinuxAmd64 -> wraps(assembleNativeLinuxAmd64)
|
||||
Target.AlpineLinuxAmd64 -> wraps(assembleNativeAlpineLinuxAmd64)
|
||||
Target.WindowsAmd64 -> wraps(assembleNativeWindowsAmd64)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,31 +68,18 @@ val testNative =
|
||||
group = "verification"
|
||||
dependsOn(assembleNative)
|
||||
|
||||
@Suppress("DuplicatedCode")
|
||||
if (!buildInfo.isCrossArchSupported && buildInfo.isCrossArch) {
|
||||
throw GradleException("Cross-arch builds are not supported on ${buildInfo.os.name}")
|
||||
}
|
||||
|
||||
when {
|
||||
buildInfo.os.isMacOsX && buildInfo.targetArch == "aarch64" -> {
|
||||
dependsOn(testNativeMacOsAarch64)
|
||||
}
|
||||
buildInfo.os.isLinux && buildInfo.targetArch == "aarch64" -> {
|
||||
dependsOn(testNativeLinuxAarch64)
|
||||
}
|
||||
buildInfo.os.isLinux && buildInfo.targetArch == "amd64" -> {
|
||||
if (buildInfo.musl) dependsOn(testNativeAlpineLinuxAmd64)
|
||||
else dependsOn(testNativeLinuxAmd64)
|
||||
}
|
||||
buildInfo.os.isWindows && buildInfo.targetArch == "amd64" -> {
|
||||
dependsOn(testNativeWindowsAmd64)
|
||||
}
|
||||
else -> {
|
||||
doLast {
|
||||
throw GradleException(
|
||||
"Cannot build targeting ${buildInfo.os.name}/${buildInfo.targetArch} with musl=${buildInfo.musl}"
|
||||
)
|
||||
}
|
||||
}
|
||||
@Suppress("DuplicatedCode")
|
||||
when (buildInfo.targetMachine) {
|
||||
Target.MacosAarch64 -> wraps(testNativeMacOsAarch64)
|
||||
Target.LinuxAarch64 -> wraps(testNativeLinuxAarch64)
|
||||
Target.LinuxAmd64 -> wraps(testNativeLinuxAmd64)
|
||||
Target.AlpineLinuxAmd64 -> wraps(testNativeAlpineLinuxAmd64)
|
||||
Target.WindowsAmd64 -> wraps(testNativeWindowsAmd64)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
::===----------------------------------------------------------------------===//
|
||||
:: Copyright © $YEAR Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
::
|
||||
:: Licensed under the Apache License, Version 2.0 (the "License");
|
||||
:: you may not use this file except in compliance with the License.
|
||||
:: You may obtain a copy of the License at
|
||||
::
|
||||
:: https://www.apache.org/licenses/LICENSE-2.0
|
||||
::
|
||||
:: Unless required by applicable law or agreed to in writing, software
|
||||
:: distributed under the License is distributed on an "AS IS" BASIS,
|
||||
:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
:: See the License for the specific language governing permissions and
|
||||
:: limitations under the License.
|
||||
::===----------------------------------------------------------------------===//
|
||||
@@ -0,0 +1,15 @@
|
||||
#===----------------------------------------------------------------------===//
|
||||
# Copyright © $YEAR Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#===----------------------------------------------------------------------===//
|
||||
@@ -5,6 +5,7 @@ checksumPlugin = "1.4.0"
|
||||
clikt = "5.0.3"
|
||||
commonMark = "0.29.0"
|
||||
downloadTaskPlugin = "5.7.0"
|
||||
eclipseCdtFormat = "12.2"
|
||||
errorProne = "2.50.0"
|
||||
errorPronePlugin = "5.1.0"
|
||||
geantyref = "2.0.1"
|
||||
@@ -30,10 +31,12 @@ graalVmSha256-windows-aarch64 = "unavailable"
|
||||
ideaExtPlugin = "1.4.1"
|
||||
javaPoet = "0.17.0"
|
||||
javaxInject = "1"
|
||||
jextractPlugin = "1.+"
|
||||
jimfs = "1.3.1"
|
||||
jline = "4.3.1"
|
||||
jmh = "1.37"
|
||||
jmhPlugin = "0.7.3"
|
||||
jna = "5.19.1"
|
||||
jspecify = "1.0.0"
|
||||
junit = "6.1.1"
|
||||
# 1.7+ generates much more verbose code
|
||||
@@ -84,6 +87,8 @@ jimfs = { group = "com.google.jimfs", name = "jimfs", version.ref = "jimfs" }
|
||||
jlineReader = { group = "org.jline", name = "jline-reader", version.ref = "jline" }
|
||||
jlineTerminal = { group = "org.jline", name = "jline-terminal", version.ref = "jline" }
|
||||
jlineTerminalJni = { group = "org.jline", name = "jline-terminal-jni", version.ref = "jline" }
|
||||
jna = { group = "net.java.dev.jna", name = "jna", version.ref = "jna" }
|
||||
jnaPlatform = { group = "net.java.dev.jna", name = "jna-platform", version.ref = "jna" }
|
||||
#noinspection UnusedVersionCatalogEntry
|
||||
jspecify = { group = "org.jspecify", name = "jspecify", version.ref = "jspecify" }
|
||||
junitApi = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit" }
|
||||
@@ -134,3 +139,4 @@ nexusPublish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "ne
|
||||
#noinspection UnusedVersionCatalogEntry
|
||||
nullaway = { id = "net.ltgt.nullaway", version.ref = "nullawayPlugin" }
|
||||
shadow = { id = "com.gradleup.shadow", version.ref = "shadowPlugin" }
|
||||
jextract = { id = "de.infolektuell.jextract", version.ref = "jextractPlugin" }
|
||||
|
||||
@@ -0,0 +1,523 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
import org.gradle.kotlin.dsl.filter
|
||||
|
||||
plugins {
|
||||
id("pklAllProjects")
|
||||
id("pklGraalVm")
|
||||
id("pklJavaLibrary")
|
||||
id("pklNativeLifecycle")
|
||||
}
|
||||
|
||||
val stagedMacAarch64NativeLibrary: Configuration =
|
||||
configurations.create("stagedMacAarch64NativeLibrary")
|
||||
val stagedLinuxAmd64NativeLibrary: Configuration =
|
||||
configurations.create("stagedLinuxAmd64NativeLibrary")
|
||||
val stagedLinuxAarch64NativeLibrary: Configuration =
|
||||
configurations.create("stagedLinuxAarch64NativeLibrary")
|
||||
val stagedAlpineLinuxAmd64NativeLibrary: Configuration =
|
||||
configurations.create("stagedAlpineLinuxAmd64NativeLibrary")
|
||||
val stagedWindowsAmd64NativeLibrary: Configuration =
|
||||
configurations.create("stagedWindowsAmd64NativeLibrary")
|
||||
|
||||
val nativeTestSourceSet: SourceSet = sourceSets.create("nativeTest")
|
||||
|
||||
val nativeTestImplementation: Configuration =
|
||||
configurations.getByName("nativeTestImplementation") {
|
||||
extendsFrom(configurations.testImplementation.get())
|
||||
}
|
||||
|
||||
val nativeTestRuntimeOnly: Configuration =
|
||||
configurations.getByName("nativeTestRuntimeOnly") {
|
||||
extendsFrom(configurations.testRuntimeOnly.get())
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.graalSdk)
|
||||
|
||||
implementation(projects.pklCore)
|
||||
implementation(projects.pklServer)
|
||||
|
||||
implementation(libs.msgpack)
|
||||
implementation(libs.truffleApi)
|
||||
implementation(libs.truffleRuntime)
|
||||
|
||||
nativeTestImplementation(projects.pklCommonsTest)
|
||||
nativeTestImplementation(libs.jna)
|
||||
nativeTestImplementation(libs.jnaPlatform)
|
||||
nativeTestRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
}
|
||||
|
||||
tasks.withType(CCompile::class) {
|
||||
if (buildInfo.targetMachine.os.isMacOS) {
|
||||
arch = buildInfo.targetMachine.arch
|
||||
}
|
||||
}
|
||||
|
||||
private fun NativeImageBuild.configure(target: Target) {
|
||||
arch = target.arch
|
||||
|
||||
if (target.arch == Target.Arch.AARCH64) {
|
||||
dependsOn(":installGraalVmAarch64")
|
||||
} else {
|
||||
dependsOn(":installGraalVmAmd64")
|
||||
}
|
||||
|
||||
outputDir = target.tempOutputDir
|
||||
outputName = "libpkl_internal"
|
||||
|
||||
classpath.from(sourceSets.main.map { it.output })
|
||||
classpath.from(
|
||||
project(":pkl-commons-cli").extensions.getByType(SourceSetContainer::class)["svm"].output
|
||||
)
|
||||
classpath.from(configurations.runtimeClasspath)
|
||||
|
||||
sharedLibrary = true
|
||||
val scriptName = if (buildInfo.os.isWindows) "build_windows.bat" else "build_unix.sh"
|
||||
nativeCompilerPath = projectDir.resolve("scripts/${scriptName}")
|
||||
}
|
||||
|
||||
val macNativeImageAarch64 =
|
||||
tasks.register<NativeImageBuild>("macNativeImageAarch64") {
|
||||
configure(Target.MacosAarch64)
|
||||
// macOS only supports 16K page size
|
||||
extraNativeImageArgs =
|
||||
listOf(
|
||||
"-H:PageSize=16384",
|
||||
// increase memory available to native-image
|
||||
"-J-Xmx32g",
|
||||
)
|
||||
}
|
||||
|
||||
val linuxNativeImageAmd64 =
|
||||
tasks.register<NativeImageBuild>("linuxNativeImageAmd64") { configure(Target.LinuxAmd64) }
|
||||
|
||||
val linuxNativeImageAarch64 =
|
||||
tasks.register<NativeImageBuild>("linuxNativeImageAarch64") {
|
||||
configure(Target.LinuxAarch64)
|
||||
extraNativeImageArgs =
|
||||
listOf(
|
||||
// Ensure compatibility for kernels with page size set to 4k, 16k and 64k
|
||||
// (e.g. Raspberry Pi 5, Asahi Linux)
|
||||
"-H:PageSize=65536"
|
||||
)
|
||||
}
|
||||
|
||||
val alpineLinuxNativeImageAmd64 =
|
||||
tasks.register<NativeImageBuild>("alpineLinuxNativeImageAmd64") {
|
||||
configure(Target.AlpineLinuxAmd64)
|
||||
extraNativeImageArgs.addAll("--libc=musl")
|
||||
}
|
||||
|
||||
val windowsNativeImageAmd64 =
|
||||
tasks.register<NativeImageBuild>("windowsNativeImageAmd64") {
|
||||
configure(Target.WindowsAmd64)
|
||||
extraNativeImageArgs.addAll("-Dfile.encoding=UTF-8", "-H:-CheckToolchain")
|
||||
}
|
||||
|
||||
val buildNativeImageLibrary =
|
||||
tasks.register("buildNativeImageLibrary") {
|
||||
group = "build"
|
||||
val underlyingTask =
|
||||
when (buildInfo.targetMachine) {
|
||||
Target.MacosAarch64 -> macNativeImageAarch64
|
||||
Target.LinuxAarch64 -> linuxNativeImageAarch64
|
||||
Target.LinuxAmd64 -> linuxNativeImageAmd64
|
||||
Target.WindowsAmd64 -> windowsNativeImageAmd64
|
||||
Target.AlpineLinuxAmd64 -> alpineLinuxNativeImageAmd64
|
||||
}
|
||||
dependsOn(underlyingTask)
|
||||
outputs.files(underlyingTask)
|
||||
}
|
||||
|
||||
val buildPklObjectFile =
|
||||
tasks.register<CCompile>("buildPklObjectFile") {
|
||||
dependsOn(buildNativeImageLibrary)
|
||||
includeDirs.from(buildInfo.targetMachine.tempOutputDir)
|
||||
includeDirs.from(file("src/main/c/include/"))
|
||||
sourceFiles.from(file("src/main/c/pkl.c"))
|
||||
positionIndependentCode = true
|
||||
if (buildInfo.os.isWindows) {
|
||||
// Match the dynamic CRT (ucrt/msvcrt) that native-image's bundled JDK objects expect -
|
||||
// otherwise linking pkl.obj together with the merged libpkl_internal_s.lib archive hits a
|
||||
// LIBCMT/MSVCRT default-lib conflict and unresolved __imp_* CRT import symbols.
|
||||
runtimeLibrary = "MD"
|
||||
}
|
||||
|
||||
outputDir =
|
||||
layout.buildDirectory.dir("tmp/compileC/${name}/${buildInfo.targetMachine.targetName}")
|
||||
|
||||
val versionMacro =
|
||||
if (buildInfo.targetMachine.os.isWindows) "\\\"${buildInfo.pklVersion}\\\""
|
||||
else "\"${buildInfo.pklVersion}\""
|
||||
defines.put("PKL_VERSION", versionMacro)
|
||||
}
|
||||
|
||||
val buildStaticLibrary =
|
||||
tasks.register<CArchive>("buildStaticLibrary") {
|
||||
dependsOn(buildNativeImageLibrary, buildPklObjectFile)
|
||||
|
||||
val targetMachine = buildInfo.targetMachine
|
||||
val objectExtension = targetMachine.os.objectFileExtension
|
||||
val pklObjectFile = buildPklObjectFile.flatMap {
|
||||
it.outputDir.map { dir -> dir.file("pkl.${objectExtension}") }
|
||||
}
|
||||
|
||||
if (targetMachine.os.isWindows) {
|
||||
// build_windows.bat produces a single self-contained merged archive
|
||||
// (libpkl_internal_s.lib) directly, rather than extracting loose .obj members into an
|
||||
// "objects" directory the way build_unix.sh does - pull that in instead.
|
||||
objectFiles.from(
|
||||
buildNativeImageLibrary.map { task ->
|
||||
task.outputs.files.find {
|
||||
it.name == "libpkl_internal_s.${targetMachine.os.staticLibraryExtension}"
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
objectFiles.from(
|
||||
fileTree(targetMachine.tempOutputDir.get().dir("objects")).matching {
|
||||
include("**/*.${objectExtension}")
|
||||
}
|
||||
)
|
||||
}
|
||||
objectFiles.from(pklObjectFile)
|
||||
|
||||
outputFile =
|
||||
targetMachine.outputDir.map { dir ->
|
||||
dir.file("lib/libpkl.${targetMachine.os.staticLibraryExtension}")
|
||||
}
|
||||
}
|
||||
|
||||
val buildSharedLibrary =
|
||||
tasks.register<CCompile>("buildSharedLibrary") {
|
||||
dependsOn(buildNativeImageLibrary, buildPklObjectFile)
|
||||
|
||||
link = true
|
||||
val targetMachine = buildInfo.targetMachine
|
||||
|
||||
val libraryFile = buildPklObjectFile.flatMap { task ->
|
||||
task.outputDir.map { dir -> dir.file("pkl.${targetMachine.os.objectFileExtension}") }
|
||||
}
|
||||
|
||||
val extension = targetMachine.os.sharedLibraryExtension
|
||||
val staticLib = buildNativeImageLibrary.map { task ->
|
||||
// link against the self-contained static archive (produced by build_unix.sh /
|
||||
// build_windows.bat) rather than the shared library, so libpkl doesn't carry a runtime
|
||||
// dependency on a separate libpkl_internal shared library.
|
||||
val fileName =
|
||||
if (targetMachine.os.isWindows)
|
||||
"libpkl_internal_s.${targetMachine.os.staticLibraryExtension}"
|
||||
else "libpkl_internal.${targetMachine.os.staticLibraryExtension}"
|
||||
task.outputs.files.find { it.name == fileName }
|
||||
}
|
||||
|
||||
sourceFiles.from(libraryFile)
|
||||
includeDirs.from(file("src/main/c/"))
|
||||
libraryFiles.from(staticLib)
|
||||
positionIndependentCode = true
|
||||
sharedLibrary = true
|
||||
|
||||
outputFile = targetMachine.outputDir.map { it.file("lib/libpkl.${extension}") }
|
||||
|
||||
if (buildInfo.os.isMacOS) {
|
||||
frameworks.addAll("Foundation", "CoreServices")
|
||||
linkerFlags.addAll("-current_version", project.version.toString())
|
||||
linkerFlags.addAll("-compatibility_version", "0.1.0")
|
||||
|
||||
// libpkl_internal_s bundles Native Image's own JNI-named implementations of JDK native
|
||||
// methods (e.g. Java_sun_nio_ch_UnixFileDispatcherImpl_write0), which by default get
|
||||
// exported with global visibility. Loading libpkl.dylib into a JVM process (e.g. via JNA)
|
||||
// then lets the host JVM's own native-method resolution bind to these internal
|
||||
// implementations instead of the JDK's real ones, silently corrupting unrelated file I/O.
|
||||
// Restrict the dylib's exported symbols to just the public pkl_* API to prevent this.
|
||||
val exportedSymbolsFile = file("src/main/c/pkl.exported_symbols")
|
||||
inputs.file(exportedSymbolsFile)
|
||||
linkerFlags.addAll("-exported_symbols_list", exportedSymbolsFile.absolutePath)
|
||||
}
|
||||
|
||||
if (targetMachine.os.isWindows) {
|
||||
// Without an explicit /IMPLIB, MSVC would name the DLL's import library "libpkl.lib" —
|
||||
// the same path buildStaticLibrary writes its static archive to.
|
||||
linkerFlags.add(
|
||||
targetMachine.libraryDir.map { dir -> "/IMPLIB:${dir.file("libpkl_dll.lib").asFile}" }
|
||||
)
|
||||
} else {
|
||||
libraries.add("z")
|
||||
libraries.add("pthread")
|
||||
}
|
||||
|
||||
if (targetMachine.os.isLinux) {
|
||||
libraries.add("dl")
|
||||
|
||||
// Same symbol-collision hazard as the macOS case above (see comment there), but scoped via
|
||||
// a GNU ld version script instead of an exported-symbols list.
|
||||
val versionScriptFile = file("src/main/c/pkl.map")
|
||||
inputs.file(versionScriptFile)
|
||||
linkerFlags.add("--version-script=${versionScriptFile.absolutePath}")
|
||||
}
|
||||
}
|
||||
|
||||
val Target.outputDir
|
||||
get() = layout.buildDirectory.dir("native-libs/$targetName")
|
||||
|
||||
val Target.libraryDir
|
||||
get() = layout.buildDirectory.dir("native-libs/$targetName/lib")
|
||||
|
||||
val Target.tempOutputDir
|
||||
get() = layout.buildDirectory.dir("tmp/native-libs/$targetName")
|
||||
|
||||
val distTar =
|
||||
tasks.register<Tar>("distTar") {
|
||||
val isUnix = buildInfo.os.isMacOS || buildInfo.os.isLinux
|
||||
onlyIf { isUnix }
|
||||
dependsOn(buildSharedLibrary, buildStaticLibrary, processFiles)
|
||||
compression = Compression.GZIP
|
||||
val baseName = "libpkl-${buildInfo.pklVersionNonUnique}-${buildInfo.targetMachine.targetName}"
|
||||
archiveFileName = "${baseName}.tar.gz"
|
||||
from(buildInfo.targetMachine.outputDir)
|
||||
into(baseName)
|
||||
}
|
||||
|
||||
val distZip =
|
||||
tasks.register<Zip>("distZip") {
|
||||
val isWindows = buildInfo.os.isWindows
|
||||
onlyIf { isWindows }
|
||||
dependsOn(buildSharedLibrary, buildStaticLibrary, processFiles)
|
||||
val baseName = "libpkl-${buildInfo.pklVersionNonUnique}-${buildInfo.targetMachine.targetName}"
|
||||
archiveFileName = "${baseName}.zip"
|
||||
from(buildInfo.targetMachine.outputDir)
|
||||
into(baseName)
|
||||
}
|
||||
|
||||
tasks.assembleNative { dependsOn(distZip, distTar) }
|
||||
|
||||
val processFiles =
|
||||
tasks.register<Copy>("processFiles") {
|
||||
inputs.property("version", buildInfo.pklVersion)
|
||||
inputs.dir("src/main/c")
|
||||
inputs.dir("src/main/files")
|
||||
from(fileTree("src/main/files"))
|
||||
from(fileTree("src/main/c") { exclude("*.{c,map,exported_symbols}") })
|
||||
includeEmptyDirs = true
|
||||
into(buildInfo.targetMachine.outputDir)
|
||||
|
||||
filesMatching("libpkl.pc") {
|
||||
filter<ReplaceTokens>("tokens" to mapOf("version" to buildInfo.pklVersion))
|
||||
}
|
||||
}
|
||||
|
||||
val testNativeJava =
|
||||
tasks.register<Test>("testNativeJava") {
|
||||
dependsOn(tasks.assembleNative)
|
||||
|
||||
description = "Test native libraries from Java"
|
||||
group = "verification"
|
||||
|
||||
testClassesDirs = nativeTestSourceSet.output.classesDirs
|
||||
classpath = nativeTestSourceSet.runtimeClasspath
|
||||
|
||||
// It's not good enough to just provide `jna.library.path` on Linux; need to also provide
|
||||
// `LD_LIBRARY_PATH` or `java.library.path` so that transitive libraries can be loaded.
|
||||
jvmArgumentProviders.add(
|
||||
CommandLineArgumentProvider {
|
||||
listOf(
|
||||
"-Djna.library.path=" + buildInfo.targetMachine.libraryDir.get().asFile.absolutePath,
|
||||
"-Djava.library.path=" + buildInfo.targetMachine.libraryDir.get().asFile.absolutePath,
|
||||
"--enable-native-access=ALL-UNNAMED",
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
environment("LD_LIBRARY_PATH", buildInfo.targetMachine.libraryDir.get().asFile.absolutePath)
|
||||
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
// link to static library
|
||||
val compileNativeTestStatic =
|
||||
tasks.register<CCompile>("compileNativeTestStatic") {
|
||||
description = "Build C test with static library"
|
||||
group = "verification"
|
||||
|
||||
dependsOn(tasks.assembleNative)
|
||||
|
||||
val libDir = buildInfo.targetMachine.libraryDir.get().asFile
|
||||
val testSrc = file("src/nativeTest/c/test_pkl.c")
|
||||
|
||||
link = true
|
||||
sourceFiles.from(testSrc)
|
||||
includeDirs.from(buildInfo.targetMachine.outputDir.map { it.file("include") })
|
||||
// Match the dynamic CRT (ucrt/msvcrt) that libpkl.lib's bundled JDK objects expect -
|
||||
// otherwise this defaults to the static CRT (LIBCMT), causing a defaultlib conflict and
|
||||
// unresolved __imp_* CRT import symbols, same as buildPklObjectFile.
|
||||
if (buildInfo.os.isWindows) {
|
||||
runtimeLibrary = "MD"
|
||||
}
|
||||
outputFile =
|
||||
layout.buildDirectory.file(
|
||||
"native-test/${buildInfo.targetMachine.targetName}/test_pkl_static"
|
||||
)
|
||||
|
||||
libraryFiles.from("${libDir.absolutePath}/libpkl.${buildInfo.os.staticLibraryExtension}")
|
||||
|
||||
if (!buildInfo.os.isWindows) {
|
||||
libraries.add("pthread")
|
||||
libraries.add("z")
|
||||
}
|
||||
|
||||
if (buildInfo.os.isLinux) {
|
||||
libraries.add("dl")
|
||||
}
|
||||
|
||||
if (buildInfo.os.isMacOS) {
|
||||
frameworks.addAll("Foundation", "CoreServices")
|
||||
}
|
||||
}
|
||||
|
||||
// link to dynamic library
|
||||
val compileNativeTestDynamic =
|
||||
tasks.register<CCompile>("compileNativeTestDynamic") {
|
||||
description = "Build C test with dynamic library"
|
||||
group = "verification"
|
||||
|
||||
dependsOn(tasks.assembleNative)
|
||||
|
||||
val testSrc = file("src/nativeTest/c/test_pkl.c")
|
||||
|
||||
link = true
|
||||
sourceFiles.from(testSrc)
|
||||
includeDirs.from(buildInfo.targetMachine.outputDir.map { it.file("include") })
|
||||
outputFile =
|
||||
layout.buildDirectory.file(
|
||||
"native-test/${buildInfo.targetMachine.targetName}/test_pkl_dynamic"
|
||||
)
|
||||
|
||||
libraryPaths.from(buildInfo.targetMachine.libraryDir)
|
||||
|
||||
if (buildInfo.os.isWindows) {
|
||||
// "pkl" would resolve to libpkl.lib, which is buildStaticLibrary's static archive, not
|
||||
// the DLL's import library — link against the import library directly instead.
|
||||
libraryFiles.from(buildInfo.targetMachine.libraryDir.map { it.file("libpkl_dll.lib") })
|
||||
} else {
|
||||
libraries.add("pkl")
|
||||
libraries.add("z")
|
||||
libraries.add("pthread")
|
||||
// Bake the library's location into the test executable so the dynamic loader can find
|
||||
// libpkl.so/libpkl.dylib without needing LD_LIBRARY_PATH/DYLD_LIBRARY_PATH set at run time.
|
||||
linkerFlags.add("-rpath")
|
||||
linkerFlags.add(buildInfo.targetMachine.libraryDir.get().asFile.absolutePath)
|
||||
}
|
||||
|
||||
if (buildInfo.os.isLinux) {
|
||||
libraries.add("dl")
|
||||
}
|
||||
}
|
||||
|
||||
val buildNativeTestC =
|
||||
tasks.register("buildNativeTestC") {
|
||||
description = "Build both static and dynamic C tests"
|
||||
group = "verification"
|
||||
|
||||
dependsOn(compileNativeTestStatic, compileNativeTestDynamic)
|
||||
}
|
||||
|
||||
fun Task.configureDummyOutput() {
|
||||
group = "verification"
|
||||
|
||||
// dummy output to satisfy up-to-date check
|
||||
val outputFile = layout.buildDirectory.file(name)
|
||||
outputs.file(outputFile)
|
||||
|
||||
doFirst { outputFile.get().asFile.delete() }
|
||||
doLast { outputFile.get().asFile.writeText("OK") }
|
||||
}
|
||||
|
||||
val testNativeCStatic =
|
||||
tasks.register<Exec>("testNativeCStatic") {
|
||||
configureDummyOutput()
|
||||
group = "verification"
|
||||
dependsOn(compileNativeTestStatic)
|
||||
|
||||
val testDir = layout.buildDirectory.dir("native-test").get().asFile
|
||||
|
||||
workingDir = projectDir
|
||||
commandLine(compileNativeTestStatic.get().outputFile.get().asFile.absolutePath)
|
||||
}
|
||||
|
||||
val testNativeCDynamic =
|
||||
tasks.register<Exec>("testNativeCDynamic") {
|
||||
configureDummyOutput()
|
||||
group = "verification"
|
||||
|
||||
dependsOn(compileNativeTestDynamic)
|
||||
|
||||
val testDir = layout.buildDirectory.dir("native-test").get().asFile
|
||||
|
||||
workingDir = projectDir
|
||||
commandLine(compileNativeTestDynamic.get().outputFile.get().asFile.absolutePath)
|
||||
|
||||
if (buildInfo.os.isWindows) {
|
||||
// Windows has no rpath equivalent — the DLL loader only searches the exe's own
|
||||
// directory and PATH, so libpkl.dll must be made findable via PATH.
|
||||
doFirst {
|
||||
environment(
|
||||
"PATH",
|
||||
"${buildInfo.targetMachine.libraryDir.get().asFile.absolutePath};${System.getenv("PATH")}",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.testNative {
|
||||
dependsOn(testNativeCStatic, testNativeCDynamic)
|
||||
|
||||
// can't run libraries from other arch in Java
|
||||
if (!buildInfo.isCrossArch) {
|
||||
dependsOn(testNativeJava)
|
||||
}
|
||||
}
|
||||
|
||||
spotless {
|
||||
cpp {
|
||||
licenseHeaderFile(
|
||||
rootProject.file("build-logic/src/main/resources/license-header.star-block.txt"),
|
||||
"// ",
|
||||
)
|
||||
target("src/*/c/*.c", "src/*/c/*.h")
|
||||
eclipseCdt(libs.versions.eclipseCdtFormat.get())
|
||||
}
|
||||
shell {
|
||||
licenseHeaderFile(
|
||||
rootProject.file("build-logic/src/main/resources/license-header.hash-comment.txt"),
|
||||
"## build_",
|
||||
)
|
||||
// skip shebang
|
||||
.skipLinesMatching("^#!.+?$")
|
||||
|
||||
target("scripts/*.sh")
|
||||
}
|
||||
format("bat") {
|
||||
target("scripts/*.bat")
|
||||
licenseHeaderFile(
|
||||
rootProject.file("build-logic/src/main/resources/license-header.batch-script.txt"),
|
||||
"@echo",
|
||||
)
|
||||
}
|
||||
}
|
||||
Executable
+116
@@ -0,0 +1,116 @@
|
||||
#!/bin/bash
|
||||
#===----------------------------------------------------------------------===//
|
||||
# Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#===----------------------------------------------------------------------===//
|
||||
## build_unix.sh
|
||||
# Adapted from https://github.com/oracle/graal/issues/3053#issuecomment-1866735057
|
||||
# This script intercepts compiler arguments from graalvm native shared images
|
||||
# and additionally generates a static library.
|
||||
#
|
||||
# Use with --native-compiler-path=${pathToThisScript}
|
||||
|
||||
set -e
|
||||
|
||||
# Detect OS
|
||||
OS=$(uname -s)
|
||||
case "$OS" in
|
||||
Darwin)
|
||||
SHARED_LIB_EXT="dylib"
|
||||
;;
|
||||
Linux)
|
||||
SHARED_LIB_EXT="so"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported OS: $OS"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Determine the project name and output path based on the output library argument
|
||||
for arg in "$@"; do
|
||||
if [[ "$arg" == *."$SHARED_LIB_EXT" ]]; then
|
||||
OUTPUT_PATH=$(dirname "$arg")
|
||||
LIB_NAME=$(basename "${arg%."$SHARED_LIB_EXT"}")
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Do a simple forward for any calls that are used to compile individual C files
|
||||
if [[ -z $LIB_NAME ]]; then
|
||||
cc "$@"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create a debug log in $output/logs
|
||||
LOG_PATH="${OUTPUT_PATH}/logs"
|
||||
LOG_FILE="${LOG_PATH}/compiler_commands.txt"
|
||||
mkdir -p "$LOG_PATH"
|
||||
|
||||
WORKINGDIR=${PWD}
|
||||
echo "Working directory: ${WORKINGDIR}" > "${LOG_FILE}"
|
||||
echo "Output path: ${OUTPUT_PATH}" >> "${LOG_FILE}"
|
||||
echo "Library name: ${LIB_NAME}" >> "${LOG_FILE}"
|
||||
echo "OS: ${OS}" >> "${LOG_FILE}"
|
||||
|
||||
echo "=====================================================" >> "${LOG_FILE}"
|
||||
echo " SHARED LIBRARY " >> "${LOG_FILE}"
|
||||
echo "=====================================================" >> "${LOG_FILE}"
|
||||
|
||||
CC_ARGS=( "$@" )
|
||||
echo "cc ${CC_ARGS[*]@Q}" >> "${LOG_FILE}"
|
||||
cc "${CC_ARGS[@]}"
|
||||
|
||||
echo "=====================================================" >> "${LOG_FILE}"
|
||||
echo " STATIC LIBRARY " >> "${LOG_FILE}"
|
||||
echo "=====================================================" >> "${LOG_FILE}"
|
||||
# To create a single static library we need to call 'ar -r' on all .o files.
|
||||
# In order to also include all static library dependencies, we can first extract the
|
||||
# .o files and then include them as well.
|
||||
echo "======= Source archives" >> "${LOG_FILE}"
|
||||
OBJECTS=${OUTPUT_PATH}/objects
|
||||
rm -rf "${OBJECTS}"
|
||||
mkdir "${OBJECTS}"
|
||||
|
||||
# Remove existing archive to avoid "fat file" errors
|
||||
ARCHIVE_FILE="${OUTPUT_PATH}/${LIB_NAME}.a"
|
||||
rm -f "${ARCHIVE_FILE}"
|
||||
|
||||
AR_ARGS="-rcs ${ARCHIVE_FILE} ${OBJECTS}/*.o"
|
||||
for arg in "$@"
|
||||
do
|
||||
if [[ $arg =~ .*\.(a)$ ]]; then
|
||||
# extract the objects (.o) of each archive (.a) into
|
||||
# separate directories to avoid naming collisions
|
||||
echo "$arg" >> "${LOG_FILE}"
|
||||
ARCHIVE_DIR=${OBJECTS}/$(basename "${arg%.a}")
|
||||
mkdir "${ARCHIVE_DIR}"
|
||||
cp "$arg" "${ARCHIVE_DIR}"
|
||||
cd "${ARCHIVE_DIR}" || exit
|
||||
ar -x "$arg"
|
||||
cd "${WORKINGDIR}" || exit
|
||||
AR_ARGS+=" ${ARCHIVE_DIR}/*.o"
|
||||
fi
|
||||
if [[ $arg =~ .*\.(o)$ ]]; then
|
||||
cp "$arg" "${OBJECTS}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "======= Objects" >> "${LOG_FILE}"
|
||||
find "${OBJECTS}" -name "*.o" >> "${LOG_FILE}"
|
||||
|
||||
echo "======= Archive command" >> "${LOG_FILE}"
|
||||
echo "ar $AR_ARGS" >> "${LOG_FILE}"
|
||||
# shellcheck disable=SC2086
|
||||
ar $AR_ARGS
|
||||
@@ -0,0 +1,85 @@
|
||||
::===----------------------------------------------------------------------===//
|
||||
:: Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
::
|
||||
:: Licensed under the Apache License, Version 2.0 (the "License");
|
||||
:: you may not use this file except in compliance with the License.
|
||||
:: You may obtain a copy of the License at
|
||||
::
|
||||
:: https://www.apache.org/licenses/LICENSE-2.0
|
||||
::
|
||||
:: Unless required by applicable law or agreed to in writing, software
|
||||
:: distributed under the License is distributed on an "AS IS" BASIS,
|
||||
:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
:: See the License for the specific language governing permissions and
|
||||
:: limitations under the License.
|
||||
::===----------------------------------------------------------------------===//
|
||||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
REM Adapted from https://github.com/oracle/graal/issues/3053#issuecomment-1866735057
|
||||
REM This script intercepts compiler arguments generated by GraalVM's native-image for
|
||||
REM creating a shared library, and additionally generates a self-contained static library.
|
||||
REM
|
||||
REM Use with --native-compiler-path=${pathToThisScript}.bat
|
||||
|
||||
REM Determine the library name and output path based on the .dll argument. MSVC's output-naming
|
||||
REM flag is passed as `/Fe<path>` with no space between the flag and the path, so strip that
|
||||
REM prefix before parsing the path - otherwise ~dp/~n misparse the combined token.
|
||||
set LIB_NAME=
|
||||
set OUTPUT_PATH=
|
||||
for %%P in (%*) do (
|
||||
echo %%P | findstr /C:".dll" 1>nul
|
||||
if !errorlevel!==0 (
|
||||
set "ARG=%%~P"
|
||||
if "!ARG:~0,3!"=="/Fe" set "ARG=!ARG:~3!"
|
||||
for %%F in ("!ARG!") do (
|
||||
set LIB_NAME=%%~nF
|
||||
set OUTPUT_PATH=%%~dpF
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
REM Do a simple forward for any calls that are used to compile individual C files
|
||||
IF "%LIB_NAME%"=="" (
|
||||
cmd /c cl %*
|
||||
exit /b
|
||||
)
|
||||
|
||||
REM Setup log path and log file
|
||||
set LOG_PATH=%OUTPUT_PATH%logs
|
||||
set LOG_FILE=%LOG_PATH%\compiler_commands.txt
|
||||
if not exist %LOG_PATH% mkdir %LOG_PATH%
|
||||
|
||||
echo Working directory: %CD% > %LOG_FILE%
|
||||
echo Output path: %OUTPUT_PATH% >> %LOG_FILE%
|
||||
echo Library name: %LIB_NAME% >> %LOG_FILE%
|
||||
|
||||
echo ===================================================== >> %LOG_FILE%
|
||||
echo SHARED LIBRARY >> %LOG_FILE%
|
||||
echo ===================================================== >> %LOG_FILE%
|
||||
set CL_ARGS=%*
|
||||
echo cl.exe %CL_ARGS% >> %LOG_FILE%
|
||||
cmd /c cl.exe %CL_ARGS%
|
||||
|
||||
echo ===================================================== >> %LOG_FILE%
|
||||
echo STATIC LIBRARY >> %LOG_FILE%
|
||||
echo ===================================================== >> %LOG_FILE%
|
||||
REM lib.exe can combine .obj and .lib inputs directly into a single output archive, so unlike
|
||||
REM build_unix.sh we don't need to manually extract members from input archives first - we just
|
||||
REM collect every .obj/.lib argument that was passed to the shared-library link and re-archive
|
||||
REM them together into one self-contained static library with no runtime DLL dependency.
|
||||
REM We don't want to overwrite the import library needed to link against the DLL, so we append
|
||||
REM "_s" to indicate that it is the static variant.
|
||||
set STATIC_INPUTS=
|
||||
for %%P in (%*) do (
|
||||
set ARG=%%P
|
||||
if /I "!ARG:~-4!"==".obj" set STATIC_INPUTS=!STATIC_INPUTS! %%P
|
||||
if /I "!ARG:~-4!"==".lib" set STATIC_INPUTS=!STATIC_INPUTS! %%P
|
||||
)
|
||||
|
||||
echo ======= Static inputs >> %LOG_FILE%
|
||||
echo %STATIC_INPUTS% >> %LOG_FILE%
|
||||
|
||||
set LIB_ARGS=/OUT:%OUTPUT_PATH%%LIB_NAME%_s.lib %STATIC_INPUTS%
|
||||
echo lib.exe %LIB_ARGS% >> %LOG_FILE%
|
||||
cmd /c lib.exe %LIB_ARGS%
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// pkl.h
|
||||
#ifndef PKL_H
|
||||
#define PKL_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define PKL_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define PKL_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#define PKL_ERR_LOCK 1 /* Failed to create a mutex, or acquire a lock on a mutex */
|
||||
#define PKL_ERR_PROTOCOL 2 /* Failed to decode a message */
|
||||
|
||||
/** Error details that occurred during a method call */
|
||||
typedef struct {
|
||||
char *message;
|
||||
} pkl_error_t;
|
||||
|
||||
/**
|
||||
* Pkl executor instance that manages communication with the Pkl runtime.
|
||||
*
|
||||
* Instances should be created via `pkl_init()` and destroyed via `pkl_close().`
|
||||
*
|
||||
* All operations on this struct are considered thread-safe and are synchronized via a mutex.
|
||||
*/
|
||||
typedef struct __pkl_exec_t pkl_exec_t;
|
||||
|
||||
/**
|
||||
* The callback that gets called when a message is received from Pkl.
|
||||
*
|
||||
* Messages must be deserialized to Pkl's Message Passing API:
|
||||
* https://pkl-lang.org/main/current/bindings-specification/message-passing-api.html
|
||||
*
|
||||
* @param length The length of the message bytes
|
||||
* @param message The message itself
|
||||
* @param userData User-defined data passed in from pkl_init.
|
||||
*/
|
||||
typedef void (*pkl_message_response_handler)(unsigned int length, char *message,
|
||||
void *userData);
|
||||
|
||||
/**
|
||||
* Initialises and allocates a Pkl executor, writing it to the slot pointed by `exec`.
|
||||
* Only one executor can exist at one time.
|
||||
* Calling `pkl_init` multiple times without calling `pkl_close` in between results in an error.
|
||||
*
|
||||
* @param handler The callback that gets called when a message is received from Pkl.
|
||||
* @param userData User-defined data that gets passed to handler.
|
||||
* @param exec The pointer to write the created pkl_exec_t to.
|
||||
* @param error The pointer to write error details to.
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
PKL_EXPORT int pkl_init(pkl_message_response_handler handler, void *userData,
|
||||
pkl_exec_t **exec, pkl_error_t *error);
|
||||
|
||||
/**
|
||||
* Send a message to Pkl, providing the length and a pointer to the first byte.
|
||||
*
|
||||
* Messages must be serialized to Pkl's Message Passing API:
|
||||
* https://pkl-lang.org/main/current/bindings-specification/message-passing-api.html
|
||||
*
|
||||
* @param pexec The Pkl executor instance.
|
||||
* @param length The length of the message, in bytes.
|
||||
* @param message The message to send to Pkl.
|
||||
*
|
||||
* @return 0 on success, and non-zero otherwise.
|
||||
*/
|
||||
PKL_EXPORT int pkl_send_message(pkl_exec_t *pexec, unsigned int length, char *message,
|
||||
pkl_error_t *error);
|
||||
|
||||
/**
|
||||
* Cleans up any resources that were created as part of the `pkl_init` process
|
||||
* for our `pkl_exec_t` instance.
|
||||
*
|
||||
* @param pexec The Pkl executor instance.
|
||||
*
|
||||
* @return 0 on success, -1 if `pexec` is NULL, and an error code otherwise.
|
||||
*/
|
||||
PKL_EXPORT int pkl_close(pkl_exec_t *pexec, pkl_error_t *error);
|
||||
|
||||
/**
|
||||
* Returns a null-terminated string indicating Pkl's version.
|
||||
*/
|
||||
PKL_EXPORT const char* pkl_version();
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// pkl.c
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <graal_isolate.h>
|
||||
#include <libpkl_internal.h>
|
||||
|
||||
#include <pkl.h>
|
||||
|
||||
#ifndef PKL_VERSION
|
||||
#define PKL_VERSION "0.0.0"
|
||||
#endif
|
||||
|
||||
struct __pkl_exec_t {
|
||||
#ifdef _WIN32
|
||||
CRITICAL_SECTION mutex;
|
||||
#else
|
||||
pthread_mutex_t mutex;
|
||||
#endif
|
||||
graal_isolatethread_t *graal_isolatethread;
|
||||
graal_isolate_t *isolate;
|
||||
|
||||
/**
|
||||
* The caller-supplied handler/userData from pkl_init, invoked only from `queue_thread`.
|
||||
*/
|
||||
pkl_message_response_handler handler;
|
||||
void *userData;
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE queue_thread;
|
||||
#else
|
||||
pthread_t queue_thread;
|
||||
#endif
|
||||
};
|
||||
|
||||
static int pkl_is_initialized = 0;
|
||||
|
||||
/**
|
||||
* Polls for messages coming from Pkl and sends them back to the handler.
|
||||
*
|
||||
* Ensures thats calls into Pkl are wrapped with graal_attach_thread/graal_detach_thread, and
|
||||
* calls back to the handler are _not_ inside the GraalVM thread context.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
static DWORD WINAPI pkl_dispatch_worker(LPVOID arg) {
|
||||
#else
|
||||
static void* pkl_dispatch_worker(void *arg) {
|
||||
#endif
|
||||
pkl_exec_t *pexec = (pkl_exec_t*) arg;
|
||||
|
||||
for (;;) {
|
||||
graal_isolatethread_t *thread;
|
||||
if (graal_attach_thread(pexec->isolate, &thread) != 0) {
|
||||
fprintf(stderr,
|
||||
"fatal: failed to attach response dispatch thread to isolate.\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
char *message = NULL;
|
||||
int length = pkl_internal_poll_response(thread, &message);
|
||||
|
||||
if (graal_detach_thread(thread) != 0) {
|
||||
fprintf(stderr,
|
||||
"fatal: failed to detach response dispatch thread from isolate.\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (length < 0) {
|
||||
// pkl_internal_server_stop has been called and the queue is drained
|
||||
break;
|
||||
}
|
||||
pexec->handler(length, message, pexec->userData);
|
||||
// message was allocated on the Java side via UnmanagedMemory.malloc, which maps onto
|
||||
// the platform's malloc/free; ownership passes to us here.
|
||||
free(message);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
return 0;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int pkl_start_dispatch_worker(pkl_exec_t *pexec, pkl_error_t *error) {
|
||||
#ifdef _WIN32
|
||||
pexec->queue_thread = CreateThread(NULL, 0, pkl_dispatch_worker, pexec, 0, NULL);
|
||||
if (pexec->queue_thread == NULL) {
|
||||
#else
|
||||
if (pthread_create(&pexec->queue_thread, NULL, pkl_dispatch_worker, pexec)
|
||||
!= 0) {
|
||||
#endif
|
||||
if (error != NULL) {
|
||||
error->message = "Failed to create response dispatch thread";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pkl_stop_dispatch_worker(pkl_exec_t *pexec) {
|
||||
#ifdef _WIN32
|
||||
WaitForSingleObject(pexec->queue_thread, INFINITE);
|
||||
CloseHandle(pexec->queue_thread);
|
||||
#else
|
||||
pthread_join(pexec->queue_thread, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void pkl_runtime_cleanup(pkl_exec_t *pexec) {
|
||||
// pkl_internal_server_stop unblocks queue_thread's pending/next poll call, so the join
|
||||
// below is guaranteed to return; only then is it safe to tear down the isolate.
|
||||
pkl_internal_server_stop(pexec->graal_isolatethread);
|
||||
pkl_stop_dispatch_worker(pexec);
|
||||
pkl_internal_close(pexec->graal_isolatethread);
|
||||
pexec->graal_isolatethread = NULL;
|
||||
}
|
||||
|
||||
static void pkl_unlock_mutex(pkl_exec_t *pexec) {
|
||||
#ifdef _WIN32
|
||||
LeaveCriticalSection(&pexec->mutex);
|
||||
#else
|
||||
if (pthread_mutex_unlock(&pexec->mutex) != 0) {
|
||||
fprintf(stderr, "fatal: failed to unlock mutex.\n");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int pkl_lock_mutex(pkl_exec_t *pexec, pkl_error_t *error) {
|
||||
#ifdef _WIN32
|
||||
EnterCriticalSection(&pexec->mutex);
|
||||
#else
|
||||
if (pthread_mutex_lock(&pexec->mutex) != 0) {
|
||||
if (error != NULL) {
|
||||
error->message = "failed to lock mutex";
|
||||
}
|
||||
return PKL_ERR_LOCK;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pkl_init(pkl_message_response_handler handler, void *userData,
|
||||
pkl_exec_t **exec, pkl_error_t *error) {
|
||||
if (handler == NULL) {
|
||||
if (error != NULL) {
|
||||
error->message = "handler is null";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (exec == NULL) {
|
||||
if (error != NULL) {
|
||||
error->message = "exec is null";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (pkl_is_initialized) {
|
||||
if (error != NULL) {
|
||||
error->message =
|
||||
"pkl_init called multiple times without calling pkl_close";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
pkl_exec_t *pexec = calloc(1, sizeof(pkl_exec_t));
|
||||
if (pexec == NULL) {
|
||||
fprintf(stderr, "failed to allocate pkl_exec_t\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
InitializeCriticalSection(&pexec->mutex);
|
||||
#else
|
||||
if (pthread_mutex_init(&pexec->mutex, NULL) != 0) {
|
||||
if (error != NULL) {
|
||||
error->message = "Failed to initialize mutex";
|
||||
}
|
||||
free(pexec);
|
||||
*exec = NULL;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
pexec->handler = handler;
|
||||
pexec->userData = userData;
|
||||
|
||||
pexec->graal_isolatethread = pkl_internal_init();
|
||||
|
||||
if (pexec->graal_isolatethread == NULL) {
|
||||
if (error != NULL) {
|
||||
error->message = "Failed to allocate graal_isolatethread";
|
||||
}
|
||||
#ifdef _WIN32
|
||||
DeleteCriticalSection(&pexec->mutex);
|
||||
#else
|
||||
if (pthread_mutex_destroy(&pexec->mutex) != 0) {
|
||||
fprintf(stderr, "fatal: failed to destroy mutex.\n");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
free(pexec);
|
||||
*exec = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pexec->isolate = graal_get_isolate(pexec->graal_isolatethread);
|
||||
if (pexec->isolate == NULL) {
|
||||
if (error != NULL) {
|
||||
error->message =
|
||||
"Failed to resolve isolate from graal_isolatethread";
|
||||
}
|
||||
pkl_internal_close(pexec->graal_isolatethread);
|
||||
#ifdef _WIN32
|
||||
DeleteCriticalSection(&pexec->mutex);
|
||||
#else
|
||||
if (pthread_mutex_destroy(&pexec->mutex) != 0) {
|
||||
fprintf(stderr, "fatal: failed to destroy mutex.\n");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
free(pexec);
|
||||
*exec = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pkl_start_dispatch_worker(pexec, error) != 0) {
|
||||
pkl_internal_close(pexec->graal_isolatethread);
|
||||
#ifdef _WIN32
|
||||
DeleteCriticalSection(&pexec->mutex);
|
||||
#else
|
||||
if (pthread_mutex_destroy(&pexec->mutex) != 0) {
|
||||
fprintf(stderr, "fatal: failed to destroy mutex.\n");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
free(pexec);
|
||||
*exec = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pkl_internal_server_start(pexec->graal_isolatethread);
|
||||
|
||||
pkl_is_initialized = 1;
|
||||
*exec = pexec;
|
||||
if (error != NULL) {
|
||||
error->message = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pkl_send_message(pkl_exec_t *pexec, unsigned int length, char *message,
|
||||
pkl_error_t *error) {
|
||||
if (pexec == NULL) {
|
||||
if (error != NULL) {
|
||||
error->message = "pexec is null";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (message == NULL) {
|
||||
if (error != NULL) {
|
||||
error->message = "message is null";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lock_response = pkl_lock_mutex(pexec, error);
|
||||
if (lock_response != 0) {
|
||||
return lock_response;
|
||||
}
|
||||
char *errormessage = NULL;
|
||||
int resp = pkl_internal_send_message(pexec->graal_isolatethread, length,
|
||||
message, &errormessage);
|
||||
pkl_unlock_mutex(pexec);
|
||||
if (resp != 0) {
|
||||
if (error != NULL) {
|
||||
error->message = errormessage;
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
if (error != NULL) {
|
||||
error->message = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pkl_close(pkl_exec_t *pexec, pkl_error_t *error) {
|
||||
if (pexec == NULL) {
|
||||
if (error != NULL) {
|
||||
error->message = "pexec is null";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
EnterCriticalSection(&pexec->mutex);
|
||||
#else
|
||||
if (pthread_mutex_lock(&pexec->mutex) != 0) {
|
||||
if (error != NULL) {
|
||||
error->message = "failed to lock mutex";
|
||||
}
|
||||
return PKL_ERR_LOCK;
|
||||
}
|
||||
#endif
|
||||
|
||||
pkl_runtime_cleanup(pexec);
|
||||
|
||||
#ifdef _WIN32
|
||||
LeaveCriticalSection(&pexec->mutex);
|
||||
DeleteCriticalSection(&pexec->mutex);
|
||||
#else
|
||||
if (pthread_mutex_unlock(&pexec->mutex) != 0) {
|
||||
fprintf(stderr, "fatal: failed to unlock mutex.\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (pthread_mutex_destroy(&pexec->mutex) != 0) {
|
||||
fprintf(stderr, "fatal: failed to destroy mutex.\n");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
pkl_is_initialized = 0;
|
||||
free(pexec);
|
||||
if (error != NULL) {
|
||||
error->message = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* pkl_version() {
|
||||
return PKL_VERSION;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
_pkl_init
|
||||
_pkl_send_message
|
||||
_pkl_close
|
||||
_pkl_version
|
||||
@@ -0,0 +1,9 @@
|
||||
PKL {
|
||||
global:
|
||||
pkl_init;
|
||||
pkl_send_message;
|
||||
pkl_close;
|
||||
pkl_version;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../../LICENSE.txt
|
||||
@@ -0,0 +1,5 @@
|
||||
# libpkl
|
||||
|
||||
libpkl is a native C library for calling into Pkl via its message passing API.
|
||||
|
||||
For full usage instructions, visit https://pkl-lang.org/main/current/libpkl/index.html
|
||||
@@ -0,0 +1,437 @@
|
||||
1) Graal Sdk (https://github.com/oracle/graal)
|
||||
POM License: Universal Permissive License, Version 1.0 - http://opensource.org/licenses/UPL
|
||||
|
||||
Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
The Universal Permissive License (UPL), Version 1.0
|
||||
|
||||
Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this software, associated documentation and/or data (collectively the "Software"), free of charge and under any and all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or (ii) the Larger Works (as defined below), to deal in both
|
||||
|
||||
(a) the Software, and
|
||||
|
||||
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software (each a "Larger Work" to which the Software is contributed by such licensors),
|
||||
|
||||
without restriction, including without limitation the rights to copy, create derivative works of, display, perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms.
|
||||
|
||||
This license is subject to the following condition:
|
||||
|
||||
The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----
|
||||
|
||||
2) Truffle API (http://openjdk.java.net/projects/graal)
|
||||
POM License: Universal Permissive License, Version 1.0 - http://opensource.org/licenses/UPL
|
||||
|
||||
Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
The Universal Permissive License (UPL), Version 1.0
|
||||
|
||||
Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this software, associated documentation and/or data (collectively the "Software"), free of charge and under any and all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or (ii) the Larger Works (as defined below), to deal in both
|
||||
|
||||
(a) the Software, and
|
||||
|
||||
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software (each a "Larger Work" to which the Software is contributed by such licensors),
|
||||
|
||||
without restriction, including without limitation the rights to copy, create derivative works of, display, perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms.
|
||||
|
||||
This license is subject to the following condition:
|
||||
|
||||
The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----
|
||||
|
||||
3) SubstrateVM (https://github.com/oracle/graal)
|
||||
POM License: GPL 2 with Classpath Exception
|
||||
|
||||
The GNU General Public License (GPL)
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to share
|
||||
and change it. By contrast, the GNU General Public License is intended to
|
||||
guarantee your freedom to share and change free software--to make sure the
|
||||
software is free for all its users. This General Public License applies to
|
||||
most of the Free Software Foundation's software and to any other program whose
|
||||
authors commit to using it. (Some other Free Software Foundation software is
|
||||
covered by the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our
|
||||
General Public Licenses are designed to make sure that you have the freedom to
|
||||
distribute copies of free software (and charge for this service if you wish),
|
||||
that you receive source code or can get it if you want it, that you can change
|
||||
the software or use pieces of it in new free programs; and that you know you
|
||||
can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid anyone to deny
|
||||
you these rights or to ask you to surrender the rights. These restrictions
|
||||
translate to certain responsibilities for you if you distribute copies of the
|
||||
software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or for
|
||||
a fee, you must give the recipients all the rights that you have. You must
|
||||
make sure that they, too, receive or can get the source code. And you must
|
||||
show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and (2)
|
||||
offer you this license which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain that
|
||||
everyone understands that there is no warranty for this free software. If the
|
||||
software is modified by someone else and passed on, we want its recipients to
|
||||
know that what they have is not the original, so that any problems introduced
|
||||
by others will not reflect on the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software patents. We
|
||||
wish to avoid the danger that redistributors of a free program will
|
||||
individually obtain patent licenses, in effect making the program proprietary.
|
||||
To prevent this, we have made it clear that any patent must be licensed for
|
||||
everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow.
|
||||
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains a notice
|
||||
placed by the copyright holder saying it may be distributed under the terms of
|
||||
this General Public License. The "Program", below, refers to any such program
|
||||
or work, and a "work based on the Program" means either the Program or any
|
||||
derivative work under copyright law: that is to say, a work containing the
|
||||
Program or a portion of it, either verbatim or with modifications and/or
|
||||
translated into another language. (Hereinafter, translation is included
|
||||
without limitation in the term "modification".) Each licensee is addressed as
|
||||
"you".
|
||||
|
||||
Activities other than copying, distribution and modification are not covered by
|
||||
this License; they are outside its scope. The act of running the Program is
|
||||
not restricted, and the output from the Program is covered only if its contents
|
||||
constitute a work based on the Program (independent of having been made by
|
||||
running the Program). Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's source code as
|
||||
you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and
|
||||
disclaimer of warranty; keep intact all the notices that refer to this License
|
||||
and to the absence of any warranty; and give any other recipients of the
|
||||
Program a copy of this License along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and you may
|
||||
at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion of it, thus
|
||||
forming a work based on the Program, and copy and distribute such modifications
|
||||
or work under the terms of Section 1 above, provided that you also meet all of
|
||||
these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices stating
|
||||
that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in whole or
|
||||
in part contains or is derived from the Program or any part thereof, to be
|
||||
licensed as a whole at no charge to all third parties under the terms of
|
||||
this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively when run,
|
||||
you must cause it, when started running for such interactive use in the
|
||||
most ordinary way, to print or display an announcement including an
|
||||
appropriate copyright notice and a notice that there is no warranty (or
|
||||
else, saying that you provide a warranty) and that users may redistribute
|
||||
the program under these conditions, and telling the user how to view a copy
|
||||
of this License. (Exception: if the Program itself is interactive but does
|
||||
not normally print such an announcement, your work based on the Program is
|
||||
not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If identifiable
|
||||
sections of that work are not derived from the Program, and can be reasonably
|
||||
considered independent and separate works in themselves, then this License, and
|
||||
its terms, do not apply to those sections when you distribute them as separate
|
||||
works. But when you distribute the same sections as part of a whole which is a
|
||||
work based on the Program, the distribution of the whole must be on the terms
|
||||
of this License, whose permissions for other licensees extend to the entire
|
||||
whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest your
|
||||
rights to work written entirely by you; rather, the intent is to exercise the
|
||||
right to control the distribution of derivative or collective works based on
|
||||
the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program with the
|
||||
Program (or with a work based on the Program) on a volume of a storage or
|
||||
distribution medium does not bring the other work under the scope of this
|
||||
License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it, under
|
||||
Section 2) in object code or executable form under the terms of Sections 1 and
|
||||
2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable source
|
||||
code, which must be distributed under the terms of Sections 1 and 2 above
|
||||
on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three years, to
|
||||
give any third party, for a charge no more than your cost of physically
|
||||
performing source distribution, a complete machine-readable copy of the
|
||||
corresponding source code, to be distributed under the terms of Sections 1
|
||||
and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer to
|
||||
distribute corresponding source code. (This alternative is allowed only
|
||||
for noncommercial distribution and only if you received the program in
|
||||
object code or executable form with such an offer, in accord with
|
||||
Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for making
|
||||
modifications to it. For an executable work, complete source code means all
|
||||
the source code for all modules it contains, plus any associated interface
|
||||
definition files, plus the scripts used to control compilation and installation
|
||||
of the executable. However, as a special exception, the source code
|
||||
distributed need not include anything that is normally distributed (in either
|
||||
source or binary form) with the major components (compiler, kernel, and so on)
|
||||
of the operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the source
|
||||
code from the same place counts as distribution of the source code, even though
|
||||
third parties are not compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program except as
|
||||
expressly provided under this License. Any attempt otherwise to copy, modify,
|
||||
sublicense or distribute the Program is void, and will automatically terminate
|
||||
your rights under this License. However, parties who have received copies, or
|
||||
rights, from you under this License will not have their licenses terminated so
|
||||
long as such parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not signed it.
|
||||
However, nothing else grants you permission to modify or distribute the Program
|
||||
or its derivative works. These actions are prohibited by law if you do not
|
||||
accept this License. Therefore, by modifying or distributing the Program (or
|
||||
any work based on the Program), you indicate your acceptance of this License to
|
||||
do so, and all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the Program),
|
||||
the recipient automatically receives a license from the original licensor to
|
||||
copy, distribute or modify the Program subject to these terms and conditions.
|
||||
You may not impose any further restrictions on the recipients' exercise of the
|
||||
rights granted herein. You are not responsible for enforcing compliance by
|
||||
third parties to this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues), conditions
|
||||
are imposed on you (whether by court order, agreement or otherwise) that
|
||||
contradict the conditions of this License, they do not excuse you from the
|
||||
conditions of this License. If you cannot distribute so as to satisfy
|
||||
simultaneously your obligations under this License and any other pertinent
|
||||
obligations, then as a consequence you may not distribute the Program at all.
|
||||
For example, if a patent license would not permit royalty-free redistribution
|
||||
of the Program by all those who receive copies directly or indirectly through
|
||||
you, then the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply and
|
||||
the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any patents or
|
||||
other property right claims or to contest validity of any such claims; this
|
||||
section has the sole purpose of protecting the integrity of the free software
|
||||
distribution system, which is implemented by public license practices. Many
|
||||
people have made generous contributions to the wide range of software
|
||||
distributed through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing to
|
||||
distribute software through any other system and a licensee cannot impose that
|
||||
choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be a
|
||||
consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in certain
|
||||
countries either by patents or by copyrighted interfaces, the original
|
||||
copyright holder who places the Program under this License may add an explicit
|
||||
geographical distribution limitation excluding those countries, so that
|
||||
distribution is permitted only in or among countries not thus excluded. In
|
||||
such case, this License incorporates the limitation as if written in the body
|
||||
of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions of the
|
||||
General Public License from time to time. Such new versions will be similar in
|
||||
spirit to the present version, but may differ in detail to address new problems
|
||||
or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any later
|
||||
version", you have the option of following the terms and conditions either of
|
||||
that version or of any later version published by the Free Software Foundation.
|
||||
If the Program does not specify a version number of this License, you may
|
||||
choose any version ever published by the Free Software Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free programs
|
||||
whose distribution conditions are different, write to the author to ask for
|
||||
permission. For software which is copyrighted by the Free Software Foundation,
|
||||
write to the Free Software Foundation; we sometimes make exceptions for this.
|
||||
Our decision will be guided by the two goals of preserving the free status of
|
||||
all derivatives of our free software and of promoting the sharing and reuse of
|
||||
software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
|
||||
THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
|
||||
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
|
||||
PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
||||
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
|
||||
YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
|
||||
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
|
||||
PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
|
||||
INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
|
||||
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
|
||||
OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest possible
|
||||
use to the public, the best way to achieve this is to make it free software
|
||||
which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to attach
|
||||
them to the start of each source file to most effectively convey the exclusion
|
||||
of warranty; and each file should have at least the "copyright" line and a
|
||||
pointer to where the full notice is found.
|
||||
|
||||
One line to give the program's name and a brief idea of what it does.
|
||||
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this when it
|
||||
starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
|
||||
with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free
|
||||
software, and you are welcome to redistribute it under certain conditions;
|
||||
type 'show c' for details.
|
||||
|
||||
The hypothetical commands 'show w' and 'show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may be
|
||||
called something other than 'show w' and 'show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary. Here
|
||||
is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
'Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
signature of Ty Coon, 1 April 1989
|
||||
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General Public
|
||||
License instead of this License.
|
||||
|
||||
|
||||
"CLASSPATH" EXCEPTION TO THE GPL
|
||||
|
||||
Certain source files distributed by Oracle America and/or its affiliates
|
||||
are subject to the following clarification and special exception to the GPLv2,
|
||||
based on the GNU Project exception for its Classpath libraries, known as the
|
||||
GNU Classpath Exception, but only where Oracle has expressly included in the
|
||||
particular source file's header the words "Oracle designates this particular
|
||||
file as subject to the "Classpath" exception as provided by Oracle in the
|
||||
LICENSE file that accompanied this code."
|
||||
|
||||
You should also note that Oracle includes multiple, independent programs in
|
||||
this software package. Some of those programs are provided under licenses
|
||||
deemed incompatible with the GPLv2 by the Free Software Foundation and others.
|
||||
For example, the package includes programs licensed under the Apache License,
|
||||
Version 2.0. Such programs are licensed to you under their original licenses.
|
||||
|
||||
Oracle facilitates your further distribution of this package by adding the
|
||||
Classpath Exception to the necessary parts of its GPLv2 code, which permits you
|
||||
to use that code in combination with other independent modules not licensed
|
||||
under the GPLv2. However, note that this would not permit you to commingle code
|
||||
under an incompatible license with Oracle's GPLv2 licensed code by, for
|
||||
example, cutting and pasting such code into a file also containing Oracle's
|
||||
GPLv2 licensed code and then distributing the result.
|
||||
|
||||
Additionally, if you were to remove the Classpath Exception from any of the
|
||||
files to which it applies and distribute the result, you would likely be
|
||||
required to license some or all of the other code in that distribution under
|
||||
the GPLv2 as well, and since the GPLv2 is incompatible with the license terms
|
||||
of some items included in the distribution by Oracle, removing the Classpath
|
||||
Exception could therefore effectively compromise your ability to further
|
||||
distribute the package.
|
||||
|
||||
Proceed with caution and we recommend that you obtain the advice of a lawyer
|
||||
skilled in open source matters before removing the Classpath Exception or
|
||||
making modifications to this package which may subsequently be redistributed
|
||||
and/or involve the use of third party software.
|
||||
|
||||
CLASSPATH EXCEPTION
|
||||
|
||||
Linking this library statically or dynamically with other modules is making a
|
||||
combined work based on this library. Thus, the terms and conditions of the GNU
|
||||
General Public License version 2 cover the whole combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent modules, and
|
||||
to copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the terms and
|
||||
conditions of the license of that module. An independent module is a module
|
||||
which is not derived from or based on this library. If you modify this library,
|
||||
you may extend this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this exception
|
||||
statement from your version.
|
||||
|
||||
----
|
||||
|
||||
4) msgpack-core (https://msgpack.org/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
Copyright © 2016 Sadayuki Furuhashi, Muga Nishizawa, Taro L. Saito, Mitsunori Komatsu, Ozawa Tsuyoshi
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
@@ -0,0 +1,11 @@
|
||||
prefix=${pcfiledir}/../..
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libpkl
|
||||
Description: C library for calling into Pkl's message passing API.
|
||||
URL: https://pkl-lang.org/main/current/libpkl/index.html
|
||||
Version: @version@
|
||||
Libs: -L${libdir} -lpkl -lz -lpthread
|
||||
Cflags: -I${includedir}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.libpkl;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import org.graalvm.nativeimage.IsolateThread;
|
||||
import org.graalvm.nativeimage.UnmanagedMemory;
|
||||
import org.graalvm.nativeimage.c.function.CEntryPoint;
|
||||
import org.graalvm.nativeimage.c.type.CCharPointer;
|
||||
import org.graalvm.nativeimage.c.type.CCharPointerPointer;
|
||||
import org.graalvm.nativeimage.c.type.CTypeConversion;
|
||||
import org.graalvm.word.WordFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.pkl.core.messaging.MessageTransports.Logger;
|
||||
import org.pkl.core.messaging.ProtocolException;
|
||||
import org.pkl.server.Server;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class LibPklInternal {
|
||||
private static final Logger logger = new LibPklLogger();
|
||||
private static final NativeTransport transport =
|
||||
new NativeTransport(logger, LibPklInternal::handleSendMessageToNative);
|
||||
private static @Nullable Server server;
|
||||
|
||||
private static final BlockingQueue<byte[]> responseQueue = new LinkedBlockingQueue<>();
|
||||
|
||||
// sentinel identity, not contents, marks the end of the stream - see pklInternalPollResponse
|
||||
private static final byte[] STOP_SENTINEL = new byte[0];
|
||||
|
||||
// keep in sync with values defined in pkl.h
|
||||
static final int PKL_ERR_PROTOCOL = 2;
|
||||
|
||||
private LibPklInternal() {}
|
||||
|
||||
@CEntryPoint(name = "pkl_internal_init", builtin = CEntryPoint.Builtin.CREATE_ISOLATE)
|
||||
static native IsolateThread pklInternalInit();
|
||||
|
||||
@CEntryPoint(name = "pkl_internal_send_message")
|
||||
public static int pklInternalSendMessage(
|
||||
IsolateThread thread, int length, CCharPointer ptr, CCharPointerPointer errorMessage) {
|
||||
try {
|
||||
transport.sendMessage(length, ptr);
|
||||
return 0;
|
||||
} catch (ProtocolException e) {
|
||||
@SuppressWarnings("resource")
|
||||
var cString =
|
||||
CTypeConversion.toCString("Invalid encoding: %s".formatted(e.getMessage())).get();
|
||||
errorMessage.write(cString);
|
||||
return PKL_ERR_PROTOCOL;
|
||||
}
|
||||
}
|
||||
|
||||
@CEntryPoint(name = "pkl_internal_close", builtin = CEntryPoint.Builtin.TEAR_DOWN_ISOLATE)
|
||||
public static native void pklInternalClose(IsolateThread thread);
|
||||
|
||||
@CEntryPoint(name = "pkl_internal_server_start")
|
||||
public static void pklInternalServerStart(IsolateThread thread) {
|
||||
server = new Server(transport);
|
||||
server.start();
|
||||
}
|
||||
|
||||
@CEntryPoint(name = "pkl_internal_server_stop")
|
||||
public static void pklInternalServerStop(IsolateThread thread) {
|
||||
assert server != null;
|
||||
server.close();
|
||||
// wakes up (and eventually stops) whatever thread is blocked in pkl_internal_poll_response
|
||||
responseQueue.add(STOP_SENTINEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks until a response is available, copies it into unmanaged memory, and writes its address
|
||||
* to {@code outMessage}. The caller (pkl.c) takes ownership of the returned buffer and must free
|
||||
* it with the C library's {@code free}.
|
||||
*
|
||||
* @return the length of the response in bytes, or a negative value once the server has been
|
||||
* stopped and no further responses will ever be produced.
|
||||
*/
|
||||
@CEntryPoint(name = "pkl_internal_poll_response")
|
||||
public static int pklInternalPollResponse(IsolateThread thread, CCharPointerPointer outMessage) {
|
||||
byte[] bytes;
|
||||
try {
|
||||
bytes = responseQueue.take();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
outMessage.write(WordFactory.nullPointer());
|
||||
return -1;
|
||||
}
|
||||
// identity check, not content check: a genuine zero-length message is never this instance
|
||||
if (bytes == STOP_SENTINEL) {
|
||||
outMessage.write(WordFactory.nullPointer());
|
||||
return -1;
|
||||
}
|
||||
var buf = UnmanagedMemory.<CCharPointer>malloc(WordFactory.unsigned(bytes.length));
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
buf.write(i, bytes[i]);
|
||||
}
|
||||
outMessage.write(buf);
|
||||
return bytes.length;
|
||||
}
|
||||
|
||||
public static void handleSendMessageToNative(byte[] bytes) {
|
||||
responseQueue.add(bytes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.libpkl;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.pkl.core.messaging.MessageTransports.Logger;
|
||||
|
||||
public class LibPklLogger implements Logger {
|
||||
|
||||
@Override
|
||||
public void log(String msg) {
|
||||
if (Objects.equals(System.getenv("PKL_DEBUG"), "1")) {
|
||||
System.err.println("[libpkl] " + msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.libpkl;
|
||||
|
||||
import java.io.InputStream;
|
||||
import org.graalvm.nativeimage.c.type.CCharPointer;
|
||||
|
||||
public class NativeInputStream extends InputStream {
|
||||
private int offset;
|
||||
private final int length;
|
||||
private final CCharPointer ptr;
|
||||
|
||||
public NativeInputStream(int length, CCharPointer ptr) {
|
||||
super();
|
||||
this.length = length;
|
||||
this.ptr = ptr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() {
|
||||
if (available() <= 0) {
|
||||
return -1;
|
||||
}
|
||||
var result = ptr.read(offset);
|
||||
offset++;
|
||||
return result & 0xFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return length - offset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.libpkl;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
import org.graalvm.nativeimage.c.type.CCharPointer;
|
||||
import org.msgpack.core.MessagePack;
|
||||
import org.pkl.core.PklBugException;
|
||||
import org.pkl.core.messaging.Message;
|
||||
import org.pkl.core.messaging.MessageTransports.AbstractMessageTransport;
|
||||
import org.pkl.core.messaging.MessageTransports.Logger;
|
||||
import org.pkl.core.messaging.ProtocolException;
|
||||
import org.pkl.server.ServerMessagePackDecoder;
|
||||
import org.pkl.server.ServerMessagePackEncoder;
|
||||
|
||||
public class NativeTransport extends AbstractMessageTransport {
|
||||
private final Consumer<byte[]> sendMessageToNative;
|
||||
|
||||
protected NativeTransport(Logger logger, Consumer<byte[]> sendMessageToNative) {
|
||||
super(logger);
|
||||
this.sendMessageToNative = sendMessageToNative;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() {}
|
||||
|
||||
@Override
|
||||
protected void doClose() {}
|
||||
|
||||
@Override
|
||||
protected void doSend(Message message) {
|
||||
try (var os = new ByteArrayOutputStream();
|
||||
var packer = MessagePack.newDefaultPacker(os)) {
|
||||
var encoder = new ServerMessagePackEncoder(packer);
|
||||
encoder.encode(message);
|
||||
sendMessageToNative.accept(os.toByteArray());
|
||||
} catch (IOException e) {
|
||||
// impossible; no IO happens during packing
|
||||
throw PklBugException.unreachableCode();
|
||||
} catch (ProtocolException e) {
|
||||
System.err.println("Received unexpected ProtocolException when encoding a message, aborting");
|
||||
e.printStackTrace(System.err);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessage(int length, CCharPointer ptr) throws ProtocolException {
|
||||
if (length == 0) {
|
||||
throw new ProtocolException("Unexpected end of input; 0 message bytes");
|
||||
}
|
||||
try (var is = new NativeInputStream(length, ptr);
|
||||
var unpacker = MessagePack.newDefaultUnpacker(is)) {
|
||||
var message = new ServerMessagePackDecoder(unpacker).decode();
|
||||
// guaranteed by `length == 0` check above
|
||||
assert message != null;
|
||||
accept(message);
|
||||
} catch (IOException e) {
|
||||
// impossible; no IO happens during unpacking
|
||||
throw PklBugException.unreachableCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
@NullMarked
|
||||
package org.pkl.libpkl;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// test_pkl.c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "pkl.h"
|
||||
|
||||
// Callback for receiving messages
|
||||
void test_message_handler(unsigned int length, char *message, void *userData) {
|
||||
printf("Received message of length %d\n", length);
|
||||
// Store message in userData for verification
|
||||
if (userData != NULL) {
|
||||
char **stored = (char**) userData;
|
||||
*stored = malloc(length + 1);
|
||||
memcpy(*stored, message, length);
|
||||
(*stored)[length] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// Test pkl_version
|
||||
void test_version() {
|
||||
const char *version = pkl_version();
|
||||
assert(version != NULL);
|
||||
printf("✓ pkl_version: %s\n", version);
|
||||
}
|
||||
|
||||
// Test pkl_init and pkl_close
|
||||
void test_init_close() {
|
||||
pkl_error_t err = { 0 };
|
||||
pkl_exec_t *exec = NULL;
|
||||
int result = pkl_init(test_message_handler, NULL, &exec, &err);
|
||||
assert(result == 0);
|
||||
assert(exec != NULL);
|
||||
|
||||
result = pkl_close(exec, &err);
|
||||
assert(result == 0);
|
||||
printf("✓ pkl_init/close succeeded\n");
|
||||
}
|
||||
|
||||
// Test error handling
|
||||
void test_null_send_message() {
|
||||
pkl_error_t err = { 0 };
|
||||
int result = pkl_send_message(NULL, 0, NULL, &err);
|
||||
assert(result == -1);
|
||||
|
||||
result = pkl_close(NULL, &err);
|
||||
assert(result == -1);
|
||||
printf("✓ Error handling works\n");
|
||||
}
|
||||
|
||||
// A zero-length message decodes to nothing and must be reported as an error, not silently accepted.
|
||||
void test_empty_message() {
|
||||
pkl_error_t err = { 0 };
|
||||
pkl_exec_t *exec = NULL;
|
||||
assert(pkl_init(test_message_handler, NULL, &exec, &err) == 0);
|
||||
|
||||
char dummy = 0;
|
||||
int result = pkl_send_message(exec, 0, &dummy, &err);
|
||||
assert(result == PKL_ERR_PROTOCOL);
|
||||
|
||||
assert(pkl_close(exec, &err) == 0);
|
||||
printf("✓ Empty message rejected\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("Running libpkl C tests...\n\n");
|
||||
|
||||
test_version();
|
||||
test_init_close();
|
||||
test_null_send_message();
|
||||
test_empty_message();
|
||||
|
||||
printf("\nAll tests passed!\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.libpkl
|
||||
|
||||
import com.sun.jna.Callback
|
||||
import com.sun.jna.Library
|
||||
import com.sun.jna.Native
|
||||
import com.sun.jna.Pointer
|
||||
import com.sun.jna.Structure
|
||||
import com.sun.jna.ptr.PointerByReference
|
||||
|
||||
@Suppress("FunctionName")
|
||||
interface LibPklJNA : Library {
|
||||
companion object {
|
||||
val INSTANCE: LibPklJNA = Native.load("pkl", LibPklJNA::class.java)
|
||||
}
|
||||
|
||||
@Structure.FieldOrder("message")
|
||||
class PklError : Structure() {
|
||||
@JvmField var message: String? = null
|
||||
}
|
||||
|
||||
interface PklMessageResponseHandler : Callback {
|
||||
fun invoke(length: Int, message: Pointer, userData: Pointer?)
|
||||
}
|
||||
|
||||
fun pkl_init(
|
||||
handler: PklMessageResponseHandler,
|
||||
userData: Pointer?,
|
||||
exec: PointerByReference,
|
||||
error: PklError,
|
||||
): Int
|
||||
|
||||
fun pkl_send_message(pexec: Pointer, length: Int, message: ByteArray, error: PklError): Int
|
||||
|
||||
fun pkl_close(pexec: Pointer, error: PklError): Int
|
||||
|
||||
fun pkl_version(): String
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.libpkl
|
||||
|
||||
import com.sun.jna.Pointer
|
||||
import com.sun.jna.ptr.PointerByReference
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.msgpack.core.MessagePack
|
||||
import org.pkl.core.messaging.Message
|
||||
import org.pkl.core.messaging.MessageTransports
|
||||
import org.pkl.server.ServerMessagePackDecoder
|
||||
import org.pkl.server.ServerMessagePackEncoder
|
||||
|
||||
class LibPklMessageTransport : MessageTransports.AbstractMessageTransport({}) {
|
||||
private val messageResponseHandler: LibPklJNA.PklMessageResponseHandler =
|
||||
object : LibPklJNA.PklMessageResponseHandler {
|
||||
override fun invoke(length: Int, message: Pointer, userData: Pointer?) {
|
||||
val message = decode(message.getByteArray(0, length))
|
||||
accept(message)
|
||||
}
|
||||
}
|
||||
|
||||
var pexec: Pointer? = null
|
||||
|
||||
override fun doStart() {
|
||||
val execRef = PointerByReference()
|
||||
val error = LibPklJNA.PklError()
|
||||
val result = LibPklJNA.INSTANCE.pkl_init(messageResponseHandler, Pointer.NULL, execRef, error)
|
||||
assertThat(result).`as` { "Failed to call pkl_init: ${error.message}" }.isEqualTo(0)
|
||||
pexec = execRef.value
|
||||
assertThat(pexec).isNotNull()
|
||||
}
|
||||
|
||||
override fun doClose() {
|
||||
val error = LibPklJNA.PklError()
|
||||
val result = LibPklJNA.INSTANCE.pkl_close(pexec!!, error)
|
||||
assertThat(result).`as` { "Failed to call pkl_close: ${error.message}" }.isEqualTo(0)
|
||||
}
|
||||
|
||||
override fun doSend(message: Message) {
|
||||
val bytes = encode(message)
|
||||
val error = LibPklJNA.PklError()
|
||||
val result = LibPklJNA.INSTANCE.pkl_send_message(pexec!!, bytes.size, bytes, error)
|
||||
assertThat(result).`as` { "Failed to call pkl_send_message: ${error.message}" }.isEqualTo(0)
|
||||
}
|
||||
|
||||
private fun encode(message: Message): ByteArray {
|
||||
val packer = MessagePack.newDefaultBufferPacker()
|
||||
val encoder = ServerMessagePackEncoder(packer)
|
||||
encoder.encode(message)
|
||||
return packer.toByteArray()
|
||||
}
|
||||
|
||||
private fun decode(receivedBytes: ByteArray): Message {
|
||||
val unpacker = MessagePack.newDefaultUnpacker(receivedBytes)
|
||||
return ServerMessagePackDecoder(unpacker).decode()!!
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.libpkl
|
||||
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.pkl.commons.test.server.AbstractServerTest
|
||||
import org.pkl.commons.test.server.TestTransport
|
||||
|
||||
/**
|
||||
* Tests libpkl bindings by using JNA (see [LibPklJNA] and [LibPklMessageTransport]).
|
||||
*
|
||||
* Extends [AbstractServerTest] directly rather than
|
||||
* [org.pkl.commons.test.server.AbstractHttpServerTest], since a real outbound HTTP request causes
|
||||
* `doClose` to hang for about a minute here (suspected to be an unclosed `HttpClient`'s default
|
||||
* thread pool blocking native isolate teardown).
|
||||
*
|
||||
* To run these tests in IntelliJ, add
|
||||
* `-Djna.library.path=$ProjectFileDir$/libpkl/build/native-libs/<os>-<arch>/lib` to the run
|
||||
* configuration.
|
||||
*
|
||||
* You can modify the IntelliJ JUnit configuration template so that this flag gets added
|
||||
* automatically. See https://www.jetbrains.com/help/idea/run-debug-configuration.html#templates for
|
||||
* more details.
|
||||
*/
|
||||
class LibPklServerTest : AbstractServerTest() {
|
||||
override lateinit var client: TestTransport
|
||||
|
||||
val delegate = LibPklMessageTransport()
|
||||
|
||||
@BeforeEach
|
||||
fun beforeEach() {
|
||||
client = TestTransport(delegate).also { it.start() }
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun afterEach() {
|
||||
client.close()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.libpkl
|
||||
|
||||
import com.sun.jna.Pointer
|
||||
import com.sun.jna.ptr.PointerByReference
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.Release
|
||||
|
||||
class LibPklTest {
|
||||
@Test
|
||||
fun testMalformedMessage() {
|
||||
val messageResponseHandler =
|
||||
object : LibPklJNA.PklMessageResponseHandler {
|
||||
override fun invoke(length: Int, message: Pointer, userData: Pointer?) {}
|
||||
}
|
||||
val execRef = PointerByReference()
|
||||
val error = LibPklJNA.PklError()
|
||||
val result = LibPklJNA.INSTANCE.pkl_init(messageResponseHandler, Pointer.NULL, execRef, error)
|
||||
assertThat(result).`as` { "Failed to call pkl_init: ${error.message}" }.isEqualTo(0)
|
||||
val result2 =
|
||||
LibPklJNA.INSTANCE.pkl_send_message(
|
||||
execRef.value,
|
||||
10,
|
||||
byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
|
||||
error,
|
||||
)
|
||||
assertThat(result2).isNotEqualTo(0)
|
||||
assertThat(error.message).isEqualTo("Invalid encoding: Malformed message header.")
|
||||
assertThat(LibPklJNA.INSTANCE.pkl_close(execRef.value, error)).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testEmptyMessageIsRejected() {
|
||||
val execRef = PointerByReference()
|
||||
val error = LibPklJNA.PklError()
|
||||
val messageResponseHandler =
|
||||
object : LibPklJNA.PklMessageResponseHandler {
|
||||
override fun invoke(length: Int, message: Pointer, userData: Pointer?) {}
|
||||
}
|
||||
assertThat(LibPklJNA.INSTANCE.pkl_init(messageResponseHandler, Pointer.NULL, execRef, error))
|
||||
.`as` { "Failed to call pkl_init: ${error.message}" }
|
||||
.isEqualTo(0)
|
||||
try {
|
||||
val result = LibPklJNA.INSTANCE.pkl_send_message(execRef.value, 0, byteArrayOf(0), error)
|
||||
assertThat(result).isEqualTo(2)
|
||||
assertThat(error.message).contains("Unexpected end of input")
|
||||
} finally {
|
||||
assertThat(LibPklJNA.INSTANCE.pkl_close(execRef.value, error)).isEqualTo(0)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testVersionString() {
|
||||
val currentVersion = Release.current().version.toString()
|
||||
assertThat(LibPklJNA.INSTANCE.pkl_version()).isEqualTo(currentVersion)
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,10 @@ dependencies {
|
||||
api(libs.junitApi)
|
||||
api(libs.junitEngine)
|
||||
api(libs.junitParams)
|
||||
api(libs.wiremock)
|
||||
api(projects.pklCommons) // for convenience
|
||||
implementation(projects.pklCore)
|
||||
implementation(projects.pklServer)
|
||||
implementation(libs.assertj)
|
||||
implementation(libs.msgpack)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -179,3 +179,6 @@ class MessagePackDebugRenderer(bytes: ByteArray) {
|
||||
currIndent.setLength(currIndent.length - indent.length)
|
||||
}
|
||||
}
|
||||
|
||||
val ByteArray.debugRendering: String
|
||||
get() = MessagePackDebugRenderer(this).output
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.commons.test.server
|
||||
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.equalTo
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.get
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.ok
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.stubFor
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.verify
|
||||
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo
|
||||
import com.github.tomakehurst.wiremock.junit5.WireMockTest
|
||||
import java.net.URI
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.server.EvaluateRequest
|
||||
import org.pkl.server.EvaluateResponse
|
||||
import org.pkl.server.Http
|
||||
|
||||
/**
|
||||
* Extends [AbstractServerTest] with HTTP tests backed by a WireMock server.
|
||||
*
|
||||
* Some transports can't run these at all (e.g. `LibPklServerTest` - a real outbound HTTP request
|
||||
* causes `doClose` to hang for about a minute, suspected to be an unclosed `HttpClient`'s default
|
||||
* thread pool blocking native isolate teardown) - those extend [AbstractServerTest] directly
|
||||
* instead of this class.
|
||||
*/
|
||||
abstract class AbstractHttpServerTest : AbstractServerTest() {
|
||||
@Nested
|
||||
@WireMockTest
|
||||
inner class HttpTests {
|
||||
@Test
|
||||
fun `http headers`(wwRuntimeInfo: WireMockRuntimeInfo) {
|
||||
stubFor(get(urlEqualTo("/foo.pkl")).willReturn(ok("foo = 1")))
|
||||
val evaluatorId =
|
||||
client.sendCreateEvaluatorRequest(
|
||||
http =
|
||||
Http(
|
||||
caCertificates = null,
|
||||
proxy = null,
|
||||
rewrites = null,
|
||||
headers = mapOf("**" to mapOf("X-Foo" to listOf("Foo"))),
|
||||
)
|
||||
)
|
||||
client.send(
|
||||
EvaluateRequest(
|
||||
1,
|
||||
evaluatorId,
|
||||
URI("repl:text"),
|
||||
"res = import(\"${wwRuntimeInfo.httpBaseUrl}/foo.pkl\")",
|
||||
"output.text",
|
||||
)
|
||||
)
|
||||
val response = client.receive<EvaluateResponse>()
|
||||
assertThat(response.error).isNull()
|
||||
verify(getRequestedFor(urlEqualTo("/foo.pkl")).withHeader("X-Foo", equalTo("Foo")))
|
||||
}
|
||||
}
|
||||
}
|
||||
+37
-47
@@ -13,24 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.server
|
||||
package org.pkl.commons.test.server
|
||||
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.equalTo
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.get
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.ok
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.stubFor
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.verify
|
||||
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo
|
||||
import com.github.tomakehurst.wiremock.junit5.WireMockTest
|
||||
import java.io.PipedInputStream
|
||||
import java.io.PipedOutputStream
|
||||
import java.net.URI
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.AbstractExecutorService
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.outputStream
|
||||
@@ -39,21 +32,48 @@ import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.msgpack.core.MessagePack
|
||||
import org.pkl.commons.test.PackageServer
|
||||
import org.pkl.commons.test.debugRendering
|
||||
import org.pkl.core.messaging.Messages.*
|
||||
import org.pkl.core.module.PathElement
|
||||
import org.pkl.server.*
|
||||
|
||||
@Suppress("FunctionName")
|
||||
abstract class AbstractServerTest {
|
||||
|
||||
companion object {
|
||||
/** Set to `true` to bypass messagepack serialization when running [JvmServerTest]. */
|
||||
internal const val USE_DIRECT_TRANSPORT = false
|
||||
/** Set to `true` to bypass messagepack serialization when running JvmServerTest. */
|
||||
const val USE_DIRECT_TRANSPORT = false
|
||||
lateinit var executor: ExecutorService
|
||||
|
||||
fun createDirectExecutor(): ExecutorService =
|
||||
object : AbstractExecutorService() {
|
||||
override fun execute(command: Runnable) {
|
||||
command.run()
|
||||
}
|
||||
|
||||
override fun shutdown() {}
|
||||
|
||||
override fun shutdownNow(): MutableList<Runnable> {
|
||||
throw UnsupportedOperationException("shutdownNow")
|
||||
}
|
||||
|
||||
override fun isShutdown(): Boolean {
|
||||
throw UnsupportedOperationException("isShutdown")
|
||||
}
|
||||
|
||||
override fun isTerminated(): Boolean {
|
||||
throw UnsupportedOperationException("isTerminated")
|
||||
}
|
||||
|
||||
override fun awaitTermination(timeout: Long, unit: TimeUnit): Boolean {
|
||||
throw UnsupportedOperationException("awaitTermination")
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
@JvmStatic
|
||||
fun beforeAll() {
|
||||
@@ -643,7 +663,8 @@ abstract class AbstractServerTest {
|
||||
fun `read and evaluate module path from jar`(@TempDir tempDir: Path) {
|
||||
val jarFile = tempDir.resolve("resource1.jar")
|
||||
jarFile.outputStream().use { outStream ->
|
||||
javaClass.getResourceAsStream("resource1.jar")!!.use { inStream ->
|
||||
javaClass.getResourceAsStream("/org/pkl/commons/test/server/resource1.jar")!!.use { inStream
|
||||
->
|
||||
inStream.copyTo(outStream)
|
||||
}
|
||||
}
|
||||
@@ -933,7 +954,7 @@ abstract class AbstractServerTest {
|
||||
writerA.start()
|
||||
writerB.start()
|
||||
|
||||
done.await(30, java.util.concurrent.TimeUnit.SECONDS)
|
||||
done.await(30, TimeUnit.SECONDS)
|
||||
pipeOut.close()
|
||||
reader.join(10_000)
|
||||
|
||||
@@ -1112,38 +1133,7 @@ abstract class AbstractServerTest {
|
||||
.contains("Rewrite rule must end with '/', but was 'https://example.com'")
|
||||
}
|
||||
|
||||
@Nested
|
||||
@WireMockTest
|
||||
inner class HttpTests {
|
||||
@Test
|
||||
fun `http headers`(wwRuntimeInfo: WireMockRuntimeInfo) {
|
||||
stubFor(get(urlEqualTo("/foo.pkl")).willReturn(ok("foo = 1")))
|
||||
val evaluatorId =
|
||||
client.sendCreateEvaluatorRequest(
|
||||
http =
|
||||
Http(
|
||||
caCertificates = null,
|
||||
proxy = null,
|
||||
rewrites = null,
|
||||
headers = mapOf("**" to mapOf("X-Foo" to listOf("Foo"))),
|
||||
)
|
||||
)
|
||||
client.send(
|
||||
EvaluateRequest(
|
||||
1,
|
||||
evaluatorId,
|
||||
URI("repl:text"),
|
||||
"res = import(\"${wwRuntimeInfo.httpBaseUrl}/foo.pkl\")",
|
||||
"output.text",
|
||||
)
|
||||
)
|
||||
val response = client.receive<EvaluateResponse>()
|
||||
assertThat(response.error).isNull()
|
||||
verify(getRequestedFor(urlEqualTo("/foo.pkl")).withHeader("X-Foo", equalTo("Foo")))
|
||||
}
|
||||
}
|
||||
|
||||
private fun TestTransport.sendCreateEvaluatorRequest(
|
||||
protected fun TestTransport.sendCreateEvaluatorRequest(
|
||||
requestId: Long = 123,
|
||||
resourceReaders: List<ResourceReaderSpec> = listOf(),
|
||||
moduleReaders: List<ModuleReaderSpec> = listOf(),
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.server
|
||||
package org.pkl.commons.test.server
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue
|
||||
import java.util.concurrent.BlockingQueue
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,7 @@ public interface MessageTransport extends AutoCloseable {
|
||||
}
|
||||
|
||||
interface RequestHandler {
|
||||
void handleRequest(Message.Request msg) throws ProtocolException, IOException;
|
||||
void handleRequest(Message.Request msg) throws ProtocolException;
|
||||
}
|
||||
|
||||
interface ResponseHandler {
|
||||
|
||||
@@ -123,7 +123,7 @@ public final class MessageTransports {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract static class AbstractMessageTransport implements MessageTransport {
|
||||
public abstract static class AbstractMessageTransport implements MessageTransport {
|
||||
|
||||
private final Logger logger;
|
||||
private MessageTransport.OneWayHandler oneWayHandler =
|
||||
@@ -151,7 +151,7 @@ public final class MessageTransports {
|
||||
|
||||
protected abstract void doSend(Message message) throws ProtocolException, IOException;
|
||||
|
||||
protected void accept(Message message) throws ProtocolException, IOException {
|
||||
protected void accept(Message message) throws ProtocolException {
|
||||
log("Received message: {0}", message);
|
||||
if (message instanceof Message.OneWay msg) {
|
||||
oneWayHandler.handleOneWay(msg);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,11 +19,13 @@ import java.io.PipedInputStream
|
||||
import java.io.PipedOutputStream
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.pkl.commons.test.server.AbstractHttpServerTest
|
||||
import org.pkl.commons.test.server.TestTransport
|
||||
import org.pkl.core.messaging.MessageTransport
|
||||
import org.pkl.core.messaging.MessageTransports
|
||||
import org.pkl.core.util.Pair
|
||||
|
||||
class JvmServerTest : AbstractServerTest() {
|
||||
class JvmServerTest : AbstractHttpServerTest() {
|
||||
private val transports: Pair<MessageTransport, MessageTransport> = run {
|
||||
if (USE_DIRECT_TRANSPORT) {
|
||||
MessageTransports.direct(::log)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,9 +18,11 @@ package org.pkl.server
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.pkl.commons.test.Executables
|
||||
import org.pkl.commons.test.server.AbstractHttpServerTest
|
||||
import org.pkl.commons.test.server.TestTransport
|
||||
import org.pkl.core.messaging.MessageTransports
|
||||
|
||||
class NativeServerTest : AbstractServerTest() {
|
||||
class NativeServerTest : AbstractHttpServerTest() {
|
||||
private lateinit var server: Process
|
||||
override lateinit var client: TestTransport
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ include("bench")
|
||||
|
||||
include("docs")
|
||||
|
||||
include("libpkl")
|
||||
|
||||
include("pkl-bom")
|
||||
|
||||
include("pkl-cli")
|
||||
|
||||
Reference in New Issue
Block a user