docs/requirements/interception-wrapper-mechanism.md
When the user runs bear -- make in wrapper mode (which mode runs and
when is owned by interception-mode-selection), Bear intercepts
compiler invocations by placing wrapper executables on PATH ahead of the
real compilers. The build system invokes the wrapper instead of the real
compiler; the wrapper reports the execution to Bear and then forwards
the call to the real compiler. The build completes normally and the user
gets a compilation database without modifying the build system.
CC=gcc) are
resolved via PATH before creating wrappers.bear/ directory is created in the current working directory.bear/ directory is cleaned up when Bear exitscl, cl.exe, and CL.EXE all match).bear/ directory name is deterministic so that paths written
during ./configure survive into the make phaseOnly intercepts known compilers: Unlike preload mode, which
intercepts all exec calls regardless of the executable, wrapper mode
only intercepts compilers that Bear knows about. If the build uses a
compiler that is not in a recognized environment variable or not on
PATH at Bear startup time, it will not be intercepted.
PATH ordering conflicts (issue #445): The .bear/ directory must
be first in PATH. If another tool (e.g. ccache's masquerade directory)
is also first in PATH, the ordering can cause conflicts. See
interception-wrapper-recursion for the specific ccache recursion
problem and its solution.
Wrapper directory lifetime (issue #654): If the user runs
bear -- ./configure and bear -- make as separate commands, the
.bear/ directory is cleaned up after ./configure exits. The
Makefile may have recorded paths into .bear/ (e.g. as the compiler
path), causing "No such file or directory" errors during make. The
workaround is to combine both steps under a single Bear invocation:
bear -- sh -c './configure && make'. Using separate Bear invocations
will always fail because the directory is removed when the first exits.
Cross-compilers may not be discovered (issue #561): Bear discovers
compilers from environment variables and common names. Cross-compilers
with unusual names (e.g. arm-none-eabi-gcc) are only intercepted if
they appear in CC, CXX, or similar variables.
Given a project with a single C source file:
When the user configures wrapper mode and runs
bear -- cc -c test.c, thencompile_commands.jsonis created with one entry fortest.c, and the compiler path in the entry is an absolute path to the real compiler (not.bear/cc), and the build exit code is preserved.
Given CC=gcc (a bare name) or CC=/usr/bin/gcc (an absolute path) in
the environment:
When the user runs
bear -- make, then Bear resolves the bare name via PATH to/usr/bin/gcc(the absolute path needs no resolution), creates.bear/gccas the wrapper in both cases, and the compilation database entry names/usr/bin/gccas the compiler.
Given a wrapper that cannot reach the collector:
When the build invokes the wrapper for
cc -c test.c, then the wrapper still launches the real compiler, the compiler's output is produced, and the build's exit code is the real compiler's exit code -- the failed report costs one database entry, never the build.
Given a parallel build with multiple source files:
When the user runs
bear -- make -j4with wrapper mode, then all compilations are intercepted, and the compilation database contains one entry per source file.
Given a build that fails partway through:
When the user runs
bear -- makeand one compilation fails, then Bear's exit code matches the build's exit code, and the compilation database still contains entries for all attempted compilations.
Given a Windows build with CC=cl (no .exe extension):
When Bear sets up wrapper mode and the build compiles
test.c, then the wrapper directory contains exactly one wrapper forcl--cl,cl.exe, andCL.EXEall match it, case- and extension- insensitively -- and the database entry names the realcl.exeby absolute path.
Given a build where the compiler is not in any environment variable:
When the build script directly invokes
/opt/custom/bin/mycc -c test.cwithout settingCC, then the invocation is not intercepted in wrapper mode (this is a known limitation -- preload mode would catch it).
Given a successful build:
When
bear -- makecompletes, then the.bear/directory is removed automatically, and no wrapper artifacts remain in the working directory.
interception-preload-mechanism (alternative
interception mode using LD_PRELOAD).interception-wrapper-recursion (ccache
recursion prevention in wrapper mode).interception-mode-selection.