LinuxCommandLibrary

bear

Generate compilation database for clang-based tools

TLDR

Generate compile_commands.json by running a build command

$ bear -- [make]
copy

Generate compilation database with a custom output file name
$ bear --output [path/to/compile_commands.json] -- [make]
copy

Append results to an existing compile_commands.json file
$ bear --append -- [make]
copy

Run in verbose mode to get detailed output
$ bear --verbose -- [make]
copy

Force bear to use the preload method for command interception
$ bear --force-preload -- [make]
copy

SYNOPSIS

bear [options] -- <build command> [<build command arguments>]

PARAMETERS

-o <file>, --output <file>
    Specifies the output path for the compile_commands.json file.

-a, --append
    Appends new commands to an existing compile_commands.json file instead of overwriting it.

-i <method>, --interception <method>
    Selects the interception method: 'preload' (default) or 'ptrace'.

-f <file>, --config <file>
    Specifies a configuration file to load options from.

-v, --version
    Displays the version information of bear.

-h, --help
    Displays the help message with available options.

DESCRIPTION

bear is a command-line tool designed to generate a compile_commands.json database. This file is crucial for tools like clangd (a language server for C/C++/Objective-C) and other static analysis tools to understand the compilation flags and include paths used during a project's build process. Without this information, these tools cannot provide accurate code completion, navigation, refactoring, and diagnostic capabilities.

bear works by intercepting the execve system calls made by your build system (e.g., make, ninja, cmake --build). It records the compiler invocations (compiler path, source files, include paths, defines, etc.) and writes them into the compile_commands.json file in the build directory. It supports different interception methods, including LD_PRELOAD (the default and generally preferred method) and ptrace. The LD_PRELOAD method is faster and less intrusive, while ptrace can be used when LD_PRELOAD is not an option or for debugging purposes. bear is widely used in modern C++ development workflows to enhance developer productivity with intelligent IDE features.

CAVEATS

Requires a functional build system executing compiler commands; it won't capture commands from generator-only builds (e.g., bare cmake). The default LD_PRELOAD interception method may not work in restricted environments; ptrace might require elevated privileges. For a complete database, a clean build (e.g., make clean && bear -- make) is often recommended, as incremental builds may miss commands for already compiled files.

THE <I>COMPILE_COMMANDS.JSON</I> FORMAT

The output file, compile_commands.json, is a JSON array of command objects. Each object represents a single compilation command and contains fields like directory (the current working directory of the compilation), command (the complete command-line invocation), and file (the primary source file being compiled). This standardized format allows various development tools to consistently understand build parameters.

INTEGRATION WITH <I>CLANGD</I> AND IDES

bear is most commonly used in conjunction with clangd, the Clang C/C++/Objective-C language server. By placing the generated compile_commands.json file in the project's root directory or build directory, clangd can automatically pick it up. This enables powerful IDE features such as accurate code completion, intelligent refactoring, semantic highlighting, and precise diagnostics directly within editors like VS Code, Neovim, and Emacs, significantly enhancing developer experience.

HISTORY

bear was developed to address the need for a robust and reliable way to generate compile_commands.json files, especially as language servers like clangd gained popularity. Before bear, users often relied on tools like cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON (which works only for CMake projects) or manual parsing/scripting, which were less general or error-prone. bear provided a generic solution by observing system calls, making it compatible with virtually any build system that invokes standard compilers. Its development focused on stability, performance, and compatibility across various Linux distributions. It has become a de-facto standard tool in the C/C++ ecosystem for integrating build systems with modern IDE features.

SEE ALSO

clangd(1), make(1), ninja(1), cmake(1), strace(1)

Copied to clipboard