Just wanted to add on in case anyone else is trying to solve this.
I really appreciated the danielbarter’s mini_compile_commands, but I wanted something a bit simplier and here is what I came up with:
{
pkgs,
stdenv ? pkgs.stdenv
} :
let
jq = "${pkgs.jq}/bin/jq";
cc-wrapper-hook = pkgs.writeShellScriptBin "cc-wrapper-hook" ''
OUTDB="$(pwd)_$(date +"%s%N").ccdb"
OUTFILE=""
INFILE=""
for ((i=0; i<''${#params[@]}; i++)); do
case ''${params[$i]} in
-o)
if [ $((i+1)) -lt ''${#params[@]} ]; then
OUTFILE="''${params[$((i + 1))]}"
OUTDB="$OUTFILE.ccdb"
OUTFILE="$(realpath $OUTFILE)"
fi
;;
-c)
if [ $((i+1)) -lt ''${#params[@]} ]; then
INFILE="''${params[$((i + 1))]}"
INFILE="$(realpath $INFILE)"
fi
;;
esac
done
PARAMS=($compiler ''${extraBefore+"''${extraBefore[@]}"} ''${params+"''${params[@]}"} ''${extraAfter+"''${extraAfter[@]}"})
PARAMS_JSON="$(printf '%s\n' "''${PARAMS[@]}" | ${jq} -R . | jq -s .)"
jq -n --argjson args "$PARAMS_JSON" --arg directory "$(pwd)" --arg file "$INFILE" --arg output "$OUTFILE" \
'{
arguments: $args,
directory: $directory,
file: $file,
output: $output
}' > $OUTDB
'';
cc-hook = ''
ln -s ${cc-wrapper-hook}/bin/cc-wrapper-hook $out/nix-support/cc-wrapper-hook
'';
collect-compile-commands = pkgs.writeShellScriptBin "collect-compile-commands" ''
echo "Collecting compilation commands in current directory."
find . -type f -name '*.ccdb' -print0 | while IFS= read -r -d $'\0' file; do
jq -c '.' "$file"
done | jq -s '.' > compile_commands.json
echo "Compilation database written to $(realpath compile_commands.json)"
'';
in stdenv.override (old: {
cc = old.cc.overrideAttrs (final: previous: {
installPhase = previous.installPhase or "" + cc-hook;
});
extraBuildInputs = old.extraBuildInputs or [] ++ [collect-compile-commands];
})
And I’ve been using it my flake something like this:
let
stdenv = import ./ccdbenv.nix { inherit pkgs stdenv; };
in stdenv.mkDerivation {
...
};
From there, running builds will drop .ccdb
files next to the build artifacts, and a command collect-compile-commands
is used to collect all the contents of the ccdb files and assemble them into a usable compile_commands.json
Anyways, mini_compile_commands was great, I just wanted something a bit simpler and easier to deploy for other people in my build system.