Get the code, build, and run seekdb
Prerequisites
Install the supported compiler and dependencies described in Install the toolchain. A full source build requires substantial disk space and memory.
Clone the repository
Build the production binary
The repository's build.py downloads the Bazel version pinned in .bazelversion and runs the requested command. The default build uses -O2 and includes debug information.
init prepares Rust and platform dependencies; run it on the first build or after dependency metadata or rust-toolchain.toml changes. For incremental builds, repeat only the build command. The resulting binary is build/bin/src/observer/seekdb.
Put all options after the command, including Bazel startup options such as --batch and --bazelrc. build.py reads the installed Bazel's option definitions on each invocation and moves startup options before the command internally. Keep Bazel's original option names, including underscores.
On Windows, use python build.py with the same commands. For C++ test targets, see Write and run unit tests. When you change Rust dependencies, commit the updated Cargo.lock.
Rust build declarations
The Cargo workspace manifest, lockfile, and toolchain pin live at the repository root. Each crate has a BUILD.bazel using standard rules_rust rules. Community dependencies, aliases, and editions come from crate_universe through all_crate_deps, aliases, and crate_edition; local dependencies, source inputs, and enabled features are explicit in BUILD files. Local dependency edges must also be declared in Cargo.toml for Cargo users.
Use rust/logger/BUILD.bazel as a small example, or rust/config/BUILD.bazel for generated inputs. Add a module that belongs in the final archive to rust/seekdb-rust's Cargo.toml, BUILD.bazel, and src/lib.rs. CXX interfaces are registered in rust/modules.bzl, which also collects bridge objects for the final C++ link. Share feature constants between a Rust target and its CXX generator when needed, as sql-nio does. New modules do not require changes to MODULE.bazel, SDK initialization, or the C++ link list.
Native targets use the pinned stable Rust SDK. Wasm uses its pinned nightly and the patched standard library prepared by init --wasm. Cargo target dependencies select the platform's community dependencies; the shared sql-nio feature map selects native networking or Wasm memory transport for both Rust and CXX. Ordinary builds track manifest and lockfile changes without another init.
Set build concurrency
Bazel defaults to the available host CPU count. When you explicitly set local build concurrency, build.py sets both the job limit and the local CPU scheduling budget:
-j32, -j 32, and --jobs=32 are equivalent. Only explicit numeric command-line values are synchronized; omitting the option preserves Bazel's automatic defaults. An explicit --local_resources=cpu=N overrides this budget. Memory settings are unaffected.
To pass a job option to another tool, use an equals sign, such as --test_arg=-j32. Program arguments after run -- are forwarded unchanged.
Use remote C++ compilation
Specify your REAPI service address and concurrency:
The default strategies in .bazelrc prefer remote execution for C++ compilation and use local execution when no remote executor is configured. Set --remote_executor without adding --config=remote. Rust compilation, generators, and linking run locally. The default local strategy order is worker,sandboxed,local on Linux and macOS, and worker,local on Windows, where Bazel does not support sandboxing. Explicit execution strategies on the command line override these defaults. If the service requires an SSH tunnel, establish the tunnel separately.
With --config=remote or a nonempty --remote_executor on the command line, --jobs only controls total concurrency. Bazel still detects the local CPU budget automatically unless you set it separately with --local_resources=cpu=N.
Build a Sanity binary
On Linux, enable Sanity instrumentation with:
Sanity is disabled by default. --sanity is equivalent to --sanity=true; use --sanity=false to disable it explicitly.
To keep a separate Sanity build, specify a build directory:
Its binary is accessible at build_sanity/bin/src/observer/seekdb.
Build directories
Bazel's working directory defaults to build/ inside the project. It contains intermediate files and final outputs. The build/bin, build/out, and other output links point into this directory; build/bin/src/observer/seekdb is the native Linux/macOS binary path.
Put -o PATH or --output_base=PATH after the command; build.py also sets the output link prefix to PATH/. For example, ./build.py build -o build3 seekdb uses build3/ as the working directory and build3/bin/src/observer/seekdb as the binary path. Relative paths are resolved from the project root; absolute paths can place builds on another disk. Different directories have independent build state and links and can build concurrently. Bazel serializes commands using the same directory.
Run ./build.py info output_base to locate the working directory and ./build.py clean --expunge to remove it. For a custom directory, use ./build.py info -o build3 output_base or ./build.py clean -o build3 --expunge. Exclude build directories when searching source files, for example: find . -path './build' -prune -o -type f -name '*.cpp' -print.
Reuse build caches
Bazel binaries and the default action cache are shared between checkouts. Their base directory is ~/.cache/bazel on Linux, ~/Library/Caches/bazel on macOS, or %LOCALAPPDATA%/bazel on Windows. Linux honors XDG_CACHE_HOME. Bazel manages its shared repository download cache separately.
Use --launcher_cache_dir PATH for the Bazel binary cache, --disk_cache=PATH for build actions, or --repository_cache=PATH for downloaded dependencies. All go after the command. For example:
To change dependency download settings, use Bazel's --registry=URL or --downloader_config=PATH after the command.
Build for another platform
Use the seekdb target on every platform. Select a platform with --config=android, --config=ios, --config=ios-simulator, or --config=wasm; without a platform configuration, the target builds the native program. Follow the Android, iOS, or WebAssembly guide to prepare dependencies. Android builds a server program, iOS builds a framework, and WebAssembly builds an engine and SQL shell. The alias preserves each platform's output paths.
Maintain build declarations
Choose the file by what you need to change:
| File | Responsibility |
|---|---|
build.py |
Launch the pinned Bazel binary and prepare platform dependencies with init. |
.bazelrc |
Default Bazel options and named platform configurations. |
MODULE.bazel |
Bazel module dependencies and repository/toolchain registration. |
bazel/defs.bzl |
Shared C++ and linking rule entry points for BUILD.bazel files. |
bazel/compile_config.bzl |
Common compiler options and Sanity instrumentation settings. |
bazel/build_settings.bzl, bazel/BUILD.bazel |
Custom setting types and shared flag declarations. |
A package's BUILD.bazel |
Targets, headers, explicit dependencies, and visibility. |
For C++ libraries, load cc_library, unity_cc_library, or grouped_unity_cc_library from //bazel:defs.bzl. cc_library compiles each source separately. unity_cc_library combines an ordered unity_members list into one translation unit. grouped_unity_cc_library creates one translation unit per named group in unity_groups.
- Add a normal source to its owning target's
srcs. For an existing Unity group, add its repository-relative path to that group'ssrcsin the package's*_source_inventory.bzl; preserve the member order. Targets declared withunity_memberslist package-relative paths directly inBUILD.bazel. - To keep a file out of a multi-file Unity group, add it to the standalone source list consumed by its target. These lists contain paths. Keep C and C++ lists separate; the rule call selects the language. A new list must be connected to a target in
BUILD.bazel. - Put public headers in
hdrsor the module's public header list. Put private headers insrcsor the module's internal header target; modules that use a headerglob()pick up matching new files automatically. The Unity helpers call these attributespublic_hdrsandprivate_hdrs. - Add dependencies used by public headers to
deps. Put dependencies used only by implementation files inimplementation_deps. Setvisibilityto the intended consumers. Dependencies are maintained explicitly; there is no include scanner that generates them.
Build the affected target with ./build.py build //package:target. Existing module-direction and header-layering checks run as part of the build.
Run a local instance
On Linux and macOS, start the compiled binary with the repository's instance helper:
python3 tools/deploy/sdb.py start \
--binary build/bin/src/observer/seekdb \
--base-dir "$PWD/build/dev-instance" --port 2881
python3 tools/deploy/sdb.py wait-ready \
--client deps/3rd/u01/obclient/bin/obclient \
--base-dir "$PWD/build/dev-instance" --port 2881
The helper starts seekdb directly. A new data directory initializes automatically. Pass repeated --parameter key=value options to start when you need server settings. start returns after spawning the process; wait-ready checks the managed process and waits for SELECT 1 to succeed.
Connect with either client:
mysql -h127.0.0.1 -P2881 -uroot
./deps/3rd/u01/obclient/bin/obclient -h127.0.0.1 -P2881 -uroot -Doceanbase -A
To run in the foreground, including on Windows, invoke the binary directly with --nodaemon --base-dir=<directory> --port=2881. The Python instance helper currently supports Linux and macOS.
Stop or remove the local instance
Stop the instance and keep its data:
Run the same start and wait-ready commands to restart it. To stop it and delete this example's data instead:
destroy removes the entire managed instance directory. Only use it for disposable data. See Running mysqltest for SQL regression tests with a separate disposable instance.