Vscode c++ cpptools and clangd not working

Hi! So this happens because vscode is downloading random binaries from the internet, which are built on a normal distro with the dynamic linker in the normal path, but NixOS doesn’t place the dynamic linker in the usual path.

Let me explain. If you run, e.g.,

ldd /home/davide/.vscode/extensions/ms-vscode.cpptools-1.12.4-linux-x64/bin/cpptools

you will get output something like this:

        linux-vdso.so.1 (0x00007ffe689dc000)
        libdl.so.2 => /nix/store/lxpdbaazqd2s79jx6lngr8nak2rjdaq1-glibc-2.34-210/lib/libdl.so.2 (0x00007f27e9915000)
        libpthread.so.0 => /nix/store/lxpdbaazqd2s79jx6lngr8nak2rjdaq1-glibc-2.34-210/lib/libpthread.so.0 (0x00007f27e9910000)
        libm.so.6 => /nix/store/lxpdbaazqd2s79jx6lngr8nak2rjdaq1-glibc-2.34-210/lib/libm.so.6 (0x00007f27e8527000)
        libc.so.6 => /nix/store/lxpdbaazqd2s79jx6lngr8nak2rjdaq1-glibc-2.34-210/lib/libc.so.6 (0x00007f27e8329000)
        /lib64/ld-linux-x86-64.so.2 => /nix/store/lxpdbaazqd2s79jx6lngr8nak2rjdaq1-glibc-2.34-210/lib64/ld-linux-x86-64.so.2 (0x00007f27e991c000)

The final line there is the so-called “interpreter”, which is at the start of the file with a #!. It’s responsible for starting the application, and making sure all its dynamic libraries are correctly loaded.

As you see, it asks for /lib64/..., which doesn’t exist on NixOS - all libraries and binaries live in the nix store instead.

ldd is even smart enough to find a dynamic linker that would work, but when you execute the binary Linux doesn’t go looking for other files, it just uses exactly the file that the binary asks for, and then gives you the extremely unhelpful “file not found” error message you see.

There are two solutions to this problem:

  1. Manually patch the binaries every time vscode downloads them
  2. Use nix to install the plugins

The former can be done with patchelf.

The latter can be done by not using vscode’s plugin browser, and instead doing something like this:

environment.systemPackages = with pkgs; [
  # <snip lots of packages>
  # ...
  (vscode-with-extensions.override {
    vscodeExtensions = with vscode-extensions; [
      ms-vscode.cpptools
      llvm-vs-code-extensions.vscode-clangd
    ];
  })
];

Personally, I think this is preferable :slight_smile: