Skip to content

Commit 42b6362

Browse files
committed
chore(native,libbuilder): build quiche in library-builder, consume prebuilt in mystralnative
1 parent ae7be51 commit 42b6362

4 files changed

Lines changed: 44 additions & 136 deletions

File tree

CMakeLists.txt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -851,19 +851,21 @@ endif()
851851
# ============================================================================
852852
# quiche (QUIC + HTTP/3, for the WebTransport API)
853853
# ============================================================================
854-
# quiche is a Rust library exposing a C API. We vendor the source and build a
855-
# static library (libquiche.a) with `cargo build --release --features ffi`.
856-
# download-deps.mjs clones + builds it. WebTransport is disabled (stubbed) if
857-
# the library is not present, so the build still succeeds without a Rust
858-
# toolchain.
854+
# quiche is a Rust library exposing a C API. The static library (libquiche.a /
855+
# quiche.lib + patched quiche.h, BoringSSL bundled) is built by
856+
# mystralengine/library-builder and downloaded as a prebuilt by
857+
# download-deps.mjs (like libuv/draco/swc) — the engine repo never compiles
858+
# Rust/BoringSSL itself. WebTransport is disabled (stubbed) if the library is
859+
# not present, so the build still succeeds without it.
860+
# Prebuilt layout: quiche/include/quiche.h, quiche/libquiche.a (or quiche.lib)
859861
option(MYSTRAL_USE_QUICHE "Enable QUIC/HTTP3 WebTransport via quiche" ON)
860862
set(QUICHE_DIR ${THIRD_PARTY_DIR}/quiche)
861863
if(MYSTRAL_USE_QUICHE AND EXISTS ${QUICHE_DIR} AND NOT IOS AND NOT ANDROID)
862-
set(QUICHE_INCLUDE_DIR ${QUICHE_DIR}/quiche/include)
864+
set(QUICHE_INCLUDE_DIR ${QUICHE_DIR}/include)
863865
if(WIN32)
864-
set(QUICHE_LIB_PATH ${QUICHE_DIR}/target/release/quiche.lib)
866+
set(QUICHE_LIB_PATH ${QUICHE_DIR}/quiche.lib)
865867
else()
866-
set(QUICHE_LIB_PATH ${QUICHE_DIR}/target/release/libquiche.a)
868+
set(QUICHE_LIB_PATH ${QUICHE_DIR}/libquiche.a)
867869
endif()
868870

869871
if(EXISTS ${QUICHE_LIB_PATH} AND EXISTS ${QUICHE_INCLUDE_DIR}/quiche.h)

docs/docs/guides/webtransport.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ WebTransport is implemented natively on top of [Cloudflare quiche](https://githu
1313

1414
- WebTransport is only available in builds compiled **with quiche**
1515
(`MYSTRAL_HAS_QUICHE`). Run `node scripts/download-deps.mjs --only quiche` to
16-
fetch and build it (needs a Rust toolchain + Go + CMake for BoringSSL). If
17-
quiche is not present, `new WebTransport(...)` rejects its `ready`/`closed`
16+
fetch the **prebuilt** static library (built per-platform by
17+
[mystralengine/library-builder](https://github.com/mystralengine/library-builder),
18+
the same place Skia/libuv/Draco come from — no Rust toolchain needed locally).
19+
If quiche is not present, `new WebTransport(...)` rejects its `ready`/`closed`
1820
promises instead of connecting.
1921
- The server URL must use `https://` and an explicit port, e.g.
2022
`https://example.com:4433/path`.
@@ -69,7 +71,7 @@ supporting `getReader().read()` and `getWriter().write()/close()/abort()`.
6971
WebTransport `0x41` / `0x54` signal framing.
7072
- WebTransport SETTINGS (`WT_MAX_SESSIONS`, etc.) are advertised via a small FFI
7173
shim added to quiche (`quiche_h3_config_set_additional_settings`), applied as a
72-
patch during `download-deps`.
74+
patch when library-builder compiles quiche (`patches/quiche-webtransport-ffi.patch`).
7375

7476
## Testing
7577

scripts/download-deps.mjs

Lines changed: 29 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,36 @@ const DEPS = {
153153
extractTo: 'quickjs',
154154
},
155155
quiche: {
156-
// Cloudflare quiche - QUIC + HTTP/3 (used by the WebTransport API).
157-
// Built from source: git clone --recursive (BoringSSL submodule) + a small
158-
// FFI patch (exposes set_additional_settings for WebTransport SETTINGS) +
159-
// `cargo build --release --features ffi`. Requires a Rust toolchain, cmake,
160-
// and Go (for BoringSSL). Skipped gracefully if those are missing — the C++
161-
// build then compiles a WebTransport stub.
162-
version: '0.24.6',
163-
getUrl: () => null, // special handling below (git clone, not an archive)
156+
// Cloudflare quiche - QUIC + HTTP/3 (native backend for the WebTransport API).
157+
// Prebuilt static libs (libquiche.a / quiche.lib + patched quiche.h, BoringSSL
158+
// bundled) come from mystralengine/library-builder, exactly like libuv/draco/swc.
159+
// The library is built there (build-quiche.py + build-quiche.yml) so the engine
160+
// repo never compiles Rust/BoringSSL itself. If no prebuilt exists for this
161+
// platform/arch, the C++ build compiles a WebTransport stub (MYSTRAL_HAS_QUICHE off).
162+
// https://github.com/mystralengine/library-builder/releases
163+
version: 'quiche-0.24.6-1',
164+
getUrl: () => {
165+
const baseUrl = 'https://github.com/mystralengine/library-builder/releases/download/quiche-0.24.6-1';
166+
if (platformName === 'macos') {
167+
const arch = ARCH === 'arm64' ? 'arm64' : 'x86_64';
168+
return `${baseUrl}/quiche-mac-${arch}.zip`;
169+
} else if (platformName === 'linux') {
170+
if (ARCH !== 'x64') {
171+
console.warn(`quiche prebuilts not available for ${platformName}-${archName}`);
172+
return null;
173+
}
174+
return `${baseUrl}/quiche-linux-x64.zip`;
175+
} else if (platformName === 'windows') {
176+
if (ARCH !== 'x64') {
177+
console.warn(`quiche prebuilts not available for ${platformName}-${archName}`);
178+
return null;
179+
}
180+
return `${baseUrl}/quiche-win-x64.zip`;
181+
}
182+
console.warn(`quiche prebuilts not available for ${platformName}-${archName}`);
183+
return null;
184+
},
164185
extractTo: 'quiche',
165-
repo: 'https://github.com/cloudflare/quiche.git',
166186
},
167187
stb: {
168188
// stb single-header libraries from nothings/stb
@@ -572,69 +592,6 @@ async function downloadDep(name) {
572592
}
573593
}
574594

575-
// Special handling for quiche (git clone --recursive + patch + cargo build)
576-
if (name === 'quiche' && dep.repo) {
577-
const libRel = PLATFORM === 'win32' ? 'target/release/quiche.lib' : 'target/release/libquiche.a';
578-
const libPath = join(destDir, libRel);
579-
if (existsSync(libPath) && !process.argv.includes('--force')) {
580-
console.log(`${name} already built at ${libPath}`);
581-
console.log('Skipping (use --force to rebuild)');
582-
return true;
583-
}
584-
585-
// Verify the toolchain is available; quiche needs cargo + Go (+ cmake) to
586-
// build BoringSSL. If absent, skip — WebTransport compiles as a stub.
587-
const haveCargo = (() => {
588-
try { execSync('cargo --version', { stdio: 'ignore' }); return true; } catch { return false; }
589-
})();
590-
if (!haveCargo) {
591-
console.warn(`Skipping ${name}: cargo (Rust toolchain) not found. WebTransport will be disabled.`);
592-
return false;
593-
}
594-
595-
try {
596-
if (!existsSync(join(destDir, '.git'))) {
597-
if (existsSync(destDir)) rmSync(destDir, { recursive: true });
598-
console.log(`Cloning quiche ${dep.version} (with BoringSSL submodule)...`);
599-
execSync(
600-
`git clone --recursive --depth 1 --branch ${dep.version} ${dep.repo} "${destDir}"`,
601-
{ stdio: 'inherit' }
602-
);
603-
}
604-
605-
// Apply the WebTransport FFI patch (idempotent: git apply --check first).
606-
const patchPath = join(__dirname, 'patches', 'quiche-webtransport-ffi.patch');
607-
if (existsSync(patchPath)) {
608-
const alreadyApplied = (() => {
609-
try { execSync(`git -C "${destDir}" apply --reverse --check "${patchPath}"`, { stdio: 'ignore' }); return true; }
610-
catch { return false; }
611-
})();
612-
if (!alreadyApplied) {
613-
console.log('Applying quiche WebTransport FFI patch...');
614-
execSync(`git -C "${destDir}" apply "${patchPath}"`, { stdio: 'inherit' });
615-
} else {
616-
console.log('quiche WebTransport FFI patch already applied');
617-
}
618-
}
619-
620-
console.log('Building quiche (cargo build --release --features ffi)...');
621-
execSync('cargo build --release --package quiche --features ffi', {
622-
cwd: destDir,
623-
stdio: 'inherit',
624-
});
625-
626-
if (existsSync(libPath)) {
627-
console.log(`Successfully built ${name}: ${libPath}`);
628-
return true;
629-
}
630-
console.error(`quiche build did not produce ${libPath}`);
631-
return false;
632-
} catch (error) {
633-
console.error(`Failed to build ${name}:`, error.message);
634-
return false;
635-
}
636-
}
637-
638595
// Special handling for cgltf (single header with specific rawUrl)
639596
if (name === 'cgltf' && dep.rawUrl) {
640597
if (existsSync(destDir)) {

scripts/patches/quiche-webtransport-ffi.patch

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)