Skip to content

Building

Mazhar Ahmed edited this page Aug 28, 2026 · 5 revisions

Building

git clone https://github.com/mazhar266/QQ-Lang
cd QQ-Lang
cargo build --release
cargo test

Rust 2021 on a stable toolchain. Nightly is only for Miri and cargo-fuzz.

All data QQL reads — text, canonical citation maps, and both search index sets — is committed, so a plain clone is a complete working installation. Nothing at runtime reads a submodule. The two submodules that are checked in (hadith-json, compressed_hadith_sqlite) are raw upstream material for the build scripts, and a clone without them works exactly the same.

What gets built

Artifact For
libqql.rlib Rust consumers
libqql.so / qql.dll / libqql.dylib the C ABI, dynamically linked
libqql.a the C ABI, statically linked
qql the CLI
qql-index index builder, with --features fulltext

Features

Feature Adds Cost
(none) everything except ranked search serde + serde_json
vector *"term" similarity no new dependency; 28 MB of committed indexes
fulltext ?"term" ranked search tantivy, a large dependency tree; 22 MB of committed indexes
cargo build --release --features vector
cargo build --release --features fulltext
cargo build --release --features vector,fulltext

Both are off by default so the core stays small for embedded and mobile use. Without a feature, its query form is refused with QQL_UNSUPPORTED — never silently downgraded.

The feature set is baked into the shared library. A plain cargo build --release overwrites libqql.so with a featureless one, which is what Dart and C consumers load.

Indexes

Index Built by Committed? Time / size
sources/vectors/*.qv python3 scripts/build-vectors.py yes ~45 s, 28 MB
sources/fulltext/<CODE>/ cargo run --features fulltext --bin qql-index yes ~11 s, 22 MB

Both are committed, so a checkout — and anything built from one — can search without a build step. Rebuild both after changing any text.

Two things to know before rebuilding the tantivy indexes casually. Tantivy names its segment files by UUID, so a rebuild replaces all of them: a large diff every time, and every rebuild leaves its own copy in git history. And a tantivy index is tied to the library version that wrote it, so upgrading the tantivy dependency means regenerating and committing.

Data

Text lives in sources/, read in each upstream project's own layout — no ETL step and no second copy. See Sources for provenance, including why the Quran text is generated from Tanzil rather than vendored.

Checks

cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test
./scripts/c-smoke.sh                    # C header + link check
cargo +nightly miri test --test ffi     # after touching src/ffi.rs
cargo +nightly fuzz run parse           # the parser must never panic

When touching search, test every combination:

cargo test
cargo test --features vector
cargo test --features fulltext
cargo test --features vector,fulltext

Dart:

cargo build --release --features vector,fulltext
cd bindings/dart && dart pub get && dart test

CI

.github/workflows/ci.yml runs fmt, clippy, tests, the C smoke test, Miri on the FFI tests, short fuzz runs, both feature jobs, and the Dart binding.

Clone this wiki locally