🌊

clangd(VS Code)で"In included file: ‘stdlib.h’ file not found

2025/01/11に公開

WSL上でARMのクロスコンパイル環境(petalinux2024.2 gcc)を構築して、Windows側でVS Code+clangdを動かしてソフトウェアを開発しているのですが

ソースコード(.c,.h)ファイルと同じフォルダにcompile_flag.txtを置いて、そこで/usr/includeや/usr/include/c++/13.3.0にincludeファイル探しに行くようInclude Pathを設定しています

ここで/usr/include/stdlib.hがあるのにも関わらず.cファイルの#include <thread.h>等のところで下記のようなメッセージがでます

In included file: 'stdlib.h' file not found clang(pp_file_not_found)
cstdlib(79, 15): Error occurred here

ファイルを追うと
bits/std_abs.hの下記の部分で失敗しているようです

#include_next <stdlib.h>

#include_nextは指定したファイル名のファイルを見つかっても一回目はスキップして二回目に見つかった同名のファイルをインクルードするディレクティブです(gccのみ使えると思います)

stdlib.hという名前のファイルは/usr/includeと/usr/include/c++/13.3.0の両方にあります

一回目はスキップして二回目に見つかったらということは二回stdlib.hを見つける必要があるのですが、
よくよく考えてみると
#include_nextを使っているのであればinclude pathをgccと同じにするだけではなく、include pathの順番もgccと同じにして見つける順番も合わせないとglibcの期待するインクルードファイルにならないと気づきました

なぜnot foundになるのかはわかりませんが、include pathの順番を変えるとメッセージが消えるので多分これだろうと思います

LinuxのようなOS上での開発はあまりしていないので気が付かなかっただけのような気もします
(include pathの順番を気にする必要があるのは抜けていました、同じファイル名が存在している時点で気が付けよという感じです)

数か月ずっと気になっていたのですが
VSCodeのClangd serverのバージョンが19になってC++20も対応?したので再調査して解決できたので記事にしてみました

clangdでgcc(glibc)のファイルをインクルードするためにcompile_flags.txtは下記の用な記述も追加しています(#include <thread>程度であればこれで通っています)

-std=gnu++20
-D_GNU_SOURCE
-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1
-D__GCC_ATOMIC_BOOL_LOCK_FREE=2
-D__GCC_ATOMIC_POINTER_LOCK_FREE=2
-D__GCC_ATOMIC_CHAR_LOCK_FREE=2
-D__GCC_ATOMIC_SHORT_LOCK_FREE=2
-D__GCC_ATOMIC_INT_LOCK_FREE=2
-D__GCC_ATOMIC_LONG_LOCK_FREE=2
-D__GCC_ATOMIC_LLONG_LOCK_FREE=2
-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2
-D__GCC_ATOMIC_CHAR8_T_LOCK_FREE=2
-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2
-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2
-nostdlibinc

参考になれば幸いです

Discussion