ccls: ccls should error when the (default) resource directory does not exist

Observed behavior

The getDefaultResourceDirectory returns a compile-time value CLANG_RESOURCE_DIRECTORY. When using binary packages this will almost never point to the correct value. When this directory does not exist ccls silently continues.

Expected behavior

I would expect ccls to error out and tell the user to point it to an appropriate resource directory.

Steps to reproduce

  1. Use ccls with default settings from VS Code on Macos
  2. It doesn’t work correctly
  3. Search for hours for a fix and find out that the ‘automatically supplied value by ccls’ is meaningless.

System information

$ ccls --version
Homebrew ccls version <unknown>
clang version 13.0.0
  • OS: Macos Catalina
  • Editor: VS Code
  • Language client (and version): No idea

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Comments: 27 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Homebrew ccls now uses a more stable resource dir path that should only “break” when Homebrew llvm itself gets version-bumped (which I gather requires a ccls rebuild anyway). Revisions at the formula level (like changes to the build process) should no longer break things.

FYI: we’re bumping LLVM to 13.0.1 in Homebrew/homebrew-core#94339.

CI caught the stale reference to the old resource-dir, which contained a reference to 13.0.0 when it should now point to 13.0.1.

The PR now includes a rebuild for ccls to make sure installations of ccls are not broken by upgrading LLVM. (Only for Homebrew-installed ccls, of course. You’ll need to rebuild ccls yourself after upgrading LLVM if you built it yourself against Homebrew llvm.)

Ah ok, then I’ll put up a PR after my lunch. : 😁

there’s that pesky version number at the end to deal with, even if we use opt_prefix

That’s fine; ccls always needs to be rebuilt with major version bumps to LLVM anyway.

Yes, I thought of that as well. It might be a good idea. A downside is that the contents of that directory (for my ccls which is built with Clang 11 I think) is 4.4M or 108,000 lines of code in about 124 files. So, not insubstantial. Also it would add a bit of time to ccls startup.

Still it might be worthwhile, just to get rid of this confusion.

Alternatively maybe the problem is that the ccls build/install should not be attempting to re-use the resource directory from the clang it was built with, and should ALWAYS make a local copy (as part of its install step for example) and be using that instead.

Barring either of these enhancements, I think that package build control files (like the homebrew formula you point to) must do extra work. Simply running “make install” and calling it a package is insufficient for ccls.

Exactly. As I said, a ccls package should provide those files as part of its package, and the ccls binary in the package should be configured to look for those files in the package directory. A correct package for ccls should have files something like:

bin/ccls
share/ccls/include/inttypes.h
share/ccls/include/stdarg.h
 ...

(of course the exact paths are not important) and the ccls binary here should have its resourceDir value hardcoded to look in share/ccls.

Every compiler comes with its own set of internal headers, and those internal headers are specific to that compiler, and even to that VERSION of that compiler. Because these headers are part of the compiler, they don’t even have to be actual valid C code: they can be any form at all.

Consider this: suppose you compile ccls with libclang version 5 which does not have a feature F. Then you install AppleClang version 6 which does have feature F, and in fact the resource files that come with version 6 make use of feature F so that they won’t compile properly with version 5. Now if you point ccls to the resource files for version 6 it will fail, because ccls is using version 5.