Skip to content
Laszlo Nagy edited this page Mar 31, 2026 · 12 revisions

Basic usage

After installation:

bear -- <your-build-command>

The output file compile_commands.json is saved in the current directory.

For more options, run bear --help or see the man page.

Example

If you compile your project with:

make -j4

Then run:

bear -- make -j4

Subcommands

Bear can operate in three modes:

bear [OPTIONS] [--] <BUILD_COMMAND>         # combined: intercept + semantic (default)
bear intercept [OPTIONS] [--] <BUILD_COMMAND>  # intercept only, writes events.json
bear semantic [OPTIONS]                     # semantic only, reads events.json

The combined mode is what most users need. The split modes are useful for debugging or when the build and analysis must happen separately.

Options

Flag Description
-c, --config <FILE> Path to YAML configuration file
-o, --output <FILE> Output file path (default: compile_commands.json)
-a, --append Append to existing output instead of overwriting
-h, --help Print help
-V, --version Print version

Pass Bear's own options before --. Everything after -- is the build command.

Limitations

Bear intercepts process executions during the build. It does not read build descriptions (Makefile, CMakeLists.txt, etc.). This means:

  • If your build is incremental and skips already-compiled files, those files will be missing from the output. Clean your build first (make clean) or use --append.
  • If your build breaks partway through, only commands that already executed will appear.
  • Bear cannot intercept builds that happen inside a Docker container if Bear itself runs outside. Run Bear inside the container.

Cross compilers

Cross compilers work with Bear. The catch is that Bear may not recognize the compiler name automatically. Use a configuration file to add compiler hints:

schema: "4.1"
compilers:
  - path: /usr/bin/arm-linux-gnueabi-gcc
    as: gcc

Compiler wrappers

Bear recognizes these wrapper tools and handles them correctly:

Interception modes

Bear has two interception methods. The mode can be set in the configuration file:

  • Preload (default on Linux/BSD): Uses LD_PRELOAD to inject a shared library (libexec.so) that intercepts exec* calls. Transparent to the build system. Does not work with statically linked build tools.
  • Wrapper (default on macOS and Windows): Creates wrapper executables in a .bear/ directory and prepends it to PATH. Requires the build system to respect CC/CXX environment variables or PATH for compiler lookup.

To force wrapper mode (useful when preload does not work):

schema: "4.1"
intercept:
  mode: wrapper

Build tools

Bear is build-tool independent, but some build systems deserve special mention.

CMake

CMake generates a compilation database natively. You do not need Bear:

cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..

Meson / Bazel

These build systems also support compilation database generation natively. Prefer their built-in support over Bear.

Statically linked build tools

If the build tool is a static binary, the dynamic linker is not involved, so preload mode cannot intercept anything. Use wrapper mode instead:

schema: "4.1"
intercept:
  mode: wrapper

The build system must respect CC/CXX environment variables for this to work.

Example: Go projects using cgo require wrapper mode because Go tooling is statically linked:

schema: "4.1"
intercept:
  mode: wrapper
bear -c bear.yml -- go build .

OS support

Platform Status Notes
Linux Supported Both preload and wrapper modes
macOS Supported Wrapper mode by default (SIP blocks preload). See Platform notes.
FreeBSD Supported
OpenBSD Supported
NetBSD Supported
DragonFly BSD Supported
Windows (MSYS2) Experimental Wrapper mode only. See Platform notes.

Clone this wiki locally