How to make a .compile_commands.json?

I have a cmake project, with the following flake:
{
description = “A very basic flake”;

inputs = {
nixpkgs.url = “nixpkgs/nixos-21.11”;
};

outputs = { self, nixpkgs }:
let
pkgs = import nixpkgs {
system = “x86_64-linux”;
};
in
{
defaultPackage.x86_64-linux = pkgs.stdenv.mkDerivation {
pname = “game-engine”;
version = “0.0.1”;
src = ./.;
nativeBuildInputs = with pkgs;[ cmake gcc gnumake ];
buildInputs = with pkgs; [SDL2 box2d];
postBuild = ‘‘mkdir -p $out/
cp compile_commands.json $out/compile_commands.json’’;
};
};
}

I am able to copy compile_commands.json to the result directory, but i want it in my root directory, aka where the flake.nix resides. Any ideas on how to do that?

I’m not sure I understand completely. Do you want to copy it to or from the directory with flake.nix?

I think the code you posted should already copy it from there, but in case I’m wrong, there should be a ,$src variable, similar to$out, with your code.

If you want to copy it to that location, I will need now explanation to understand it. I feel like flakes aren’t really meant to do that, so if you explain what you’re trying to achieve, we’ll surely find a way to do that

Thanks @voydus. I want to copy it to the directory with flake.nix.
I have figured out a hacky way to do it, here’s my updated flake.nix:

{
  description = "A very basic flake";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-21.11";
  };

  outputs = { self, nixpkgs }:
  let
    pkgs = import nixpkgs {
      system = "x86_64-linux";
    };
  in
  {
    defaultPackage.x86_64-linux = pkgs.stdenv.mkDerivation {
      pname = "game-engine";
      version = "0.0.1";
      src = ./.;
      nativeBuildInputs = with pkgs;[ cmake gcc gnumake ];
      buildInputs = with pkgs; [SDL2 box2d];
      postBuild = ''mkdir -p $out/
                    cp compile_commands.json $out/compile_commands.json'';
    };

    packages.x86_64-linux.cc = pkgs.stdenv.mkDerivation {
      name = "compile_commands.json";
      src = ./.;
      nativeBuildInputs = with pkgs;[ cmake gcc gnumake ];
      buildInputs = with pkgs; [SDL2 box2d];
      installPhase = ''cmake .
                       make
                       cp compile_commands.json $out'';
    };

  };
}

Now I run nix build .#cc -o compile_commands.json.
It runs the cc derivation, which installs the compile_commands.json to $out. While this is a doable way, I feel making another derivation for compile_commands.json is unneccessary, when it is being generated when normally compiling the program.

In general you are not supposed or even allowed to create anything outside of $out via a derivation.

If you make the compile commands part of out, you can link to them, though you really shouldn’t.

If your dev tooling requires a JSON file, build that as part of dev, but not as part of the derivation, as the derivation should only contain “production output”.

1 Like

I’m not quite sure I understand the goals here (maybe because I’m not using flakes? maybe because I know compile_commands.json is a thing, but don’t really know what it’s for? :slight_smile:), but:

If your question is more like, “When I use Nix in my development workflow, how do I integrate artifacts generated by Nix builds back into my project?”, I’ve been using a Makefile for something like this in my development workflow for resholve.

For example, I regularly regenerate a file, timings.md, with test timings so that performance over time is a little easier to explore. The meat of the timings file is one of the outputs of the CI task:

The recipe for that file indirectly depends on result-ci, which is a directory produced by running nix-build --out-link result-ci:

If this is your goal, I assume you’d just copy the file out (I’m using cat here only because I need to compose the final file). Make sure the file doesn’t contain any store paths if you plan to commit it (future Nix builds won’t like this).

1 Like