This is because the clang-tools package is a wrapper that injects the buildPlatform’s glibc to clangd’s C_INCLUDE_PATH, while the actual libc for pkgsCross.arm-embedded is newlib.
To fix this, I have to 1. remove glibc from clangd’s search path, 2. add newlib to clangd’s search path. The canonical method for 2 is --query-driver. The easiest way I can think of is to make my own wrapper for clangd to mask the one from clang-tools:
(lib.hiPrio (
pkgsBuildBuild.writeShellScriptBin "clangd" ''
${pkgsBuildBuild.llvmPackages.clang-unwrapped}/bin/clangd --query-driver="$(command -v $CC)" "$@"
''
))
pkgsBuildBuild.clang-tools # The rest of the package
A recent PR clang-tools: Improve wrapper script, add tests by Patryk27 · Pull Request #354755 · NixOS/nixpkgs · GitHub added a condition check to the wrapper: if user passed --query-driver, don’t inject search paths. I’m still on nixos-25.11, but if you are on nixos-unstable, you should be able to have some sort of project-specific Neovim config to do this:
vim.lsp.config('clangd', {cmd={'clangd', '--query-driver=...'}})