48 Star 39 Fork 208

OpenHarmony/third_party_llvm-project

 / 详情

[R&D] Clangd failed to resolve symbols

已完成
需求 成员
创建于  
2023-04-23 19:08

【任务描述】
clangd failed to resolve symbols.

Reproduce steps:

  1. compile openharmony code and generate compile_commands.json using ninja
  2. install clangd in vscode and set clangd.path, clangd.arguments
  3. some symbols are missed such as std::make_shared

【解决方案】

【任务来源】

评论 (8)

guzhihao4 创建了任务 2年前
Pavel Kosov 负责人设置为Pavel Kosov 2年前
liuguangfeng 任务状态待办的 修改为进行中 2年前
Pavel Kosov 修改了标题 2年前
Pavel Kosov 修改了描述 2年前
Pavel Kosov 添加协作者Pavel Kosov 2年前
Pavel Kosov 负责人Pavel Kosov 修改为Kulikov Ivan 2年前
Pavel Kosov 取消协作者Pavel Kosov 2年前
展开全部操作日志

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

  • path to clangd binary (absolute or at least from repo root, such as $REPOROOT/out/install/linux-x86_64/clang-dev/bin/clangd)
  • path to the source file
  • path to the compile_commands.json that is expected to be used by clangd
  • a section from compile_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?

Pavel Kosov-kosovpavel Pavel Kosov 成员
回复 Kulikov Ivan 成员
2年前
Pavel Kosov 任务类型任务 修改为需求 2年前
Pavel Kosov 任务状态进行中 修改为待办的 2年前
Pavel Kosov 任务状态待办的 修改为已分解 2年前

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:

  • Compile OHOS inside a Docker container with Ubuntu 20.04 with the above command (./build.sh --product-name rk3568 --gn-flags=--export-compile-commands)
  • Build produces a $ROOT/out/rk3568/compile_commands.json
  • Run clangd in "check" mode in terminal:
    $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
    
    • note the following lines
      Failed to find compilation database ...
      Generic fallback command is: /usr/lib/llvm-15/bin/clang ...
      
    • this error is because clangd cannot find either 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
  • copy or symlink (if possible) $ROOT/out/rk3568/compile_commands.json as $ROOT/compile_commands.json
    • now output should be
      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
      
  • If I use system-provided clangd instead (Ubuntu clangd version 15.0.7), instead of "no member named 'nullptr_t' ..." I got "Line 16: in included file: 'string' file not found" and 12 errors instead of 4
  • Running the "CDB command" printed by clangd with -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 headers
  • Now both prebuilt clangd and system-provided one can parse the file (the debug output ends with "All checks completed, 0 errors")

Finally, 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.

Pavel Kosov-kosovpavel Pavel Kosov 成员
回复 Kulikov Ivan 成员
2年前

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.

Pavel Kosov 任务状态已分解 修改为开发中 2年前
Pavel Kosov 负责人Kulikov Ivan 修改为Kholiavin Nikolai 2年前
openharmony_ci 添加了
 
waiting_for_fix
标签
2年前

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.

登录 后才可以发表评论

状态
负责人
项目
里程碑
分支
开始日期   -   截止日期
-
置顶选项
优先级
预计工期 (小时)
参与者(5)
Kulikov Ivan-kulikov-ivan Pavel Kosov-kosovpavel guzhihao4-guzhihao4 7387629 openharmony ci 1656582662 Kholiavin Nikolai-nkholiavin
C++
1
https://gitee.com/openharmony/third_party_llvm-project.git
git@gitee.com:openharmony/third_party_llvm-project.git
openharmony
third_party_llvm-project
third_party_llvm-project

搜索帮助