Skip to content

Commit 9c9192e

Browse files
committed
Stage OpenCL-Headers + ICD-Loader before Android OpenCL build
The dockcross/android-arm64 image does not ship OpenCL headers or a stub libOpenCL.so, so find_package(OpenCL REQUIRED) in ggml-opencl fails. Add build_opencl_android.sh which clones pinned KhronosGroup OpenCL-Headers and cross-builds OpenCL-ICD-Loader inside the container, then passes -DOpenCL_INCLUDE_DIR and -DOpenCL_LIBRARY into the main project cmake. The device's vendor ICD (Adreno driver) provides the runtime symbols. https://claude.ai/code/session_01CQFUfYpg9m65CBt5RRaFRr
1 parent c560813 commit 9c9192e

3 files changed

Lines changed: 62 additions & 5 deletions

File tree

.github/build_opencl_android.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/bin/bash
2+
3+
# SPDX-FileCopyrightText: 2026 Bernard Ladenthin <bernard.ladenthin@gmail.com>
4+
#
5+
# SPDX-License-Identifier: MIT
6+
#
7+
# Android arm64 build with the OpenCL backend enabled and Adreno-tuned
8+
# kernels embedded. Runs inside the dockcross/android-arm64 container.
9+
#
10+
# The dockcross image does not ship OpenCL headers or a libOpenCL.so stub,
11+
# so this script first stages Khronos OpenCL-Headers and cross-builds
12+
# OpenCL-ICD-Loader to satisfy `find_package(OpenCL REQUIRED)` at link
13+
# time. At runtime the device's vendor ICD (e.g. Qualcomm Adreno driver)
14+
# provides the actual OpenCL symbols.
15+
16+
set -eu
17+
18+
# Forward args to the inner cmake invocation.
19+
EXTRA_ARGS=("$@")
20+
21+
OPENCL_STAGE=/tmp/opencl-stage
22+
HEADERS_DIR="$OPENCL_STAGE/OpenCL-Headers"
23+
LOADER_DIR="$OPENCL_STAGE/OpenCL-ICD-Loader"
24+
LOADER_BUILD="$LOADER_DIR/build"
25+
26+
# Pinned tags for reproducibility.
27+
HEADERS_TAG=v2025.07.22
28+
LOADER_TAG=v2025.07.22
29+
30+
if [ ! -d "$HEADERS_DIR" ]; then
31+
mkdir -p "$OPENCL_STAGE"
32+
git clone --depth 1 --branch "$HEADERS_TAG" \
33+
https://github.com/KhronosGroup/OpenCL-Headers.git "$HEADERS_DIR"
34+
fi
35+
36+
if [ ! -f "$LOADER_BUILD/libOpenCL.so" ]; then
37+
if [ ! -d "$LOADER_DIR" ]; then
38+
git clone --depth 1 --branch "$LOADER_TAG" \
39+
https://github.com/KhronosGroup/OpenCL-ICD-Loader.git "$LOADER_DIR"
40+
fi
41+
cmake -B "$LOADER_BUILD" -S "$LOADER_DIR" \
42+
-DCMAKE_BUILD_TYPE=Release \
43+
-DOPENCL_ICD_LOADER_HEADERS_DIR="$HEADERS_DIR" \
44+
-DBUILD_TESTING=OFF
45+
cmake --build "$LOADER_BUILD" --config Release -j"$(nproc)"
46+
fi
47+
48+
mkdir -p build
49+
cmake -Bbuild \
50+
-DOpenCL_INCLUDE_DIR="$HEADERS_DIR" \
51+
-DOpenCL_LIBRARY="$LOADER_BUILD/libOpenCL.so" \
52+
"${EXTRA_ARGS[@]}"
53+
cmake --build build --config Release -j"$(nproc)"

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ jobs:
146146
- name: Build libraries
147147
shell: bash
148148
run: |
149-
.github/dockcross/dockcross-android-arm64 .github/build.sh "-DANDROID_PLATFORM=android-24 -DOS_NAME=Linux-Android -DOS_ARCH=aarch64 -DGGML_OPENCL=ON -DGGML_OPENCL_EMBED_KERNELS=ON -DGGML_OPENCL_USE_ADRENO_KERNELS=ON"
149+
.github/dockcross/dockcross-android-arm64 .github/build_opencl_android.sh "-DANDROID_PLATFORM=android-24 -DOS_NAME=Linux-Android -DOS_ARCH=aarch64 -DGGML_OPENCL=ON -DGGML_OPENCL_EMBED_KERNELS=ON -DGGML_OPENCL_USE_ADRENO_KERNELS=ON"
150150
- name: Upload artifacts
151151
uses: actions/upload-artifact@v7
152152
with:

CLAUDE.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,20 @@ Three places wire it together (mirrors the CUDA classifier pattern):
6161

6262
Local sanity build:
6363
```bash
64-
.github/dockcross/dockcross-android-arm64 .github/build.sh \
64+
.github/dockcross/dockcross-android-arm64 .github/build_opencl_android.sh \
6565
"-DANDROID_PLATFORM=android-24 -DOS_NAME=Linux-Android -DOS_ARCH=aarch64 \
6666
-DGGML_OPENCL=ON -DGGML_OPENCL_EMBED_KERNELS=ON \
6767
-DGGML_OPENCL_USE_ADRENO_KERNELS=ON"
6868
```
6969
Artifacts land in `src/main/resources_android_opencl/net/ladenthin/llama/Linux-Android/aarch64/`.
7070

71-
At runtime the device must provide an OpenCL ICD (`libOpenCL.so`); Qualcomm
72-
Adreno drivers do. Devices without an ICD should use the default CPU-only
73-
Android JAR.
71+
The dockcross image does not ship OpenCL headers or a stub `libOpenCL.so`, so
72+
`build_opencl_android.sh` first stages Khronos `OpenCL-Headers` and
73+
cross-builds `OpenCL-ICD-Loader` into `/tmp/opencl-stage/` before invoking the
74+
main project cmake with `-DOpenCL_INCLUDE_DIR=...` and `-DOpenCL_LIBRARY=...`.
75+
At runtime the device must provide its own OpenCL ICD (`libOpenCL.so`);
76+
Qualcomm Adreno drivers do. Devices without an ICD should use the default
77+
CPU-only Android JAR.
7478

7579
## Upgrading/Downgrading llama.cpp Version
7680

0 commit comments

Comments
 (0)