hedronvision / bazel-compile-commands-extractor

Goal: Enable awesome tooling for Bazel users of the C language family.
Other
659 stars 109 forks source link

YCM reporting errors not present when code is actually built #178

Open davidzchen opened 5 months ago

davidzchen commented 5 months ago

First of all, thank you for building this wonderful tool and enabling integration with YouCompleteMe for Bazel.

However, I am running into a few issues. YouCompleteMe, using the compile_commands.json generated by bazel-compile-commands-extractor, is reporting error messages that I do not get when I run bazel build on the code. In particular, I am getting errors like these in the source files:

Out-of-line definition of 'Foo' does not match any declaration in 'foo_namespace::Foo' [member_decl_does_not_match]

...as well as "no matching constructor" errors. Curiously, this seems to be happening for all my constructors, all static methods, and some private methods.

Has anyone run into this type of issue or know what the fix is? What information should I provide to help with debugging?

Thank you in advance.

cpsauer commented 5 months ago

Hey David! You're very welcome. Sorry I'm just getting to this--and thanks for giving the tool a go.

I'm not sure offhand, without more info. Is clangd finding the headers? It might also be worth checking its log to make sure it's finding the command? I know there are people using it with YCM--but we're using from VSCode.

The reason for those questions is that I'd have two hypotheses about what might be going wrong. (1) Either YCM isn't finding the compile_commands.json or (2) the compile_commands.json might be wrong and need some target configuration (as in that section of the README)

davidzchen commented 5 months ago

No problem. Thank you for getting back to me.

I am not sure if clangd is finding the headers. How do I find the clangd logs?

I will also put together a repo with a minimal repro case and share that with you to help with debugging.

cpsauer commented 5 months ago

Logs: I'm not sure--we're using from VSCode, but I'll bet it says in their docs somewhere!

@stonebrakert6, are you still using this with YCM? And if so, have you seen anything like this?

stonebrakert6 commented 5 months ago

@davidzchen You can use :YcmToggleLogs and then open the appropriate log file and check its contents to see where errors occur. @cpsauer Yeah I am using YCM and no I don't see any problems mentioned by @davidzchen here is head of my clangd logs

 I[11:19:53.661] clangd version 19.0.0git (https://github.com/llvm/llvm-project babbdad15b8049a6a78087d15a163d897f07d320)
I[11:19:53.661] Features: linux
I[11:19:53.661] PID: 7539
I[11:19:53.661] Working directory: /home/kartik/codeberg/app0
I[11:19:53.661] argv[0]: /opt/git_llvm/bin/clangd
I[11:19:53.661] argv[1]: --log=verbose
I[11:19:53.661] argv[2]: -pretty
I[11:19:53.661] argv[3]: --clang-tidy
I[11:19:53.661] argv[4]: -j=16
I[11:19:53.661] argv[5]: --background-index
I[11:19:53.661] argv[6]: --header-insertion=iwyu
I[11:19:53.661] argv[7]: --completion-style=detailed
I[11:19:53.661] argv[8]: --compile-commands-dir=/home/kartik/codeberg/app0
I[11:19:53.661] argv[9]: -header-insertion-decorators=0
V[11:19:53.661] User config file is /home/kartik/.config/clangd/config.yaml
I[11:19:53.661] Starting LSP over stdin/stdout

My system is Ubuntu 22.04 and I use vim 9.1 But I do want to highlight that I face the following problems.

Need to convert relative paths in compile_commands.json to absolute paths

I have to run a utility to convert the relative paths in compile_commands.json generated by bazel-compile-commands-extractor to absolute paths. If I don't do so, my GoToDefinition and other GoTo... commands just end up in the header file and not the exact source code definition.

I don't know why this happens and if what I do(below) is recommended or not.

Here is what I do

bazel run --config=dbg //:refresh_compile_commands && python3 ~/tools/cc_modify.py compile_commands.json

and here is the source code(in case someone needs it) for cc_modify.py(it just converts relative paths to absolute paths in compile_commands.json)

import re
import subprocess

def replace_pattern(file_name, search_pattern, replacement_pattern):
    # Read the contents of the file
    with open(file_name, 'r') as file:
        file_content = file.read()

    # Perform the replacement using regular expressions
    new_content = re.sub(search_pattern, replacement_pattern, file_content)

    # Write the updated content back to the file
    with open(file_name, 'w') as file:
        file.write(new_content)

# Define the file name
file_name = 'compile_commands.json'

# Read the contents of the file
with open(file_name, 'r') as file:
    file_content = file.read()

# Call the function to replace the first pattern
search_pattern1 = r'"(external/.*?)"'
output_base = subprocess.check_output(['bazel', 'info', 'output_base']).decode('utf-8').strip()
replacement_pattern1 = fr'"{output_base}/\1"'
file_content = re.sub(search_pattern1, replacement_pattern1, file_content)

# Call the function to replace the second pattern
search_pattern2 = r'"bazel-out/(.*?)"'
output_path = subprocess.check_output(['bazel', 'info', 'output_path']).decode('utf-8').strip()
replacement_pattern2 = fr'"{output_path}/\1"'
file_content = re.sub(search_pattern2, replacement_pattern2, file_content)

# Write the updated content back to the file
with open(file_name, 'w') as file:
    file.write(file_content)

3rd party libraries which need rules_foreign_cc don't give completions

e.g liburing which use ./configure && make i.e for which I have liburing.BUILD that looks like this

load("@rules_foreign_cc//foreign_cc:defs.bzl", "configure_make")

filegroup(
    name = "liburing_srcs",
    srcs = glob(["**"]),
)

configure_make(
    name = "liburing",
    args = [
        # "V=1",
        "-j $(nproc)",
    ],
    configure_in_place = True,
    configure_options = [
        "--cc=$$CC",
        "--cxx=$$CXX",
    ],
    env = {
        "CC": "clang",
        "CXX": "clang++",
    },
    lib_source = ":liburing_srcs",
    visibility = ["//visibility:public"],
)

doesn't give completions as the entries are not there in compile_commands.json May be I'll open another issue(and sorry for hijacking the thread) - but is there any plan to support this?

My knowledge of bazel right now is more or less shallow as we just use cmake at our workplace and so my experience is mostly limited to my own personal projects.

davidzchen commented 4 months ago

I created a minimal repro case here: https://github.com/davidzchen/bazel-ycm-test

When foo/file.cc is opened in Vim, YCM highlights many lines as errors as shown below:

Screenshot 2024-04-28 at 15 47 52

Here is my :YcmDebugInfo:

Printing YouCompleteMe debug information...
-- Resolve completions: Up front
-- Client logfile: /var/folders/d3/yj9wzlg96ql05cjzm329d76r0000gn/T/ycm_s03l_h6b.log
-- Server Python interpreter: /opt/homebrew/opt/python@3.12/bin/python3.12
-- Server Python version: 3.12.2
-- Server has Clang support compiled in: True
-- Clang version: clang version 17.0.1 (https://github.com/ycm-core/llvm f0e018b8aadf1be25e3af0daa7a87d505de67957)
-- No extra configuration file found
-- C-family completer debug information:
--   Clangd running
--   Clangd process ID: 70415
--   Clangd executable: ['/Users/dzc/Projects/davidzchen/dotfiles/vim/bundle/YouCompleteMe/third_party/ycmd/third_party/clangd/output/bin/clangd', '-header-insertion-decorators=0', '-resource-dir=/Users/dzc/Projects/davidzchen/dotfiles/vim/bundle/YouCompleteMe/third_party/ycmd/third_party/clang/lib/clang/17.0.1', '-limit-results=500']
--   Clangd logfiles:
--     /var/folders/d3/yj9wzlg96ql05cjzm329d76r0000gn/T/clangd_stderrhpnr9y6h.log
--   Clangd Server State: Initialized
--   Clangd Project Directory: /Users/dzc/Projects/davidzchen/bazel-ycm-test/foo
--   Clangd Open Workspaces: {'/Users/dzc/Projects/davidzchen/bazel-ycm-test/foo'}
--   Clangd Settings: {}
--   Clangd Compilation Command: False
-- Server running at: http://127.0.0.1:63368
-- Server process ID: 70413
-- Server logfiles:
--   /var/folders/d3/yj9wzlg96ql05cjzm329d76r0000gn/T/ycmd_63368_stdout_xebv3sf1.log
--   /var/folders/d3/yj9wzlg96ql05cjzm329d76r0000gn/T/ycmd_63368_stderr_p1l0fz26.log
-- Semantic highlighting supported: True
-- Virtual text supported: True
-- Popup windows supported: True
Press ENTER or type command to continue

Many of the errors seem to be around Abseil, though the code compiles without any issue.

davidzchen commented 4 months ago

FYI I did use @stonebrakert6's script to generate the compile_commands.json, but I am still getting these errors.

davidzchen commented 3 months ago

Is there anything I can provide to help debug this further?

stonebrakert6 commented 3 months ago

hey @davidzchen This is probably NOT the answer you're looking for but I am still posting it anyway.

Disclaimer

I am a newbie at bazel. So can't really explain why toolchain based solution is not working. My dev environment is Linux and the issues I was facing with your project were much different(and way more). Don't want to mention them to avoid noise.

What I did

  1. removed llvm toolchain from WORKSPACE and some other cosmetic changes.
  2. I have created a PR so that you can see the diff

    I have verified all this on MBP(macbook pro) by installing llvm via brew install llvm So essentially the TLDR is

    1. ./setup_clang.sh /usr/local/opt/llvm i.e path to llvm install path(top-level)
    2. ./compile_commands.sh

All this has been inspired from how Envoy is built(for your reference). Do let me know if it works for you(I am assuming you are on MBP).

davidzchen commented 3 months ago

Thanks you very much, @stonebrakert6! I will give this a try and report back.

Yes, I am on MBP (M1 Max running macOS Sonoma 14.4.1).