【任务描述】
clangd failed to resolve symbols.
Reproduce steps:
【解决方案】
【任务来源】
Could you clarify the description?
compile openharmony code and generate compile_commands.json using ninja
Do you mean "compile OHOS toolchain and use clangd
from it"? Or is this issue only reproducible on the sources of OHOS itself (if yes, then which file exhibits this issue)?
Could you provide some self-contained cpp source that demonstrates this bug?
If this issue is only reproduced with some OHOS-specific source file, please specify
clangd
binary (absolute or at least from repo root, such as $REPOROOT/out/install/linux-x86_64/clang-dev/bin/clangd
)compile_commands.json
that is expected to be used by clangdcompile_commands.json
that corresponds to the source file:{
"directory": "...",
"command": "...",
"file": "..."
}
It would also be helpful to perform "go to source" for some symbol from standard C++ library that can be resolved and check the full path to the header file - is it from the correct compiler installation?
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
We are using clangd to analysis openharmony code, so we have to compile openharmony master code.
So, the first step is building openharmony using command like "./build.sh --product-name rk3568 --gn-flags=--export-compile-commands". This can also generate compile_commands.json in out/rk3568. The second step is using clangd in vscode.
Thanks, I managed to reproduce the issue on Ubuntu 23.04 and prepared an (at least temporary) workaround. The workaround is adding a $ROOT/.clangd
file (see below) but the extended debugging steps are provided in case something goes wrong.
Here are the debugging steps (assuming $ROOT
is the repo checkout root), see the official documentation on discoverability of system headers for the details:
./build.sh --product-name rk3568 --gn-flags=--export-compile-commands
)$ROOT/out/rk3568/compile_commands.json
$ROOT/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clangd --log=info --check=$ROOT/applications/standard/contacts_data/ability/account/src/account_data_collection.cpp
Failed to find compilation database ...
Generic fallback command is: /usr/lib/llvm-15/bin/clang ...
compile_commands.json
or build/compile_commands.json
in any of the directories from the account_data_collection.cpp
file up to the root directory$ROOT/out/rk3568/compile_commands.json
as $ROOT/compile_commands.json
Loaded compilation database from $ROOT/compile_commands.json
Compile command from CDB is: ../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang++ --driver-mode=g++ ...
...
[no_member] Line 16: in included file: no member named 'nullptr_t' in the global namespace
...
All checks completed, 4 errors
-v
option inserted right after clang++ prints a huge list of options passed to in-process cc1, with -internal-isystem ../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/../include/libcxx-ohos/include/c++/v1 -internal-isystem /usr/lib/llvm-15/lib/clang/15.0.7/include -internal-externc-isystem obj/third_party/musl/usr/include/arm-linux-ohos -internal-externc-isystem obj/third_party/musl/include -internal-externc-isystem obj/third_party/musl/usr/include
near its end - these options can be added to the command from compile_commands.json as -Wp,-internal-isystem,/path/to/include,-other-option,-one-more-option
to make it find the system headersFinally, since adding extra options to every command in compile_commands.json is not handy for a quick workaround (but may be the correct fix in general), you can create $ROOT/.clangd
file as suggested here with the contents:
CompileFlags:
Add: "-Wp,-internal-isystem,../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/../include/libcxx-ohos/include/c++/v1,-internal-isystem,/usr/lib/llvm-15/lib/clang/15.0.7/include,-internal-externc-isystem,obj/third_party/musl/usr/include/arm-linux-ohos,-internal-externc-isystem,obj/third_party/musl/include,-internal-externc-isystem,obj/third_party/musl/usr/include"
P.S.: In the above .clangd
file I add an include directory from Docker image to the file parsed on host: /usr/lib/llvm-15/lib/clang/15.0.7/include - this looks incorrect but seems to be harmless in my setup.
So, the problem here is clangd failed to find the header file and it also appears in official llvm-15. This workaround is ok here.
My question is that does the upstream solve this problem? If not, maybe wen can solve it in llvm.
I successfully reproduced the issue. The problem seems to be in this line https://gitee.com/openharmony/third_party_llvm-project/blob/master/clang/lib/Driver/ToolChains/OHOS.cpp#L300:
std::string OHOS::computeSysRoot() const {
...
if (!llvm::sys::fs::exists(SysRoot))
return std::string();
In other ToolChains/
places, VFS
is used, for example here https://gitee.com/openharmony/third_party_llvm-project/blob/master/clang/lib/Driver/ToolChains/Linux.cpp#L360:
std::string Linux::computeSysRoot() const {
...
if (getVFS().exists(AndroidSysRootPath))
return AndroidSysRootPath;
This means that OHOS
toolchain will look for relative path sysroot from its current working directory (here it would be directory from which clangd
is run) and not the one specified by VFS (here it would be the one specified in compile_commands.json
). While there are some places in ToolChains/
directory in upstream where llvm::sys::fs::...
methods are used instead of accessing through getVFS()
, it is unclear whether it is actually wrong there or whether it really matters. This specific fix in OHOS
works for the example file in this issue, so I will prepare PR that changes specified above OHOS
code, which should fix the problems.
登录 后才可以发表评论