MaskRay / ccls

C/C++/ObjC language server supporting cross references, hierarchies, completion and semantic highlighting
Apache License 2.0
3.73k stars 254 forks source link

Indexing in external headers #912

Open dscole opened 1 year ago

dscole commented 1 year ago

Here are some things you should try before filing a bug report:

Observed behavior

I have a project that I build with conan+cmake+ninja and I have ccls use the generated compile_commands.json. ccls is able to correctly index everything in the project and it's working great. The issue starts when I try to browse included headers from external projects, for example dependencies in the conan cache directory. So when I have a header file in my project:

// my_header.h
#include <dep_lib/some_header.h>
class MyClass{
    TypeFromDepLib a;
};

ccls provides all the features I need while I'm editing this file. When I try to jump to definition of TypeFromDepLib it correctly jumps to dep_lib/some_header.h inside the external conan cache dir. But then ccls isn't able to correctly index some_header.h complaining about various unknown header files and unknown symbols. From what I understand (from the ccls log, generated with -v=2) the compilation flags ccls got from the compile_commands.json that it used to index my_header.h aren't used when indexing dep_lib/some_header.h. This is from the ccls log for the original file (edited for brevity):

 14:35:54 preamble     sema_manager.cc:779 I create session for /home/dscole/my_project/src/my_file.h
  /home/dscole/.conan/data/clang/13.0.1/_/_/package/2201725ed6c2736f243c00af939498ce6c18440d/bin/clang++ --driver-mode=g++ -isystem /home/dscole/.conan/data/dep_lib/1.2.5/_/_/package/6bc750131bf23241bc02610b3b4719d94f9888b4/include -Wall -Wextra -Werror -stdlib=libstdc++ -O3 -g -DN\
DEBUG -pthread -std=gnu++17 -o src/CMakeFiles/my_lib.dir/my_header.cpp.o -c /home/dscole/my_project/src/my_file.cpp -working-directory=/home/dscole/my_project/build/clang13_Release

And this is for the external header:

14:36:25 preamble     sema_manager.cc:779 I create session for /home/dscole/.conan/data/dep_lib/1.2.5/_/_/package/6bc750131bf23241bc02610b3b4719d94f9888b4/include/dep_lib/some_header.h
  clang -xobjective-c++-header /home/dscole/.conan/data/dep_lib/1.2.5/_/_/package/6bc750131bf23241bc02610b3b4719d94f9888b4/include/dep_lib/some_header.h -working-directory=/home/dscole/my_project

It's easy to see that none of the compilation flags from the original file made to the indexing of the external header.

Expected behavior

I'd expect ccls to use the same compilation flags for the external header file as it used when indexing the original file from which it was included. So, keep some sort of cache of all included header files external to the project and when indexing the project use the flags it was using when first encountering it as an included file. This would allow it to actually recognize the includes and symbols in that file as well.

Steps to reproduce

  1. Have 2 projects, one with compile_commands.json, "project-1", and another without, "project-2" which is header only.
  2. Have a header file in "project-1" include a header file in "project-2".
  3. compile_commands.json would include a flag such as -isystem /path/to/project-1.
  4. Index "proejct-1"
  5. Use jump-to-definition on a symbol in an indexed file in project-1 that's defined in project-2.
  6. Try to navigate or get information about symbols in that jumped-to-file in project-2.

System information