C/C++ analyzers not working due to includes

I am trying to make some basic nix-shell for my C/C++ development. I am a big fan of LLVM and their tools. I managed to get the clang++ working with llvmPackages_latest.llvm (because it could not find and include anything from libc++.

But when it comes to clang-tidy or cppcheck I just cannot make it work properly. I looked into the older threads like: clang-tooling-woes-on-nixos. But none of it really helped me.

Using this shell.nix file:

{
  pkgs ? import <nixpkgs> {},
  stdenv ? pkgs.clangStdenv
}:

pkgs.mkShell {
  name = "C/C++ Study Environment";
  buildInputs = with pkgs; [
    pkg-config
    gnumake
    ninja
    cmake
    meson
    bashInteractive

    llvmPackages_latest.llvm
    llvmPackages_latest.libcxxClang
    llvmPackages_latest.libcxxStdenv

    lld
    clang
    clang-tools
    cppcheck
  ];

  shellHook = with pkgs; ''
    export CC=clang
    export CXX=clang++
  '';
}

and simple hello world in C:

#include <stdio.h>
int main() {
  printf("Hello, World!\n");
  return 0;
}

when trying to run clang-tidy hello.c
I get this error:

Error while trying to load a compilation database:
Could not auto-detect compilation database for file "test.c"
No compilation database found in /home/dan/Documents/Code/Cpp or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
1 error generated.
Error while processing /home/dan/Documents/Code/Cpp/test.c.
/home/dan/Documents/Code/Cpp/test.c:1:10: error: 'stdio.h' file not found [clang-diagnostic-error]
#include <stdio.h>
         ^~~~~~~~~
Found compiler error(s).

and if I manually set CPATH variable in the shellHook to something like this (I realize that it is not a good idea to override this variable without $CPATH:, this is only for testing if it works):
export CPATH=/nix/store/k3d8wqlsnmm5270zd19cbs26g7wifxj6-glibc-2.34-210-dev/include

Then I get a new error, I cannot find stddef.h:

Error while trying to load a compilation database:
Could not auto-detect compilation database for file "test.c"
No compilation database found in /home/dan/Documents/Code/Cpp or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
1 error generated.
Error while processing /home/dan/Documents/Code/Cpp/test.c.
/nix/store/k3d8wqlsnmm5270zd19cbs26g7wifxj6-glibc-2.34-210-dev/include/stdio.h:33:10: error: 'stddef.h' file not found [clang-diagnostic-error]
#include <stddef.h>
         ^~~~~~~~~~
Found compiler error(s).

And the CppCheck gives me this error, every time:

Checking hello.c ...
test.c:1:0: information: Include file: <stdio.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]

^

LLVM and clang is not installed on the system level.

With my current knowledge I simply cannot get this to work. I only want to lint my code with clang-tidy and cppcheck is here some easy fix?

Making a flake for quick generic setup of C++ projects (that is to say, adding C++ to this collection) has been somewhere below page 50 of my TODO list for quite some time. I try to avoid C++ like the plague, and for the situations where I’m obliged to use C++, I have ad-hoc nix solutions which work for me, so the motivation to get a clean, shareable generic solution is somewhat lacking. I’ll have a look if I can get this into a usable state if I find a bit of spare time.

On the specific topic of clang not finding standard headers, I recall I had (and solved) this problem somewhere … here. This solution is cmake-specific, but the whole topic does discuss the problem in a slightly broader context. Maybe you’ll find something relevant.

1 Like

I am not familiar with configuring clang, but I notice that the nixOS wiki page on Rust has a shell.nix containing some llvm config, including LIBCLANG_PATH and BINDGEN_EXTRA_CLANG_ARGS. Maybe you can find some clues there.

Thank you for the idea with cmake, I am going to try it.

In my search of more generic solution I tried using configuration for clangd for which I tried searching for include paths with clang++ -v -c -xc++ /dev/null and manually adding them to the ~/.config/clangd/config.yaml like this:

---
CompileFlags:
  Add:
    - "-I <path-in-nix-store>/include"

Unfortunaly it didn’t help my case, but perhaps you could use it someday in your collection.

edit: I found out that path /nix/store/<hash>-libcxx-13.0.1-dev/include/c++/v1/ contains all required header files, so that could be the point of next investigation.

Found little fix that fixes atleast a part of the problem (clangd).

Due to this “bug” in nix clangd has different version and wrapping depending on its position to clang in *.nix file, therefore it can cause some issues.

with this smaller and more simple shell.nix atleast LSP works:

{ pkgs ? import <nixpkgs> {}, }:

pkgs.mkShell {
  name = "C++ Study Repository";
  buildInputs = with pkgs; [
    pkg-config
    gnumake
    ninja
    cmake
    meson
    bashInteractive

    lld
    clang-tools
    clang
    cppcheck
  ];
}

clang-tidy still produces some errors, but those are probably more due to the configuration of the tools, than something nix related. For the curious:

Error while trying to load a compilation database:
Could not auto-detect compilation database for file "main.cpp"
No compilation database found in /home/dan/Documents/shellTest or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.

When I have been using clang-tidy on fedora, I have never encountered this issue and I didn’t have to specify --check="<checks>", but this is probably on my side.

cppcheck still cannot find the headers and it probably needs some kind of wrapping as well.

1 Like

I have looked into this and BINDGEN_EXTRA_CLANG_ARGS is something rust specific and changing LIBCLANG_PATH (which is also used in the rust but I have found some issues with it on the internet related to C++) did not help either. It is shame, it was a good tip.

1 Like

I could make at least clangd work and find stdlibraries by doiing:

 # C++
          # Clangd from clang-tools must come first.
          (hiPrio clang-tools.override {
            llvmPackages = llvmPackages_16;
            enableLibcxx = false;
          })
          # Do not use the clangd from this package as it does not work correctly with
          # stdlib headers.
          llvmPackages_16.libstdcxxClang
1 Like