Files
luma-home/tools/webos-runtime.mjs
T
Kaloyan DanchevandClaude Opus 4.6 cbea5a322f
CI / Identify a merged version PR (push) Canceled after 0s
CI / Rust checks, rendering, and native package (push) Canceled after 0s
CI / Publish release and Homebrew feed (push) Canceled after 0s
Release PR / Maintain Version Packages PR (push) Canceled after 0s
Merge Luma launcher fork into monorepo
Move trampoline files (boot-hook, watcher, overlay) into trampoline/
subdirectory. Add upstream Luma v2.3.1 source at repo root with our
additions:

- Page::Ha (4th nav tab) with placeholder empty state
- HA tab config schema and default entity mapping (ha-home/)
- Nav keys renamed: "home" → "start", new "ha" tab between Apps and Settings
- All state.rs/view.rs/main.rs/tests.rs updated for 4-tab navigation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-10-24 11:52:55 +03:00

97 lines
3.8 KiB
JavaScript

// SDL in the NDK is for linking, not TV display: its Wayland backend is disabled.
import fs from 'node:fs/promises';
import path from 'node:path';
import { createHash } from 'node:crypto';
import { spawnSync } from 'node:child_process';
import { pathToFileURL } from 'node:url';
const root = path.resolve(import.meta.dirname, '..');
const directory = path.join(root, '.build/sdl-webos');
const release = 'release-2.30.12-webos.5';
const filename = 'SDL2-2.30.12-webos.tar.gz';
const archiveHash = '4ad566453d113bdd9ee96878176b97d28d9fa70503a62d83d55a351545abb334';
const libraryHash = 'f564f7da624cec47168300d017f3ec822f41b5096f0ce1c96873eecd8614d446';
const hash = (bytes) => createHash('sha256').update(bytes).digest('hex');
export function verifyWebosSdl(bytes) {
if (
bytes.length < 52 ||
bytes.subarray(0, 4).toString('hex') !== '7f454c46' ||
bytes[4] !== 1 ||
bytes[5] !== 1 ||
bytes.readUInt16LE(18) !== 40 ||
bytes.readUInt16LE(16) !== 3 ||
(bytes.readUInt32LE(36) & 0x400) !== 0
) {
throw new Error('SDL runtime must be an ARM soft-float shared library.');
}
// These are compiled backend strings, not merely exported SDL_webOS API stubs.
if (
!bytes.includes(Buffer.from('SDL Wayland video driver\0')) ||
!bytes.includes(Buffer.from('APPID environment variable is not set\0'))
) {
throw new Error('SDL has no webOS Wayland video backend. Do not package the SDK stub SDL.');
}
}
export async function prepareWebosRuntime() {
await fs.mkdir(directory, { recursive: true });
const archive = path.join(directory, filename);
let bytes;
try {
bytes = await fs.readFile(archive);
} catch (error) {
if (error.code !== 'ENOENT') throw error;
console.log(`Downloading SDL-webOS ${release} (standard SDL ABI).`);
const url = `https://github.com/webosbrew/SDL-webOS/releases/download/${release}/${filename}`;
const response = await fetch(url, { signal: AbortSignal.timeout(60000) });
if (!response.ok) throw new Error(`SDL-webOS download failed: ${response.status}`);
bytes = Buffer.from(await response.arrayBuffer());
if (hash(bytes) !== archiveHash) throw new Error('SDL-webOS archive checksum mismatch.');
await fs.writeFile(archive, bytes);
}
if (hash(bytes) !== archiveHash) throw new Error('SDL-webOS archive checksum mismatch.');
const library = path.join(directory, 'lib/libSDL2-2.0.so.0');
let current;
try {
current = await fs.readFile(library);
} catch (error) {
if (error.code !== 'ENOENT') throw error;
}
if (!current || hash(current) !== libraryHash) {
const result = spawnSync('tar', ['-xzf', archive, '-C', directory], {
stdio: 'inherit',
timeout: 60000,
});
if (result.error) throw result.error;
if (result.status !== 0) throw new Error('SDL-webOS extraction failed.');
current = await fs.readFile(library);
}
if (hash(current) !== libraryHash) throw new Error('SDL-webOS library checksum mismatch.');
verifyWebosSdl(current);
// Upstream metadata embeds /usr/local and an rpath. Generate relocatable build-host
// lookup metadata instead; the TV executable keeps only its $ORIGIN/lib rpath.
const pkgconfig = path.join(directory, 'pkgconfig');
await fs.mkdir(pkgconfig, { recursive: true });
await fs.writeFile(
path.join(pkgconfig, 'sdl2.pc'),
`prefix=${directory}
libdir=\${prefix}/lib
includedir=\${prefix}/include/SDL2
Name: sdl2
Description: SDL-webOS with the Wayland/webOS backend and standard SDL ABI
Version: 2.30.12
Libs: -L\${libdir} -lSDL2
Cflags: -I\${includedir} -D_REENTRANT
`,
);
console.log(`Verified SDL-webOS ${release}: ARM soft-float, Wayland/webOS backend.`);
return directory;
}
if (process.argv[1] && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
await prepareWebosRuntime();
}