I frequently use this to make clangd work well. With CMake-based projects, you can just set CMAKE_EXPORT_COMPILE_COMMANDS then create a symlink from compile_commands.json in your source directory to the CMake build directory. (If you control the CMake file, you can even set this by default and make CMake create this symlink automatically.) To keep the symlink out of Git, you can add it to .gitignore of course, or if you don't control that, the lesser-known local equivalent, .git/info/exclude.
I use this often in combination with direnv and Nix flakes for a good developer experience. (Note that if you need to keep the Nix flake VCS-ignored, you'll need to tell direnv to explicitly not use a Git fetcher for Nix using something like `use flake path://$PWD` though this isn't needed if you can just re-use a Nixpkgs expression, e.g. `use flake nixpkgs#wineWow64Packages.wine-unstable` or so.)
One thing that sucks is that it doesn't seem to be easy to handle cross-compilation stuff. Wine is a particularly challenging case, as many of the binaries are now cross-compiled with MinGW. It still provides better completion than nothing, but I do wish I could get it to be perfect.
When using Nix with MinGW I struggled even harder because Nix's MinGW is even weirder... But with enough mangling, you can even convince clangd on Linux to give somewhat decent completions for a MinGW compilation.
One obvious disadvantage is that you kind of need a full rebuild to get the compilation database to work correctly. At least in my personal experience, running bear on a partial build seems to not work in an additive fashion, though maybe I was holding it wrong.
Never thought about wanting it to work with incremental builds, so thanks for the idea. Added a jq one-line to do so in my script: https://git.sr.ht/~q3cpma/scripts/commit/3f860728eb2ea6d46e4...