Skip to content

Build from Source ​

clice depends on C++23 features and requires a modern C++ toolchain. We also need to link against LLVM/Clang to parse ASTs. Both come from xclang, clice-io's clang toolchain: Bazel builds clice with xclang's toolchain and links the prebuilt LLVM/Clang libraries of the same xclang release, both downloaded by Bazel itself. The two must match: the libraries hold ThinLTO bitcode, which only the toolchain of that release reads.

To simplify setup and keep builds reproducible, we strongly recommend pixi to manage the development environment. Dependency versions are pinned in pixi.toml; Bazel's are in MODULE.bazel.

Quick Start ​

Install pixi following the official guide.

We ship several tasks; the commands below build and run tests:

shell
# build (default RelWithDebInfo) into build/RelWithDebInfo
pixi run build

# unit + integration + smoke + snap tests
pixi run test

For finer-grained tasks (first argument sets the build type):

shell
pixi run build Debug
pixi run unit-test Debug
pixi run integration-test Debug
pixi run smoke-test Debug
pixi run snap-test Debug

pixi run build builds //:dist with Bazel. Each build type has a directory of its own, build/<type>, whose bin is Bazel's output tree of that type: clice is build/<type>/bin/bin/clice, next to the resource directory it reads clang's headers from, build/<type>/bin/lib/clang; the tests and the editors run it from there.

TIP

Run pixi shell to enter a shell with all env vars configured, and npx bazel there for Bazel itself.

Bazel ​

Bazel is run through bazelisk, an npm package of the repository (npm install installs it), which fetches the Bazel release .bazelversion names:

shell
npx bazel build //:bin/clice //:bin/unit_tests

The build types are configurations of .bazelrc:

ConfigurationEffect
--config=RelWithDebInfoThe default: optimized, with debug info
--config=DebugUnoptimized, with Address Sanitizer; on Windows without it

Options after -- reach Bazel through pixi run build, for example pixi run build RelWithDebInfo -- //:package.

The LLVM/Clang libraries hold ThinLTO bitcode, so every link of a program redoes their code generation, minutes per program. lld keeps what it generated in a cache, /var/tmp/xclang-thinlto (C:/xclang-thinlto on Windows), and later links take seconds.

npx bazel build //:package //:symbols builds the release archive and the symbol package, the unstripped clice: clice.tar.gz and clice-symbol.tar.xz in build/<type>/bin (.zip on Windows).

npx bazel run //:compile_commands writes a compile_commands.json of clice's own sources to the repository root, for clice to work on its own code; it runs bazel-compile-commands.

On Windows, Bazel's default output root is too deep for Windows paths; put a short one in %USERPROFILE%\.bazelrc:

startup --output_user_root=C:/b

Bazel also needs a Bash on Windows, which Git for Windows provides.

About LLVM ​

clice calls Clang APIs to parse C++ code, so it must link against LLVM/Clang. Because clice uses Clang's private headers (usually absent from distro packages), the system LLVM package cannot be used directly.

Every xclang release publishes prebuilt LLVM/Clang libraries (the libclang-* archives) for all six targets, built by that release's toolchain, and its Bazel module makes them repositories Bazel downloads with the toolchain.

IMPORTANT

Debug builds enable Address Sanitizer and link the ASan-instrumented libraries xclang publishes for x86_64 Linux and arm64 macOS; arm64 Linux and x86_64 macOS have none, and no Debug build. Debug builds for Windows link the release libraries, without Address Sanitizer.

A build of LLVM/Clang of one's own replaces the release's with --repo_env=XCLANG_LIBCLANG_ROOT=<directory> (XCLANG_LIBCLANG_ASAN_ROOT for the ASan one); it has to be built the way xclang builds it, by xclang's scripts/toolchain.ts; see xclang.