cquery icon indicating copy to clipboard operation
cquery copied to clipboard

Cquery header file "file not found"

Open girvain opened this issue 6 years ago • 3 comments

Hi, I have been getting this error from the syntax checker using cquery. I only get it when i split my project into src and include folders. I am using cmake and using a build dir. When i just use a build dir and run cmake and make in there and bung all the .cpp and .h files in the project folder it works perfectly. Another weird part is that cquery its self works fine with the include folder for jumping to definition etc and i still have code completion, it's just the syntax highlighting error.

If any one has any ideas why this is it would be greatly appreciated.

Thanks

girvain avatar Jun 19 '18 00:06 girvain

Could you post the compile_commands.json and the cquery stderr? Set the cquery-extra-args defcustom to(list "--log-all-to-stderr") to get verbose logs in the stderr buffer.

You can also try and disable the system include searching via in emacs-cquery by setting the cquery-extra-init-params defcustom to (list :discoverSystemIncludes :json-false). It's fixed some other issues like #691, although this does sound a little different.

jaelsasser avatar Jun 19 '18 03:06 jaelsasser

There is nothing in the cquery stderr buffer initially. After I put in what you said if outputs this

( 5.078s) [stdout ] timer.cc:35 | [e2e] Running textDocument/codeAction took 0.175ms ( 5.078s) [stdin ] lsp.cc:25 | RecordPath: client=/Users/gavinross/array_stuff/src/Arrays.cpp, normalized=/Users/gavinross/array_stuff/src/Arrays.cpp ( 5.079s) [stdout ] timer.cc:35 | [e2e] Running textDocument/hover took 0.129ms ( 6.173s) [stdin ] lsp.cc:25 | RecordPath: client=/Users/gavinross/array_stuff/src/Arrays.cpp, normalized=/Users/gavinross/array_stuff/src/Arrays.cpp ( 6.173s) [stdout ] timer.cc:35 | [e2e] Running textDocument/documentHighlight took 0.134ms ( 6.175s) [stdin ] lsp.cc:25 | RecordPath: client=/Users/gavinross/array_stuff/src/Arrays.cpp, normalized=/Users/gavinross/array_stuff/src/Arrays.cpp ( 6.175s) [stdout ] timer.cc:35 | [e2e] Running textDocument/codeAction took 0.157ms

Here is the compile_commands.json

[ { "directory": "/Users/gavinross/array_stuff/build", "command": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -I/Users/gavinross/array_stuff/include -std=gnu++11 -o CMakeFiles/ArrayStuff.dir/src/ArrayStuff.cpp.o -c /Users/gavinross/array_stuff/src/ArrayStuff.cpp", "file": "/Users/gavinross/array_stuff/src/ArrayStuff.cpp" }, { "directory": "/Users/gavinross/array_stuff/build", "command": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -I/Users/gavinross/array_stuff/include -std=gnu++11 -o CMakeFiles/ArrayStuff.dir/src/Arrays.cpp.o -c /Users/gavinross/array_stuff/src/Arrays.cpp", "file": "/Users/gavinross/array_stuff/src/Arrays.cpp" } ]

I also tried that you said with the config file with the same results. I thought the error might actually be with flycheck so I tried to set a .dir-locals variable and still couldn't get any results.

girvain avatar Jun 19 '18 10:06 girvain

I had similar issues with unresolved includes in header files in my project's include directory. They were caused by cquery choosing the "wrong" compilation arguments for the headers (which were missing some include folders).

I traced this down to cquery's heuristic for determining the "best matching" entry for headers from compile_commands.json entries, and found that it doesn't work well in projects that use separate include and source directories.

See ComputeGuessScore() in cquery's src/project.cc. It checks for matching prefix and matching postfix. The prefix matching will work well if the header and src are in the same directory. If not (e.g. "src/path/to/my_file.cc" and "inc/path/to/my_file.h"), the matching score will be pretty poor.

I modified ComputeGuessScore() to take into account a "common middle", as well, and my problems disappeared. Naive implementation with potential for optimization:

int ComputeGuessScore(const std::string& a, const std::string& b) {
  const int kMatchPrefixWeight = 100;
  const int kMismatchDirectoryWeight = 100;
  const int kMatchPostfixWeight = 1;

  int score = 0;
  size_t i = 0;

  // Increase score based on matching prefix.
  for (i = 0; i < a.size() && i < b.size(); ++i) {
    if (a[i] != b[i])
      break;
    score += kMatchPrefixWeight;
  }
  size_t common_prefix = i;

  // Reduce score based on mismatched directory distance.
  for (size_t j = i; j < a.size(); ++j) {
    if (a[j] == '/')
      score -= kMismatchDirectoryWeight;
  }
  for (size_t j = i; j < b.size(); ++j) {
    if (b[j] == '/')
      score -= kMismatchDirectoryWeight;
  }

  // Common case of include and src directories: Some different prefix and
  // ending but common middle.
  size_t common_middle = 0;
  size_t common_middle_dirs = 0;
  for (i = common_prefix; i < a.size(); ++i) {
    for (size_t j = common_prefix; j < b.size(); ++j) {
      size_t common = 0;
      size_t middle_dirs = 0;
      for (; i + common < a.size() && j + common < b.size(); ++common) {
        if (b[j + common] != a[i + common])
          break;
        if (a[i + common] == '/')
          ++middle_dirs;
      }
      common_middle = std::max(common_middle, common);
      common_middle_dirs = std::max(common_middle_dirs, middle_dirs);
    }
  }
  score += common_middle * kMatchPrefixWeight;
  score += common_middle_dirs * kMismatchDirectoryWeight;

  // Increase score based on common ending. Don't increase as much as matching
  // prefix or directory distance.
  for (size_t offset = 1; offset <= a.size() && offset <= b.size(); ++offset) {
    if (a[a.size() - offset] != b[b.size() - offset])
      break;
    score += kMatchPostfixWeight;
  }

  return score;
}

betasheet avatar Jul 17 '19 09:07 betasheet