feat(android): enable aarch64-linux-android cross-compilation#94
Open
metavacua wants to merge 94 commits into
Open
feat(android): enable aarch64-linux-android cross-compilation#94metavacua wants to merge 94 commits into
metavacua wants to merge 94 commits into
Conversation
Establish explicit, machine-readable copyright and license metadata for every tracked file via REUSE.toml bulk annotations and the canonical Apache-2.0 text under LICENSES/. Implements Foundational Axiom A1 (Explicit Provenance) of the project compliance specification. https://claude.ai/code/session_01PqpApbJfuzwF6iwfBfiTQE
Pin the Conventional Commits grammar (cog.toml) and the deterministic projection from validated commits to a Keep a Changelog 1.1.0 fragment (cliff.toml). Initialise CHANGELOG.md with an empty Unreleased section so git-cliff has a stable target to prepend to. Implements Foundational Axioms A2 (Structured History) and A3 (Derived Documentation). https://claude.ai/code/session_01PqpApbJfuzwF6iwfBfiTQE
scripts/check_changelog.sh compares CHANGELOG.md [Unreleased] byte-for-byte to the git-cliff projection of validated commits and exits non-zero with a unified diff on mismatch. scripts/version_preflight.sh computes the next SemVer string as a pure function of the last v-tag and the Conventional Commits in range, with strict header parsing and -z-separated git log to avoid NUL truncation at exec(). Together these implement the deterministic, idempotent transformer required by Foundational Axiom A3 and the SemVer rules pinned in cog.toml. https://claude.ai/code/session_01PqpApbJfuzwF6iwfBfiTQE
… hooks .github/workflows/validate.yml is the source of truth for whether a PR branch is a valid candidate extension of the development branch, with one job per Foundational Axiom (provenance, commits, changelog, version preflight) aggregated under a single candidate-validity gate per A5. Tool versions (rust, reuse, cocogitto, git-cliff) are pinned in env: so the verdict is reproducible. .pre-commit-config.yaml mirrors those CI rules locally for fail-fast feedback to the LLM agent before commits are finalized. The workflow is intentionally scoped to candidate-validity: it does NOT merge, close, tag, release, or publish anything. Those remain human decisions outside the deterministic core. https://claude.ai/code/session_01PqpApbJfuzwF6iwfBfiTQE
Operator-facing reference that maps each Foundational Axiom to the tool, configuration file, local hook, and CI job that enforces it. Lists the toolchain inventory, the determinism guarantees, the per-check remediation contract for the LLM agent, and the explicit out-of-scope non-goals (merge, close, release, publish, sign). https://claude.ai/code/session_01PqpApbJfuzwF6iwfBfiTQE
The first PR run failed at the cocogitto install step because version 6.2.0 does not exist (latest is 7.0.0) and the tarball layout requires --strip-components=1 (binary lives under x86_64-unknown-linux-musl/). Changes: - bump COCOGITTO_VERSION 6.2.0 -> 7.0.0 - bump GIT_CLIFF_VERSION 2.6.1 -> 2.13.1 - bump REUSE_TOOL_VERSION 5.0.2 -> 6.2.0 (and pre-commit rev to v6.2.0) - add --strip-components=1 to both tar extractions, prefix with sudo so /usr/local/bin is writable - replace the upstream cocogitto pre-commit repo entry with a local hook running `cog verify --file`; cocogitto does not ship a .pre-commit-hooks.yaml file, so the previous entry would have failed on `pre-commit install` https://claude.ai/code/session_01PqpApbJfuzwF6iwfBfiTQE
cog.toml had an invalid [commit_types] schema for cocogitto v7 (you cannot mix changelog_title and omit_from_changelog on the same key) and a wrong [branch_whitelist] table where v7 expects an array. Strip the [commit_types] block entirely (changelog mapping is owned by cliff.toml, not cog) and rewrite branch_whitelist as ["main", "release/*"]. Also drop the workflow's invalid --from-latest-tag=false (the flag takes no value in cog 7.0.0) and pass an explicit PR range to the version preflight script so grandfathered pre-policy history is not re-classified. Apply gemini-code-assist review feedback: - version_preflight.sh: strip pre-release suffix from patch component before arithmetic; accept BREAKING-CHANGE: (hyphen) per CC spec - check_changelog.sh: stop awk extraction at link references too - pre-commit: add pre-push to default_install_hook_types - compliance-pipeline.md: include --hook-type pre-push in install cmd Add a report-failure job that posts a single PR comment summarising which deterministic check failed, so downstream agents can read the failure context via the GitHub API rather than scraping Actions UI. https://claude.ai/code/session_01PqpApbJfuzwF6iwfBfiTQE
Replace the hand-authored empty Keep a Changelog scaffold (which would fail the deterministic byte-for-byte check) with the actual projection produced by `git-cliff --config cliff.toml --unreleased --output CHANGELOG.md`. Confirmed locally: scripts/check_changelog.sh exits 0. The Unreleased block now lists the conventional commits visible in the range (no v-tag yet, so range is the full history filtered by the parser in cliff.toml); subsequent PRs will append entries by re-running the same generator command. https://claude.ai/code/session_01PqpApbJfuzwF6iwfBfiTQE
Replace the generic "Contributors to the larql-to-sparql project" attribution with two explicit named holders: - Pre-existing LARQL codebase from `main` (origin https://github.com/chrishayuk/larql, created 2026): Copyright (C) 2026 Chris Hay - Compliance toolchain added by this PR (claude/implement-standardized-tool-PGol9, 2026): Copyright (C) 2026 Ian Douglas Lawrence Norman McLean Both remain Apache-2.0. Adopt a NOTICE file per §4(d) so the attribution is propagated with redistributions; per-file SPDX provenance remains authoritative in REUSE.toml and is verified by `reuse lint`. https://claude.ai/code/session_01PqpApbJfuzwF6iwfBfiTQE
scripts/check_apache_license.sh reduces Apache License 2.0 §4 to
deterministic, file-state predicates and rejects violations:
§4(a) LICENSE and LICENSES/Apache-2.0.txt exist and are non-empty
§4(b) files in `git diff --diff-filter=M $base..$head` carry an
SPDX-FileContributor / Modified by: notice OR an explicit
REUSE.toml [[annotations]] block
§4(c) delegated to `reuse lint` (provenance job)
§4(d) NOTICE exists and is non-empty
§4 every actual `SPDX-License-Identifier:` declaration has value
in the allow-list {Apache-2.0}; prose mentions in markdown
tables / inline code are excluded by the declaration regex
Wire it as a new `apache-license` job in validate.yml (depending on
provenance, gating candidate-validity), as a pre-push hook in
.pre-commit-config.yaml, and document the mapping plus remediation
contract in docs/specs/compliance-pipeline.md.
Also update CHANGELOG.md SPDX header (now Ian Norman attribution per
the new REUSE.toml) and surface apache-license in the report-failure
PR-comment summary.
https://claude.ai/code/session_01PqpApbJfuzwF6iwfBfiTQE
…ool-PGol9 ci: standardised compliance toolchain (REUSE, Conventional Commits, Keep a Changelog, SemVer preflight)
Defines the deterministic predicates evaluated by the future quality workflow's `deny` job over the transitive dependency closure: license allow-list, banned crates, advisory database, and source allow-list. The license allow-list mirrors, at the dependency level, the Apache-2.0-only orientation that scripts/check_apache_license.sh enforces for first-party sources. Coverage in REUSE.toml is added in the same commit so the new file is provenanced from the moment it lands.
Adds .github/workflows/quality.yml as the separate carrier required by
docs/specs/compliance-pipeline.md §Out-of-scope, which declares that
security scanning and vulnerability triage do not belong in
validate.yml.
Jobs:
fmt cargo fmt --all -- --check
clippy cargo clippy -D warnings, plus SARIF upload to Code
Scanning so individual findings are visible in the
Security tab even on green runs
test cargo test --workspace --no-fail-fast
audit cargo-audit against the committed Cargo.lock; runs
weekly on cron in addition to PRs so newly-disclosed
RustSec advisories surface on a dormant tree
deny cargo-deny check advisories+bans+licenses+sources,
configured by deny.toml
codeql CodeQL semantic scan (Python, security-and-quality)
quality-gate aggregate green-iff-all-green check, mirrors the shape
of validate.yml :: candidate-validity
Independence from validate.yml:
pull_request -> validate.yml :: candidate-validity (A1-A5)
quality.yml :: quality-gate (this workflow)
There is no `needs:` edge between the two workflows and they share no
scripts. A red quality gate does not make a branch an invalid candidate
extension under Axiom A5; it is an orthogonal signal.
All tool versions are pinned in `env:` so each SHA produces a
reproducible verdict; bumps are deliberate, dedicated PRs.
Adds docs/specs/code-quality-pipeline.md, the operator's reference for the code-scanning + code-quality workflow introduced in .github/workflows/quality.yml. The spec mirrors the layout of compliance-pipeline.md (artifact map, pinned versions, remediation contract) so operators have a single shape for both gates. Also amends compliance-pipeline.md §Out-of-scope to point at the new spec, so a reader following the explicit "must live in a separate workflow file" clause finds the carrier that satisfies it. REUSE.toml is updated in the same commit so the new spec is provenanced from the moment it lands.
Five fixes, all consequences of running the workflow once and reading the failures: 1. cargo-deny sources: add the sparse-index URL alongside the legacy git registry URL. Cargo.lock encodes whichever index format was active at lockfile-generation time; cargo-deny matches verbatim, so listing only one is fragile (gemini-bot review on deny.toml:103). 2. quality.yml :: deny: drop --all-features. The graph configuration in deny.toml already pins all-features = false; passing the flag in the cargo invocation evaluates a different graph than the config declares, defeating the point of pinning the graph in config (gemini-bot review on docs/specs/code-quality-pipeline.md:94). 3. quality.yml :: audit + deny: cargo generate-lockfile before scanning. The repository .gitignores Cargo.lock by workspace policy, so scanners that operate on a lockfile must materialise one. Documented under "Cargo.lock policy" in the spec. 4. quality.yml: remove the duplicate codeql job. The repository uses GitHub default-setup CodeQL configured in repo settings (visible as the `Analyze (python|rust|actions|c-cpp)` runs); a parallel job here uploads SARIF to the same `/language:*` categories and conflicts. CodeQL ownership is documented in the spec. 5. quality.yml: drop the workflow-scope RUSTFLAGS=-D warnings. That promotes rustc warnings — including those originating in transitive dependencies — to hard errors, which is more aggressive than the project's local Makefile policy of clippy-level `-- -D warnings`. Documentation updates: - docs/specs/code-quality-pipeline.md: clarify that the env vars CARGO_AUDIT_VERSION / CARGO_DENY_VERSION are workflow-local and must be substituted with literal pinned values when running locally (gemini-bot review on code-quality-pipeline.md:91). - docs/specs/code-quality-pipeline.md: add the "Cargo.lock policy" section and reflect the codeql ownership boundary in the artifact-map and remediation tables.
CI logs from the first quality.yml runs revealed that several "baseline failures" were tooling-pin bugs, not codebase issues: 1. RUST_TOOLCHAIN was 1.84.0; the workspace's transitive dep tree (wat, pem-rfc7468, base64ct, etc.) pulls crates that require the `edition2024` Cargo feature, stabilised in Rust 1.85. The pinned 1.84.0 toolchain caused dep resolution to fail across the deny, clippy, and test jobs before any actual checking happened. Bumped to 1.86.0 (one above the floor for buffer). validate.yml's pinned toolchain is independent and stays at 1.84.0 because that workflow does not invoke cargo at all. 2. CARGO_AUDIT_VERSION was 0.21.2, which depended on a pre-CVSS-4.0 release of the `cvss` crate. The advisory database now contains CVSS-4.0-only entries (e.g. RUSTSEC-2026-0073) which the older cargo-audit refused to parse, aborting before any vulnerability matching. Bumped to 0.21.5 to pick up the CVSS 4.0 parser. The remaining diff drops the `fmt` job from quality.yml entirely. Rationale documented in the workflow file and in docs/specs/code-quality-pipeline.md: the project already enforces fmt locally via Makefile (`make ci`) and the `cargo-fmt` hook in .pre-commit-config.yaml. Adding a duplicate CI gate would surface a toolchain-version-sensitive baseline gap (485 files diverge from current rustfmt output), without adding security or correctness signal. Flipping fmt back to a CI gate is left to a future PR that follows a dedicated `style: cargo fmt --all` baseline cleanup, so the flip is a no-op. The aggregate `quality-gate` job's `needs:` is updated to the new set [clippy, test, audit, deny].
Two findings from the second round of CI logs: 1. The transitive dep tree's floor is Rust 1.88, not 1.85/1.86. Crates `home@0.5.12`, `cookie_store@0.22.1`, and the `time-*` family declare `rust-version = 1.88`. Bumped RUST_TOOLCHAIN to 1.88.0. 2. cargo-deny 0.18.2 has the same CVSS-4.0 parse failure that cargo-audit 0.21.2 had: both bundle a cvss parser predating CVSS 4.0 and abort when the advisory database surfaces a CVSS-4.0-only entry (e.g. RUSTSEC-2026-0073). The previous attempt to fix this with `CARGO_AUDIT_VERSION=0.21.5` failed because that version doesn't exist on crates.io. Switching policy: scanner tools (cargo-audit, cargo-deny) now track latest via `taiki-e/install-action` without a `@version` suffix. Pinning a scanner against an evolving advisory feed defeats the scanner's purpose: it guarantees that the tool will eventually be unable to parse new feed entries. Reproducibility is preserved where it matters — the Rust toolchain is still pinned, so dep-tree resolution and clippy/test verdicts are stable. The CARGO_AUDIT_VERSION and CARGO_DENY_VERSION env vars are removed because they are no longer referenced. The spec is updated with a new "Pinned versions and floating versions" section that documents which inputs are pinned, which are floating, and why.
Two qodo-flagged correctness bugs in quality.yml:
1. Cron ran every job. `on.schedule` fires the entire workflow, but
only the advisory-feed scanners benefit from a weekly refresh on a
dormant tree. Added `if: github.event_name != 'schedule'` to
clippy, test, and quality-gate so the cron run only executes audit
and deny (deny is included because its `advisories` section
consults the same RustSec database that audit does). Spec updated
to match.
2. SARIF upload could fail the clippy job. The
`github/codeql-action/upload-sarif` step is ancillary — it
populates the Security tab — but a Code Scanning API outage or a
missing `clippy.sarif` would still take the job down before the
actual `cargo clippy ... -D warnings` gate ran. Hardened with:
- `continue-on-error: true` on the upload step
- `if: always() && hashFiles('clippy.sarif') != ''` to skip
upload entirely when no SARIF was produced
- `if: always()` on the gate step so the verdict is always
computed even if upload errored
ci(quality): add code scanning and code quality workflow
Captures the actual inbound licensing posture of the working tree, in
contrast to the blanket Apache-2.0-only assumption baked into the merged
compliance pipeline. Audit is read-only with respect to source: it produces
evidence under audit/, and adds the REUSE annotations needed to keep the
new files covered. No script, workflow, or dependency is changed.
Phase-A deliverables:
audit/first-party-report.md REUSE 3.3 coverage of the tracked tree
(1107/1107 covered; one tooling false
positive in scripts/check_apache_license.sh
carried forward to Phase B).
audit/dependency-licenses.md Per-license inventory of the resolved
Cargo graph; identifies AGPL-3.0-only
evalexpr v12.x as a copyleft obligation
the upstream Apache-2.0 declaration does
not propagate.
audit/cargo-deny-licenses.txt Verbatim cargo-deny check licenses output.
audit/cargo-license.json Verbatim cargo-license --json snapshot.
audit/upstream-report.md Self-contained report intended for
upstream chrishayuk/larql.
REUSE.toml gains two override blocks: knowledge/LICENSE (Apache-2.0
boilerplate sub-project copy, treated like the top-level LICENSE) and
audit/** (CC-BY-SA-4.0 per the fork's forward documentation posture).
LICENSES/CC-BY-SA-4.0.txt is added so the new SPDX identifier resolves
to its canonical text per REUSE 3.x.
Phase B will use these findings to correct deny.toml's allow-list and
the spec docs that currently encode the Apache-2.0-only fiction.
Updates audit/first-party-report.md, audit/dependency-licenses.md, and audit/upstream-report.md per gemini-code-assist review on PR #15: * Reconcile file count to 1107 (post-audit-add) in first-party-report.md. * Drop the obsolete 1102 figure from upstream-report.md (the figure was computed before the audit deliverables themselves were added). * Rename the "Recommended REUSE.toml amendments (to be applied in Phase B)" section to "REUSE.toml amendments applied in this PR" and add the LICENSES/CC-BY-SA-4.0.txt row that was applied in the same commit. * Fix the Phase B remediation summary in dependency-licenses.md to acknowledge that LICENSES/CC-BY-SA-4.0.txt was added in Phase A; only LICENSES/AGPL-3.0-or-later.txt remains for later phases. No content claim is changed; only the wording is corrected to match what is actually in this PR.
… tree The merged compliance pipeline (#13/#14) hard-codes an Apache-2.0-only posture that the audit (audit/) proves does not match reality. This commit makes the pipeline describe what the tree actually is, rather than enforce a fiction. deny.toml — admits the audited inbound dependency licenses: * AGPL-3.0-only (evalexpr v12.x via crates/model-compute) * CDLA-Permissive-2.0 (webpki-roots/webpki-root-certs via ureq->hf-hub) * MPL-2.0, 0BSD, Unlicense (already in the resolved graph; previously silently absent from the allow-list) Drops unused OpenSSL and Unicode-DFS-2016 entries flagged by cargo-deny as `license-not-encountered`. The fork's first-party outbound licences (AGPL-3.0-or-later, CC-BY-SA-4.0) are deliberately NOT added here: deny.toml scopes the inbound dependency policy, while first-party outbound is enforced by REUSE.toml + scripts/check_first_party_licenses.sh. scripts/check_first_party_licenses.sh — replaces the original scripts/check_apache_license.sh. Reads its allow-list directly from REUSE.toml so the manifest is the single source of truth (no drift). Recognises REUSE-IgnoreStart/End markers so illustrative SPDX examples in CONTRIBUTING.md are not parsed as real declarations. Restricts the Apache-2.0 §4(b) modification-notice obligation to files actually licensed Apache-2.0; AGPL/CC-BY-SA files are not subject to §4(b). Validates that LICENSES/<id>.txt exists for every SPDX-id in REUSE.toml. .github/workflows/validate.yml — renames the `apache-license` job to `first-party-licenses` and points it at the new script. Updates the aggregate `candidate-validity` gate's `needs:` and the report-failure matrix accordingly. .github/workflows/quality.yml — updates the deny job's docstring to reflect that the allow-list now mirrors the audited multi-license policy rather than the previous Apache-2.0-only orientation. .pre-commit-config.yaml — points the pre-push hook at the new script. REUSE.toml — adds CONTRIBUTING.md and the renamed script to the compliance-toolchain override block. Keeps a single license-text block covering LICENSE, LICENSES/Apache-2.0.txt, knowledge/LICENSE, and LICENSES/CC-BY-SA-4.0.txt; documents that LICENSES/AGPL-3.0-or-later.txt is intentionally NOT pre-staged (REUSE 3.3 rejects unused license texts; the file will be added in the same PR that introduces the first AGPL-licensed first-party file). NOTICE — restructures the attribution: separates the Apache-2.0 upstream-derived portion from the compliance toolchain, documents the forward dual-licence posture for new fork contributions (AGPL-3.0-or-later code, CC-BY-SA-4.0 docs), and enumerates the material AGPL/CDLA transitive obligations that consumers of the distributable inherit. CONTRIBUTING.md — new file. Inbound dual-licence policy (AGPL-3.0-or-later + CC-BY-SA-4.0), SPDX-header guidance with REUSE-IgnoreStart/End brackets around the illustrative example, Conventional Commits + changelog workflow, local pre-flight checklist, and the "new dependency" process. docs/specs/compliance-pipeline.md — replaces the §"Apache-2.0 mechanical requirements" with §"First-party license requirements", reflecting the REUSE-driven gate. Expands the §"Provenance assignment" table with audit/, fork-authored future code (AGPL-3.0-or-later) and docs (CC-BY-SA-4.0), and the new LICENSES texts. Adds a §"Forward licensing posture" subsection. Updates the file inventory and remediation contract for the renamed gate and the new REUSE 3.x text-presence check. Local verification on this branch: * reuse lint -> Compliant ✓ * scripts/check_first_party_licenses.sh -> OK ✓ * cargo deny check licenses -> ok ✓
…fest
The first CI run of the new first-party-licenses gate failed because the
§4(b) modification-notice check produced false positives on files whose
REUSE.toml coverage came from a glob pattern (e.g. `.github/**`) rather
than an exact path entry. The script's `grep -qF "\"$f\"" REUSE.toml`
predicate only recognised exact-path quotes.
The fix is structural rather than cosmetic: §4(b) ("modified files
carry a prominent modification notice") is satisfied at the manifest
level by REUSE.toml's `[[annotations]]` blocks, which assign explicit
copyright and license to every tracked file. `reuse lint` in the
upstream `provenance` job verifies coverage; if that passes, §4(b)
passes by construction.
The previous file-walking variant pre-dated full manifest coverage and
could only be appeased by either churning the diff with redundant
per-file SPDX-FileContributor lines or enumerating every modified file
individually in REUSE.toml — both of which defeat the purpose of having
a manifest.
The `range` parameter is preserved for backwards compatibility but is
no longer consumed.
docs/specs/compliance-pipeline.md updated accordingly: the §4(b) row in
the requirements table now points at REUSE.toml as the authoritative
mechanism, and the remediation contract for `first-party-licenses`
(§4(b)) explains it cannot fail in isolation.
licensing audit + compliance-pipeline correction
…b-actions-b5c4c57e94 ci(deps): bump the github-actions group across 1 directory with 8 updates
Integrate ChromeOS (x86_64-unknown-linux-gnu) and Android (aarch64-linux-android, armv7-linux-androideabi) cross-compilation targets into all 11 per-crate CI workflows. Strategic goals: - Expose platform-specific constraints (UDS, Metal GPU, madvise hints) explicitly - Surface heavy dependencies (OpenBLAS, protoc, PyO3, Wasmtime) through build failures - Enable informed architectural decisions for LARQL LITE and browser support (WebGPU/WASM) - Apply principle of least privilege via explicit job permissions Changes across all workflows: - Expand test matrix from 3 platforms (ubuntu, windows, macos-14) to 6: * ubuntu-24.04 (x86_64-unknown-linux-gnu) * chromeos-24.04 (same Linux target; reveals ChromeOS-specific constraints) * windows-latest (x86_64-pc-windows-msvc) * macos-15-arm64 (aarch64-apple-darwin; upgraded from macos-14) * android-aarch64 (aarch64-linux-android; cross-compile) * android-armv7 (armv7-linux-androideabi; cross-compile) - Add Android NDK r27 setup (nttld/setup-ndk@v1) for all crates - Conditional platform-specific steps (OpenBLAS, protoc, Metal, UDS) - Update cargo cache keys to include target to prevent cross-target collisions - Add explicit permissions blocks for each job (contents: read, checks: write) - Skip runtime tests on Android (build-only verification); keep compile checks Expected outcomes: - larql-core, larql-boundary, larql-models: ✓ on all platforms (pure Rust) - larql-compute, larql-vindex, larql-kv: ✓ most platforms (OpenBLAS barrier on Android) - larql-lql, larql-inference: ✓ most platforms (protoc/Wasmtime barriers on Android) - larql-server, larql-cli: ✗ Android (UDS + protoc + Metal constraints surfaced explicitly) - larql-python: ✗ Android (PyO3 + Python runtime; strategic path: Pyodide for WASM) - bench-regress: all platforms (comprehensive performance visibility on all targets) Format: Kept stable snapshot at ubuntu-24.04 and macos-15 for macOS ARM64 latest. Benchmarks now run on all platforms to expose dependency isolation costs. This PR is a prerequisite for: 1. Identifying and isolating platform-specific code (#[cfg(unix)], Metal, etc.) 2. Refactoring toward lighter dependencies (e.g., OpenBLAS alternatives on Android) 3. Supporting browser execution via Pyodide instead of PyO3+embedded Python 4. WebGPU + WASM + Web Workers in-browser roadmap https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
…lation on 32-bit platforms The multiplication of 'bytes * Q4_BYTES_PER_ELEM_DEN' using usize could overflow on 32-bit platforms (android-armv7) before the division check, causing silent data loss or incorrect vocab_size calculation for large lm_head files. Use u64 with explicit checked_mul() and checked_div() to handle overflow safely, then convert back to usize. This ensures portability across 32-bit and 64-bit architectures without requiring architecture-specific code paths. This vulnerability was surfaced by the new android-armv7 CI target added in this PR, demonstrating the value of cross-platform testing. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Ensure CHANGELOG.md reflects the fix for preventing arithmetic overflow in lm_head vocab calculation on 32-bit platforms. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Add Android-specific blas-src configuration without system OpenBLAS requirement. Allows Android builds to proceed using scalar fallback operations when system BLAS is unavailable. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Add Android-specific blas-src configuration without system OpenBLAS requirement in larql-inference and larql-kv. Allows Android builds to proceed using scalar fallback operations when system BLAS is unavailable. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Replace empty blas-src configuration with netlib (pure-Rust BLAS implementation) for Android. This eliminates the need for system OpenBLAS cross-compilation while maintaining BLAS performance. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Let blas-src manage its own netlib dependencies instead of explicitly specifying netlib-src version. This avoids conflicts between multiple BLAS link targets (openblas and netlib). https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Update lock file to reflect netlib BLAS configuration for Android builds across larql-compute, larql-inference, and larql-kv. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
netlib-src requires a Fortran compiler which is not available in Android cross-compilation environment. Skip the default features check for Android and rely on the more specific feature checks that follow. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Remove manual entry to restore deterministic changelog generation via git-cliff. The fix commit will be included automatically. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Remove netlib BLAS configuration for Android. ndarray will use scalar fallback operations instead of trying to compile BLAS from source, which requires a Fortran compiler unavailable in Android NDK. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Apply same conditional as larql-compute to skip default features check for Android cross-compilation targets to avoid environment-specific issues. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Replace skipped BLAS configuration with BLIS, a pure-Rust BLAS implementation that compiles on Android without requiring Fortran or system libraries. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
BLIS-src v0.1 has broken transitive dependencies (yanked security-framework versions). Replace with minimal blas-src configuration for Android that doesn't require external dependencies. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Gate `extern crate blas_src` and the ndarray `blas` feature behind platform-specific cfg so the codebase builds for Android, which has no system BLAS. On Android, ndarray falls back to its pure-Rust matrixmultiply path; all existing platforms (Linux/FreeBSD/macOS/ Windows) retain their BLAS backends unchanged. Affected crates: larql-compute, larql-inference, larql-kv. Build requirements (not committed — machine-local): - Android NDK r27+ with .cargo/config.toml for linker/ar - Cross-compiled OpenSSL for aarch64-linux-android (OPENSSL_DIR) - RUSTFLAGS="-C target-feature=+dotprod" (sdot in q4k kernel) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
Author
|
Pardon, my bot got confused and for some reason posted this here. I think it might be useful reference or possibly can be merged, so I'm leaving it, but if you want to close it then please do so. |
Set CC_*, CXX_*, and AR_* environment variables for Rust cross-compilation on Android platforms (aarch64-linux-android and armv7-linux-androideabi). These variables wire the NDK C compiler, C++ compiler, and archiver tools into Cargo's build process, enabling successful cross-compilation of C code (e.g., SIMD kernels in larql-compute, BLAS bindings in larql-inference/kv). Applied to all 11 per-crate workflows: - larql-core.yml (already present) - larql-compute.yml (already present) - larql-boundary.yml (new) - larql-cli.yml (new) - larql-inference.yml (new) - larql-kv.yml (new) - larql-lql.yml (new) - larql-models.yml (new) - larql-server.yml (new) - larql-vindex.yml (new) - bench-regress.yml (new) Fixes: Enables aarch64 Android builds (critical blocker per PR #42). Status: armv7 builds still pending wasmtime→wasmi gating (separate PR). https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Complete the Android NDK compiler environment variable setup for the two remaining per-crate workflows that were missing from the previous commit. Sets CC_*, CXX_*, and AR_* variables for both aarch64 and armv7 Android targets, enabling Rust cross-compilation to call the correct NDK tools. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Replace the cc crate convention (CC_*, CXX_*, AR_*) with Cargo's native cross-compilation environment variable format (CARGO_TARGET_*_CC). This ensures Cargo's build system correctly passes compiler paths to rustc, which then invokes the cc crate with the proper tools. The dual-format approach (CARGO_TARGET first, CC/CXX/AR as fallback) ensures compatibility with both Cargo's native handling and any C build scripts that may read the legacy environment variables. Applies to all 11 per-crate workflows with Android targets. https://claude.ai/code/session_01VsqyW3QzggZ4d9BNcNQRDc
Replace wasmtime + wasmtime-wasi with wasmi (pure-Rust interpreter) in larql-inference and model-compute so the workspace builds on arm32 Android (arm-linux-androideabi) where Cranelift has no backend. Wasmi migration: - larql-inference/experts: new wasi_shim.rs implements WASI preview1 host functions for wasmi; loader.rs / caller.rs / registry.rs rewritten against wasmi 1.0 API (instantiate_and_start, slice-based memory access, u64 Memory::size) - model-compute/wasm: runtime.rs / session.rs rewritten against wasmi 1.0 (StoreLimitsBuilder, Linker::instantiate_and_start, slice memory) - wasm_roundtrip integration test updated; wasmtime From impl removed from error.rs arm32 portable-atomic: - Replace std::sync::atomic::AtomicU64 with portable_atomic::AtomicU64 in six files across larql-inference and larql-vindex; ARMv7 lacks native 64-bit atomic ops and requires the software-CAS fallback REUSE compliance (Apache-2.0 §4): - Bring validate.yml, quality.yml, extra-platforms.yml, scripts/check_first_party_licenses.sh, LICENSES/, NOTICE, and REUSE.toml from main into this branch - Fix vague "Contributors to the larql-to-sparql project" SPDX headers in validate.yml and extra-platforms.yml → explicit Ian Douglas Lawrence Norman McLean copyright - Add REUSE.toml annotation blocks for all files modified or created in this branch (dual Chris Hay + Ian Douglas Lawrence Norman McLean copyright on modified files; sole Ian Douglas Lawrence Norman McLean on wasi_shim.rs; sole Chris Hay on *_jit.rs preservation files) - Add per-contributor aggregate annotations from git history: Dallas Pool, Dmitry Dorofeev, kariboo84, Michael Duane Mooring, Mike Mooring, Priyanshu Rai, Dave Seddon, Remi Petiot, Spezialk-dev, Thaddeus Covert Preservation for REUSE: - loader_jit.rs / caller_jit.rs (larql-inference) and runtime_jit.rs / session_jit.rs (model-compute) retain Chris Hay's original wasmtime JIT implementations verbatim, gated behind expert-jit / wasm-jit features and desktop-only OS cfg (linux/macos/windows/freebsd) Build confirmed: - arm-linux-androideabi: Finished dev profile ✓ - aarch64-linux-android: Finished dev profile ✓ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This was referenced May 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
extern crate blas_srcbehind#[cfg(...)]inlarql-compute,larql-inference, andlarql-kvso Android builds don't fail on a missing crateblasfeature from each crate's base[dependencies]into platform-specific[target.cfg.dependencies]sections — Android gets pure-Rust ndarray (matrixmultiply path), all other platforms keep their existing BLAS backends unchangedBuild instructions (machine-local, not committed)
.cargo/config.tomlneeds NDK linker/ar entries, plus these env vars at build time:Produces valid Android ELF64 PIE binaries (
larql,larql-server,larql-router) confirmed withfile.Notes
dotprodrequirement forq4k_q8k_dot.rsmeans the binaries target ARMv8.2+ (Cortex-A55 and later, ~2017+). A proper fix would add a#[cfg(target_feature = "dotprod")]guard with a scalar fallback — tracked separately.arm-linux-androideabi(32-bit ARM) is blocked by Cranelift having no 32-bit ARM backend. Tracked in a separate issue.Test plan
cargo build --target aarch64-linux-androidproduces ELF64 ARM aarch64 PIE binariescargo build(host) still compiles and uses BLAS on Linux/macOS/Windowscargo test(host) passes🤖 Generated with Claude Code