MaskRay / ccls

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

Unable to include a header in a subdirectory of include path #868

Closed jg110 closed 2 years ago

jg110 commented 2 years ago

Observed behavior

Attempting to include the Eigen/Dense header fails. This is caused by the path, not the header itself; just creating a dummy file with touch Eigen/Dense is enough to reproduce the issue.

Running clang from the terminal with the following command finishes successfully: clang -I/home/jg110/example-project/eigen3 include/min.hpp

Changing the #include statement in min.hpp to #include <eigen3/Eigen/Dense> finds the file successfully.

I've been able to include other headers without a problem in my project, with the only difference being that these are directly inside the included directory instead of being within a subdirectory (e.g. -I/path/to/project/include successfully finds project/foo.hpp)

Expected behavior

Eigen/Dense should be found.

Steps to reproduce

  1. Create the project as outlined above
  2. Open include/min.hpp in emacs
  3. Observe flycheck error (also visible in the *ccls::stderr* buffer).

System information

jg110 commented 2 years ago

After some further testing, it looks like there are two things that can cause this:

  1. Having a space in the include path. This wasn't in my example, but occurs in my main project. I've tried escaping the spaces with backslashes, and when that didn't work I tried quoting the include paths.
  2. Having the wrong workspace directory. This is probably specific to emacs-ccls rather than ccls itself, but I realized that when I was opening the header file in the include directory, ccls would initialize with example-project/include as the workspace directory and would create the cache in there. When I created example-project/src/main.cpp, the workspace directory was set to the project root and the header file was found successfully.

So 2. seems to be just a quirk from my janky half-project setup used as an example and can probably be ignored.

I finally figured out 1., I hadn't tried just entering the path spaces and all since I interpreted

No whitespace splitting is performed on the argument, thus -I foo cannot be used (use -Ifoo or -I\nfoo for example).

from the docs to mean arguments can't have whitespace in them at all. But that fixed it: just enter the paths without any modification.