ccls icon indicating copy to clipboard operation
ccls copied to clipboard

CCLS jumps to host libs instead of the target cross-platform libs

Open pvonmoradi opened this issue 3 years ago • 5 comments

Observed behavior

I'm using CCLS as a LSP (with coc-nvim) as the auto-complete framework for embedded development.
Using platformio or makefiles, I'm generating the compile_commands.json file with bear make.

It works nicely for the most part. Problem is, for stdio functions (printf, sprintf, etc), goto-definition jumps to /usr/include instead of the corresponding path in the cross-compiler's own libs. This causes the linter to show errors and warnings erroneously (as if the source is to be compiled for the host(Intel x86 CPU) not the target (Arm Cortex-M MCU).

I've observed this behavior when the cross-compiler was arm-none-eabi-gcc (stm32f103, nrf52832) and xtensa (esp8266).
For example here is the compile_commands.json for nRF52832 generated with bear with PIO-ArduinoHAL framework. https://dpaste.com/2GTYHLNF4

GIF

https://user-images.githubusercontent.com/1058151/106142907-4cafc900-6187-11eb-8dc7-32864a97d30a.mp4

System information

$ ccls --version
ccls version <unknown>
clang version 10.0.0-4ubuntu1~18.04.2
  • OS: Xubuntu 18.04
  • Editor: vim (coc-nvim)

pvonmoradi avatar Jan 28 '21 13:01 pvonmoradi

ccls doesn't use GCC, at all. It uses clang/llvm. So, there's no way for ccls to know (on its own) that the GCC variant you're using is a cross-compiler and where to find the system headers.

You can set ccls options that force the compiler to look in alternate locations for system headers: this is what I do. Unfortunately I don't know how to configure vim so all I can do is provide my Emacs setup that does this:

(setq ccls-initialization-options
      `(:clang (:extraArgs ["--gcc-toolchain=/path/to/gcc/install" "--sysroot=/path/to/target/sysroot"])))

I'm not sure if you can add these in the .ccls file, or not. If so that might be simpler.

madscientist avatar Jan 28 '21 16:01 madscientist

@madscientist For vim/CoC, we use a .vim/coc-settings.json in project dir which is like this:

{
  "clangd.enabled": false,
  "languageserver": {
    "ccls": {
      "command": "ccls",
      "filetypes": ["c", "cpp", "cuda", "objc", "objcpp"],
      "rootPatterns": [".ccls", ".ccls-root", "compile_commands.json"],
      "initializationOptions": {
        "cache": {
          "directory": ".ccls-cache"
        },
        "client": {
          "snippetSupport": true
        },
        "highlight": { "lsRanges" : true }
      }
    }
  }
}

But I didn't think that I should change this. Doesn't bear tool figure out that a cross-compiler is used and sets up the proper paths in the compile_commands.json automatically? I mean shouldn't system libs and all paths relevant to the project be inside that compile_commands.json?

pvonmoradi avatar Jan 28 '21 17:01 pvonmoradi

Well, you can look in compile_commands.json and see what's there.

Tools like bear can only track the options that you invoke the compiler with. However, usually those options are not provided explicitly on the command line: usually cross-compilers know intuitively where to look for system headers etc. So, you just run arm-none-eabi-gcc -o armexe armexe.c and you get an ARM executable, and you don't have to add a bunch of specialized command-line options to tell arm-non-eabi-gcc where to find system headers and libraries. Of course there are almost as many different subtle difference in cross-compilation systems as there are people cross-compiling so YMMV.

If that's the way your cross-compilers work, then the magical paths are embedded into the cross-compiler front-end and external tools like make, bear, ccls, etc. never see them, and they won't appear in compile_commands.json.

You'll have to add them yourself, as I've described above.

madscientist avatar Jan 28 '21 18:01 madscientist

I have not done much cross compiling, but.  Can one not ask the compiler et al which directories they use to find header files and libraries? Then it will also adjust to the arguments the user gives to be used by the compiler. Certainly these tools have to know where they look for files? And the proper way would then be to ask the tools, and just by telling ccls which tools to use should be enough to get it right? Am I missing something here?  Yours A Jackson

ajxn avatar Feb 25 '21 14:02 ajxn

I use cmake tool, compile my project, has the same questions.

wangwenqiangGitHub avatar Sep 26 '21 12:09 wangwenqiangGitHub