From a67d1eb1cf98468d59b62c2dd0dc804c7c850b84 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 12 Sep 2026 09:47:12 +0000 Subject: [PATCH 1/4] Update generated OpenCL bindings --- DISTRIBUTION_FILES | 1 + GENERATOR_COMMIT | 2 +- opencl.v | 2 + setup.vsh | 231 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 setup.vsh diff --git a/DISTRIBUTION_FILES b/DISTRIBUTION_FILES index acd9983..146f376 100644 --- a/DISTRIBUTION_FILES +++ b/DISTRIBUTION_FILES @@ -48,6 +48,7 @@ include/CL/opencl.h opencl.v ownership.v program.v +setup.vsh svm.v test/pointer_abi_shim.c test/pointer_abi_test.v diff --git a/GENERATOR_COMMIT b/GENERATOR_COMMIT index 30f0b06..6603b76 100644 --- a/GENERATOR_COMMIT +++ b/GENERATOR_COMMIT @@ -1 +1 @@ -672b9a1dd1d38693829296568a832b656f86c866 +3abe0dabc477c2302e68a4fcb46ce493659fdeb9 diff --git a/opencl.v b/opencl.v index 90b01d7..8ecad26 100644 --- a/opencl.v +++ b/opencl.v @@ -3,6 +3,8 @@ module opencl #flag linux -lOpenCL #flag windows -lOpenCL +#flag windows -I@VMODROOT/include +#flag windows -L@VMODROOT/lib #flag darwin -framework OpenCL #flag darwin -I@VMODROOT/include #include diff --git a/setup.vsh b/setup.vsh new file mode 100644 index 0000000..38a1058 --- /dev/null +++ b/setup.vsh @@ -0,0 +1,231 @@ +#!/usr/bin/env -S v run + +// Installs and verifies the native prerequisites used by antono2.opencl. +// Running without arguments performs the installation. Use --check for a +// read-only diagnostic pass suitable for support requests and CI. + +import os + +const usage = 'Usage: v run setup.vsh [--install|--check]\n\n' + ' --install Install the OpenCL loader, headers, a development runtime, and this V module (default).\n' + ' --check Only report whether the compiler, headers, loader, and an OpenCL platform work.\n' + +fn command_exists(name string) bool { + os.find_abs_path_of_executable(name) or { return false } + return true +} + +fn run(command string) ! { + println('\n> ${command}') + result := os.execute(command) + if result.output.trim_space() != '' { + println(result.output.trim_right('\r\n')) + } + if result.exit_code != 0 { + return error('command failed with exit code ${result.exit_code}') + } +} + +fn install_linux() ! { + if command_exists('apt-get') { + run('sudo apt-get update')! + run('sudo apt-get install -y build-essential clinfo ocl-icd-opencl-dev pocl-opencl-icd')! + return + } + if command_exists('dnf') { + run('sudo dnf install -y gcc gcc-c++ clinfo ocl-icd-devel opencl-headers pocl')! + return + } + if command_exists('pacman') { + run('sudo pacman -S --needed --noconfirm base-devel clinfo ocl-icd opencl-headers pocl')! + return + } + if command_exists('zypper') { + run('sudo zypper --non-interactive install -y gcc gcc-c++ clinfo ocl-icd-devel opencl-headers pocl')! + return + } + return error('unsupported Linux package manager; install OpenCL headers, an ICD loader, clinfo, and an ICD such as PoCL, then rerun with --check') +} + +fn install_macos() ! { + if !command_exists('xcode-select') || os.execute('xcode-select -p').exit_code != 0 { + return error('Apple Command Line Tools are required; run `xcode-select --install`, then retry') + } + println('The OpenCL headers, loader, and implementation are provided by the macOS OpenCL framework.') +} + +fn copy_windows_sdk_files(module_root string) ! { + sdk_root := os.getenv('OPENCL_SDK') + source := os.join_path(sdk_root, 'lib', 'OpenCL.lib') + if !os.is_file(source) { + return error('OpenCL import library was not installed at ${source}') + } + os.mkdir_all(os.join_path(module_root, 'lib'))! + os.cp(source, os.join_path(module_root, 'lib', 'OpenCL.lib'))! + os.cp_all(os.join_path(sdk_root, 'include'), os.join_path(module_root, 'include'), true)! +} + +fn install_windows() ! { + if !command_exists('winget') { + return error('winget is required for automatic Windows setup; install Microsoft App Installer, then try again') + } + if !command_exists('git') { + run('winget install --id Git.Git --exact --accept-package-agreements --accept-source-agreements')! + } + if !command_exists('cmake') { + run('winget install --id Kitware.CMake --exact --accept-package-agreements --accept-source-agreements')! + } + path_result := os.execute('powershell -NoProfile -Command "[Environment]::GetEnvironmentVariable(\'Path\',\'Machine\') + \';\' + [Environment]::GetEnvironmentVariable(\'Path\',\'User\')"') + if path_result.exit_code == 0 && path_result.output.trim_space() != '' { + os.setenv('PATH', path_result.output.trim_space(), true) + } + cache_root := os.join_path(os.cache_dir(), 'antono2', 'opencl') + vcpkg_root := os.join_path(cache_root, 'vcpkg') + if !os.is_dir(vcpkg_root) { + os.mkdir_all(cache_root)! + run('git clone --depth 1 https://github.com/microsoft/vcpkg.git ${os.quoted_path(vcpkg_root)}')! + } + bootstrap := os.join_path(vcpkg_root, 'bootstrap-vcpkg.bat') + vcpkg := os.join_path(vcpkg_root, 'vcpkg.exe') + if !os.is_file(vcpkg) { + run(os.quoted_path(bootstrap))! + } + run('${os.quoted_path(vcpkg)} install opencl:x64-windows')! + sdk_root := os.join_path(vcpkg_root, 'installed', 'x64-windows') + os.setenv('OPENCL_SDK', sdk_root, true) + copy_windows_sdk_files(os.dir(os.real_path(@FILE)))! + // Persist the development location for new terminals. The current process + // is also updated above so verification can continue without a restart. + run('setx OPENCL_SDK ${os.quoted_path(sdk_root)}')! + println('\nThe Khronos loader is installed for development. Install the current GPU vendor driver to provide an OpenCL implementation.') +} + +fn install_native() ! { + $if linux { + install_linux()! + } $else $if macos { + install_macos()! + } $else $if windows { + install_windows()! + } $else { + return error('automatic setup is not supported on this operating system') + } +} + +fn find_opencl_header() string { + mut roots := []string{} + if sdk := os.getenv_opt('OPENCL_SDK') { + roots << sdk + } + $if macos { + framework := '/System/Library/Frameworks/OpenCL.framework' + if os.is_dir(framework) { + return framework + } + } $else $if !windows { + roots << ['/usr', '/usr/local', '/opt/homebrew'] + } + for root in roots { + for relative in ['include/CL/opencl.h', 'Headers/opencl.h'] { + candidate := os.join_path(root, relative) + if os.is_file(candidate) { + return candidate + } + } + } + return '' +} + +fn report_command(name string, required bool) bool { + if path := os.find_abs_path_of_executable(name) { + println('[ok] ${name}: ${path}') + return true + } + label := if required { 'missing' } else { 'optional' } + println('[${label}] ${name}') + return !required +} + +fn check() bool { + println('\nOpenCL setup check') + println('------------------') + mut ok := true + ok = report_command('v', true) && ok + $if windows { + report_command('cl', false) + } $else { + ok = report_command('cc', true) && ok + } + header := find_opencl_header() + $if macos { + if header == '' { + println('[missing] macOS OpenCL framework headers') + ok = false + } else { + println('[ok] OpenCL framework header: ${header}') + } + } $else { + if header == '' { + println('[missing] OpenCL development headers') + ok = false + } else { + println('[ok] OpenCL header: ${header}') + } + } + if command_exists('clinfo') { + result := os.execute('clinfo -l') + if result.exit_code == 0 && result.output.contains('Platform') { + println('[ok] OpenCL loader enumerated a platform') + } else { + println('[warning] the loader is installed, but no OpenCL platform was found') + println(' Install the GPU vendor driver or a CPU implementation such as PoCL.') + } + } else { + $if windows { + if os.exists(os.join_path(os.getenv('WINDIR'), 'System32', 'OpenCL.dll')) { + println('[ok] OpenCL.dll is installed') + } else { + println('[warning] OpenCL.dll was not found; install the current GPU vendor driver') + } + } $else $if macos { + println('[ok] macOS OpenCL framework is available') + } $else { + println('[warning] clinfo is unavailable; OpenCL runtime verification was skipped') + } + } + return ok +} + +fn main() { + if os.args.len > 2 || (os.args.len == 2 && os.args[1] !in ['--install', '--check', '-h', '--help']) { + eprintln(usage) + exit(2) + } + if os.args.len == 2 && os.args[1] in ['-h', '--help'] { + println(usage) + return + } + install := os.args.len == 1 || os.args[1] == '--install' + if install { + install_native() or { + eprintln('Setup failed: ${err}') + exit(1) + } + if command_exists('v') { + run('v install antono2.opencl') or { + eprintln('Could not install the V module: ${err}') + exit(1) + } + $if windows { + installed_module := os.join_path(os.vmodules_dir(), 'antono2', 'opencl') + copy_windows_sdk_files(installed_module) or { + eprintln('Could not configure the installed V module: ${err}') + exit(1) + } + } + } + } + if !check() { + eprintln('\nSetup is incomplete. Resolve the missing items above and rerun with --check.') + exit(1) + } + println('\nOpenCL development prerequisites are ready.') +} From d58bfc34d210b2ce456f19a8f37487116bca2fd6 Mon Sep 17 00:00:00 2001 From: Anton Oreskin Date: Sat, 12 Sep 2026 11:23:25 +0200 Subject: [PATCH 2/4] Document and test one-command OpenCL setup --- .github/workflows/test.yml | 10 ++++++++-- README.md | 15 +++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e683642..94b4a2e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,6 +45,8 @@ jobs: run: | sudo apt-get update sudo apt-get install --yes ocl-icd-opencl-dev pocl-opencl-icd libvulkan-dev libvulkan-volk-dev libglfw3-dev mesa-vulkan-drivers vulkan-validationlayers xauth xvfb + - name: Verify the public setup diagnostics + run: v run setup.vsh --check - name: Assemble namespaced module and install example modules run: | install -d "$HOME/.vmodules/antono2/opencl" @@ -98,7 +100,9 @@ jobs: install -d "$HOME/.vmodules/antono2/opencl/include/CL" install -m 0644 include/CL/opencl.h "$HOME/.vmodules/antono2/opencl/include/CL/opencl.h" - name: Compile macOS ABI probe - run: v -cc clang -o /tmp/opencl-abi-probe abi/main.c.v + run: | + v run setup.vsh --check + v -cc clang -o /tmp/opencl-abi-probe abi/main.c.v linux-v-master: runs-on: ubuntu-24.04 @@ -162,7 +166,9 @@ jobs: Copy-Item opencl.v, convenience.v, ownership.v, program.v, event.v, image.v, svm.v, capabilities.v, external_interop.v, v.mod, VERSION, LICENSE, GENERATOR_COMMIT -Destination $module $include = Join-Path $env:VCPKG_INSTALLATION_ROOT 'installed/x64-windows/include' $lib = Join-Path $env:VCPKG_INSTALLATION_ROOT 'installed/x64-windows/lib' - v -cc msvc -cflags "/I$include" -ldflags "/LIBPATH:$lib" -o "$env:TEMP/opencl-abi-probe.exe" abi/main.c.v + $env:OPENCL_SDK = Join-Path $env:VCPKG_INSTALLATION_ROOT 'installed/x64-windows' + v run setup.vsh --check + v -cc msvc -o "$env:TEMP/opencl-abi-probe.exe" abi/main.c.v required-checks: name: required-checks diff --git a/README.md b/README.md index 64ef9c5..10c6dc1 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,21 @@ The bindings are generated from Khronos' canonical OpenCL XML registry by for this release. `GENERATOR_COMMIT` identifies the exact canonical generator revision from which the published module was synchronized. -Applications must have an OpenCL ICD loader and OpenCL development headers. -On Debian or Ubuntu, a CPU implementation suitable for development and testing -can be installed with: +## One-command setup + +Install the native OpenCL development prerequisites and this V module: ```sh -sudo apt install ocl-icd-opencl-dev pocl-opencl-icd +v run setup.vsh ``` +When running from an installed module, use +`v run ~/.vmodules/antono2/opencl/setup.vsh`. Ubuntu and Debian, Fedora, Arch, +openSUSE, macOS, and Windows are supported. `v run setup.vsh --check` performs +a read-only diagnostic pass. On Windows, the script installs the Khronos loader +and headers through vcpkg; the current GPU vendor driver still supplies the +actual OpenCL implementation. macOS uses its built-in OpenCL framework. + ## Supported toolchains | Platform | V compiler | C compiler | Validation level | From 093f34009c28137d483aa53ec8465e5359dd4fac Mon Sep 17 00:00:00 2001 From: Anton Oreskin Date: Sat, 12 Sep 2026 11:27:38 +0200 Subject: [PATCH 3/4] Assemble Windows OpenCL SDK layout in CI --- .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 94b4a2e..ee2833d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -166,6 +166,9 @@ jobs: Copy-Item opencl.v, convenience.v, ownership.v, program.v, event.v, image.v, svm.v, capabilities.v, external_interop.v, v.mod, VERSION, LICENSE, GENERATOR_COMMIT -Destination $module $include = Join-Path $env:VCPKG_INSTALLATION_ROOT 'installed/x64-windows/include' $lib = Join-Path $env:VCPKG_INSTALLATION_ROOT 'installed/x64-windows/lib' + Copy-Item -Recurse include -Destination $module + New-Item -ItemType Directory -Force (Join-Path $module 'lib') | Out-Null + Copy-Item (Join-Path $lib 'OpenCL.lib') -Destination (Join-Path $module 'lib') $env:OPENCL_SDK = Join-Path $env:VCPKG_INSTALLATION_ROOT 'installed/x64-windows' v run setup.vsh --check v -cc msvc -o "$env:TEMP/opencl-abi-probe.exe" abi/main.c.v From 71edd90ab6660e3ccbd07aa02588876ca2d17fca Mon Sep 17 00:00:00 2001 From: Anton Oreskin Date: Sat, 12 Sep 2026 11:31:23 +0200 Subject: [PATCH 4/4] Use Windows OpenCL headers in CI module --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ee2833d..f625e87 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -166,7 +166,8 @@ jobs: Copy-Item opencl.v, convenience.v, ownership.v, program.v, event.v, image.v, svm.v, capabilities.v, external_interop.v, v.mod, VERSION, LICENSE, GENERATOR_COMMIT -Destination $module $include = Join-Path $env:VCPKG_INSTALLATION_ROOT 'installed/x64-windows/include' $lib = Join-Path $env:VCPKG_INSTALLATION_ROOT 'installed/x64-windows/lib' - Copy-Item -Recurse include -Destination $module + New-Item -ItemType Directory -Force (Join-Path $module 'include') | Out-Null + Copy-Item -Recurse (Join-Path $include 'CL') -Destination (Join-Path $module 'include') New-Item -ItemType Directory -Force (Join-Path $module 'lib') | Out-Null Copy-Item (Join-Path $lib 'OpenCL.lib') -Destination (Join-Path $module 'lib') $env:OPENCL_SDK = Join-Path $env:VCPKG_INSTALLATION_ROOT 'installed/x64-windows'