YouCompleteMe找不到本地头文件 [英] YouCompleteMe can't find local header files

查看:103
本文介绍了YouCompleteMe找不到本地头文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有一个结构如此的项目

 项目|| ---- src/|||| ---- test.cpp|| ---- include/|||| ---- test.hpp|| ----.ycm_extra_conf.py 

但是当 test.hpp

中包含 test.hpp 时,我无法让YouCompleteMe识别

  #include"test.hpp" 

这是我的:YcmDebugInfo

的输出

 打印YouCompleteMe调试信息...-客户端日志文件:/tmp/ycm_tcrryhfo.log-服务器Python解释器:/usr/bin/python2.7-服务器Python版本:2.7.14-服务器具有Clang支持,编译为:True-lang版本:3.版本3.9.1(标签/RELEASE_391/最终)-找到并加载了额外的配置文件-额外的配置路径:/home/jake/project/.ycm_extra_conf.py-C系列完成器调试信息:-编译数据库路径:无-标志:['-std = c ++ 11','-x','c ++','-Wall','-I','include','-isystem','/usr/include','-resource-dir =/home/jake/.local/share/nvim/plugged/YouCompleteMe/third_party/ycmd/ycmd/../clang_includes','-fspell-checking']-服务器运行在:http://127.0.0.1:59337-服务器进程ID:21577-服务器日志文件:-/tmp/ycmd_59337_stdout_kndkmx3g.log-/tmp/ycmd_59337_stderr__xriaszp.log 

服务器日志文件中没有错误,但是客户端日志文件中有一些最终导致此错误的错误:

  Traceback(最近一次通话最近):文件/home/jake/.local/share/nvim/plugged/YouCompleteMe/autoload/../python/ycm/client/base_request.py",第 214 行,在 HandleServerException 中屈服在CheckIfServerIsReady中,文件"/home/jake/.local/share/nvim/plugged/YouCompleteMe/autoload/../python/ycm/youcompleteme.py",第237行'准备好' )GetDataFromHandler中的文件"/home/jake/.local/share/nvim/plugged/YouCompleteMe/autoload/../python/ycm/client/base_request.py",第68行超时 ) )文件"/home/jake/.local/share/nvim/plugged/YouCompleteMe/autoload/../python/ycm/client/base_request.py",行180,在JsonFromFuture中响应= future.result()结果是文件"/usr/lib64/python3.4/concurrent/futures/_base.py",第402行返回self .__ get_result()__get_result中的文件"/usr/lib64/python3.4/concurrent/futures/_base.py",第354行引发 self._exception文件"/home/jake/.local/share/nvim/plugged/YouCompleteMe/autoload/../python/ycm/unsafe_thread_pool_executor.py",第43行,正在运行结果= self.fn(* self.args,** self.kwargs)在请求中,文件"/home/jake/.local/share/nvim/plugged/YouCompleteMe/third_party/ycmd/third_party/requests/requests/sessions.py"resp = self.send(准备,** send_kwargs)发送中的文件"/home/jake/.local/share/nvim/plugged/YouCompleteMe/third_party/ycmd/third_party/requests/requests/sessions.py",第576行r = adapter.send(request,** kwargs)发送中的文件"/home/jake/.local/share/nvim/plugged/YouCompleteMe/third_party/ycmd/third_party/requests/requests/adapters.py",第437行引发ConnectionError(e,request = request)request.exceptions.ConnectionError:HTTPConnectionPool(host ='127.0.0.1',port = 34155):url超过了最大重试次数:/ready(由NewConnectionError('< requests.packages.urllib3.connection.HTTPConnection object at 0x7f32a77aa048>引起):无法建立新的连接:[Errno 111]连接被拒绝',)) 

除此之外,一切似乎都可以正常运行,尽管它会在自动完成时提供超出范围的变量作为建议(建议使用不同类的成员变量).

我遵循了完整的安装指南,并将外部clang设置为/usr/lib/libclang.so

我不知道是什么原因造成的.

解决方案

默认的 .ycm_extra_conf.py 不在附近的 include 目录中查找标头.

此查找是在 JDevlieghere的配置中完成的,我还为包含路径根添加了一个标志(在函数 FlagsForInclude 中):

 导入操作系统导入os.path导入fnmatch导入日志导入ycm_core汇入BASE_FLAGS = ['-墙','-Wextra','-Werror','-Wlong-long-long','-Wno-variadic-macros','-fexceptions','-ferror-limit = 10000','-DNDEBUG','-std = c ++ 1z','-xc ++','-I/usr/lib/','-I/usr/include/']SOURCE_EXTENSIONS = ['.cpp','.cxx','.cc','.C','.m','.毫米']SOURCE_DIRECTORIES = ['src','lib']HEADER_EXTENSIONS = ['.H','.hxx','.hpp','.hh']HEADER_DIRECTORIES = ['包括']BUILD_DIRECTORY ='build';def IsHeaderFile(文件名):扩展名= os.path.splitext(文件名)[1]在HEADER_EXTENSIONS中返回扩展名def GetCompilationInfoForFile(数据库,文件名):如果IsHeaderFile(filename):basename = os.path.splitext(filename)[0]在SOURCE_EXTENSIONS中进行扩展:#通过替换扩展名从源文件获取信息.replace_file =基本名称+扩展名如果os.path.exists(replacement_file):编译信息=数据库.GetCompilationInfoForFile(替换文件)如果compiling_info.compiler_flags_:返回compilation_info#如果未成功,请尝试使用可能的源目录替换可能的标头目录.HEADER_DIRECTORIES中的header_dir:对于SOURCE_DIRECTORIES中的source_dir:src_file =替换文件.replace(header_dir,source_dir)如果os.path.exists(src_file):编译信息=数据库.GetCompilationInfoForFile(src_file)如果compiling_info.compiler_flags_:返回compilation_info不返回返回database.GetCompilationInfoForFile(文件名)def FindNearest(路径,目标,build_folder =无):候选人= os.path.join(路径,目标)if(os.path.isfile(候选)或os.path.isdir(候选)):logging.info(在" +候选位置找到最近的"+目标+"返回候选人;parent = os.path.dirname(os.path.abspath(path));if(父==路径):引发RuntimeError(找不到目标+");如果(build_folder):候选人= os.path.join(父母,build_folder,目标)if(os.path.isfile(候选)或os.path.isdir(候选)):logging.info(在构建文件夹中的"+候选位置"找到最近的"+目标+")返回候选人;返回FindNearest(父,目标,build_folder)def MakeRelativePathsInFlagsAbsolute(flags,working_directory):如果不是working_directory:返回列表(标志)new_flags = []make_next_absolute = Falsepath_flags = ['-isystem','-I','-iquote','--sysroot =']对于标志中的标志:new_flag =标志如果make_next_absolute:make_next_absolute = False如果不是flag.startswith('/'):new_flag = os.path.join(工作目录,标志)对于path_flags中的path_flag:如果标志== path_flag:make_next_absolute = True休息如果flag.startswith(path_flag):路径=标志[len(path_flag):]new_flag = path_flag + os.path.join(工作目录,路径)休息如果new_flag:new_flags.append(new_flag)返回new_flagsdef FlagsForClangComplete(root):尝试:clang_complete_path = FindNearest(root,'.clang_complete')clang_complete_flags = open(clang_complete_path,'r').read().splitlines()返回clang_complete_flags除了:不返回def FlagsForInclude(root):尝试:include_path = FindNearest(root,'include')标志= []对于os.walk(include_path)中的dirroot,dirnames,文件名:标志=标志+ ["-I" + dirroot]对于dirnames中的dir_path:real_path = os.path.join(dirroot, dir_path)标志=标志+ ["-I" + real_path]返回标志除了:不返回def FlagsForCompilationDatabase(root,filename):尝试:#next函数的最后一个参数是构建文件夹的名称#超出源项目Compilation_db_path = FindNearest(root,'compile_commands.json',BUILD_DIRECTORY)Compilation_db_dir = os.path.dirname(compilation_db_path)logging.info(将编译数据库目录设置为" + compiling_db_dir)Compilation_db = ycm_core.CompilationDatabase(compilation_db_dir)如果没有,则为:logging.info(找到了编译数据库文件,但无法加载")不返回Compilation_info = GetCompilationInfoForFile(compilation_db,文件名)如果没有,则为logging.info(编译数据库中没有" + filename +的编译信息")不返回返回MakeRelativePathsInFlagsAbsolute(Compilation_info.compiler_flags_,编译信息(compiler_working_dir_)除了:不返回def FlagsForFile(文件名):根= os.path.realpath(文件名);Compilation_db_flags = FlagsForCompilationDatabase(根目录,文件名)如果compiling_db_flags:final_flags =编译_db_flags别的:final_flags = BASE_FLAGSclang_flags = FlagsForClangComplete(根)如果clang_flags:final_flags = final_flags + clang_flagsinclude_flags = FlagsForInclude(根)如果include_flags:final_flags = final_flags + include_flags返回 {'标志':final_flags,'do_cache':正确} 

I currently have a project that is structured as so

project
|
|----src/
|   |
|   |----test.cpp
|
|----include/
|   |
|   |----test.hpp
|
|----.ycm_extra_conf.py

But I can't get YouCompleteMe to recognize test.hpp when it's include in test.cpp

#include "test.hpp"

This is the output of my :YcmDebugInfo

Printing YouCompleteMe debug information...                                                                                                                                                                                                   
-- Client logfile: /tmp/ycm_tcrryhfo.log                                                                                                                                                                                                      
-- Server Python interpreter: /usr/bin/python2.7                                                                                                                                                                                              
-- Server Python version: 2.7.14                                                                                                                                                                                                              
-- Server has Clang support compiled in: True                                                                                                                                                                                                 
-- Clang version: clang version 3.9.1 (tags/RELEASE_391/final)                                                                                                                                                                                
-- Extra configuration file found and loaded                                                                                                                                                                                                  
-- Extra configuration path: /home/jake/project/.ycm_extra_conf.py                                                                                                                                                                          
-- C-family completer debug information:                                                                                                                                                                                                      
--   Compilation database path: None                                                                                                                                                                                                          
--   Flags: ['-std=c++11', '-x', 'c++', '-Wall', '-I', 'include', '-isystem', '/usr/include', '-resource-dir=/home/jake/.local/share/nvim/plugged/YouCompleteMe/third_party/ycmd/ycmd/../clang_includes', '-fspell-checking']                 
-- Server running at: http://127.0.0.1:59337                                                                                                                                                                                                  
-- Server process ID: 21577                                                                                                                                                                                                                   
-- Server logfiles:                                                                                                                                                                                                                           
--   /tmp/ycmd_59337_stdout_kndkmx3g.log                                                                                                                                                                                                      
--   /tmp/ycmd_59337_stderr__xriaszp.log

There are no errors present in the server log files, but the client logfile has a few errors that ultimately begins with this:

Traceback (most recent call last):                                                                                                                                                                                                            
  File "/home/jake/.local/share/nvim/plugged/YouCompleteMe/autoload/../python/ycm/client/base_request.py", line 214, in HandleServerException                                                                                                 
yield                                                                                                                                                                                                                                     
  File "/home/jake/.local/share/nvim/plugged/YouCompleteMe/autoload/../python/ycm/youcompleteme.py", line 237, in CheckIfServerIsReady                                                                                                        
'ready' )                                                                                                                                                                                                                                 
  File "/home/jake/.local/share/nvim/plugged/YouCompleteMe/autoload/../python/ycm/client/base_request.py", line 68, in GetDataFromHandler                                                                                                     
timeout ) )                                                                                                                                                                                                                               
  File "/home/jake/.local/share/nvim/plugged/YouCompleteMe/autoload/../python/ycm/client/base_request.py", line 180, in JsonFromFuture                                                                                                        
response = future.result()                                                                                                                                                                                                                
  File "/usr/lib64/python3.4/concurrent/futures/_base.py", line 402, in result                                                                                                                                                                
return self.__get_result()                                                                                                                                                                                                                
  File "/usr/lib64/python3.4/concurrent/futures/_base.py", line 354, in __get_result                                                                                                                                                          
raise self._exception                                                                                                                                                                                                                     
  File "/home/jake/.local/share/nvim/plugged/YouCompleteMe/autoload/../python/ycm/unsafe_thread_pool_executor.py", line 43, in run                                                                                                            
result = self.fn(*self.args, **self.kwargs)                                                                                                                                                                                               
  File "/home/jake/.local/share/nvim/plugged/YouCompleteMe/third_party/ycmd/third_party/requests/requests/sessions.py", line 468, in request                                                                                                  
resp = self.send(prep, **send_kwargs)                                                                                                                                                                                                     
  File "/home/jake/.local/share/nvim/plugged/YouCompleteMe/third_party/ycmd/third_party/requests/requests/sessions.py", line 576, in send                                                                                                     
r = adapter.send(request, **kwargs)                                                                                                                                                                                                       
  File "/home/jake/.local/share/nvim/plugged/YouCompleteMe/third_party/ycmd/third_party/requests/requests/adapters.py", line 437, in send                                                                                                     
raise ConnectionError(e, request=request)                                                                                                                                                                                                 
requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', port=34155): Max retries exceeded with url: /ready (Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x7f32a77aa048>: Failed to establish a new connection: [Errno 111] Connection refused',))

Other than this everything seems to be working although it will offer variables that are out of scope as suggestions when autocompleting (Suggests member variables of different classes).

I followed the full installation guide and set my external clang to /usr/lib/libclang.so

I have no idea what's causing this.

解决方案

The default .ycm_extra_conf.py doesn't look for headers in nearby include directories.

This lookup is done in JDevlieghere's configuration, which I adapted to also add a flag for the include path root (in function FlagsForInclude):

import os
import os.path
import fnmatch
import logging
import ycm_core
import re

BASE_FLAGS = [
        '-Wall',
        '-Wextra',
        '-Werror',
        '-Wno-long-long',
        '-Wno-variadic-macros',
        '-fexceptions',
        '-ferror-limit=10000',
        '-DNDEBUG',
        '-std=c++1z',
        '-xc++',
        '-I/usr/lib/',
        '-I/usr/include/'
        ]

SOURCE_EXTENSIONS = [
        '.cpp',
        '.cxx',
        '.cc',
        '.c',
        '.m',
        '.mm'
        ]

SOURCE_DIRECTORIES = [
        'src',
        'lib'
        ]

HEADER_EXTENSIONS = [
        '.h',
        '.hxx',
        '.hpp',
        '.hh'
        ]

HEADER_DIRECTORIES = [
        'include'
        ]

BUILD_DIRECTORY = 'build';

def IsHeaderFile(filename):
    extension = os.path.splitext(filename)[1]
    return extension in HEADER_EXTENSIONS

def GetCompilationInfoForFile(database, filename):
    if IsHeaderFile(filename):
        basename = os.path.splitext(filename)[0]
        for extension in SOURCE_EXTENSIONS:
            # Get info from the source files by replacing the extension.
            replacement_file = basename + extension
            if os.path.exists(replacement_file):
                compilation_info = database.GetCompilationInfoForFile(replacement_file)
                if compilation_info.compiler_flags_:
                    return compilation_info
            # If that wasn't successful, try replacing possible header directory with possible source directories.
            for header_dir in HEADER_DIRECTORIES:
                for source_dir in SOURCE_DIRECTORIES:
                    src_file = replacement_file.replace(header_dir, source_dir)
                    if os.path.exists(src_file):
                        compilation_info = database.GetCompilationInfoForFile(src_file)
                        if compilation_info.compiler_flags_:
                            return compilation_info
        return None
    return database.GetCompilationInfoForFile(filename)

def FindNearest(path, target, build_folder=None):
    candidate = os.path.join(path, target)
    if(os.path.isfile(candidate) or os.path.isdir(candidate)):
        logging.info("Found nearest " + target + " at " + candidate)
        return candidate;

    parent = os.path.dirname(os.path.abspath(path));
    if(parent == path):
        raise RuntimeError("Could not find " + target);

    if(build_folder):
        candidate = os.path.join(parent, build_folder, target)
        if(os.path.isfile(candidate) or os.path.isdir(candidate)):
            logging.info("Found nearest " + target + " in build folder at " + candidate)
            return candidate;

    return FindNearest(parent, target, build_folder)

def MakeRelativePathsInFlagsAbsolute(flags, working_directory):
    if not working_directory:
        return list(flags)
    new_flags = []
    make_next_absolute = False
    path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
    for flag in flags:
        new_flag = flag

        if make_next_absolute:
            make_next_absolute = False
            if not flag.startswith('/'):
                new_flag = os.path.join(working_directory, flag)

        for path_flag in path_flags:
            if flag == path_flag:
                make_next_absolute = True
                break

            if flag.startswith(path_flag):
                path = flag[ len(path_flag): ]
                new_flag = path_flag + os.path.join(working_directory, path)
                break

        if new_flag:
            new_flags.append(new_flag)
    return new_flags


def FlagsForClangComplete(root):
    try:
        clang_complete_path = FindNearest(root, '.clang_complete')
        clang_complete_flags = open(clang_complete_path, 'r').read().splitlines()
        return clang_complete_flags
    except:
        return None

def FlagsForInclude(root):
    try:
        include_path = FindNearest(root, 'include')
        flags = []
        for dirroot, dirnames, filenames in os.walk(include_path):
            flags = flags + ["-I" + dirroot]
            for dir_path in dirnames:
                real_path = os.path.join(dirroot, dir_path)
                flags = flags + ["-I" + real_path]
        return flags
    except:
        return None

def FlagsForCompilationDatabase(root, filename):
    try:
        # Last argument of next function is the name of the build folder for
        # out of source projects
        compilation_db_path = FindNearest(root, 'compile_commands.json', BUILD_DIRECTORY)
        compilation_db_dir = os.path.dirname(compilation_db_path)
        logging.info("Set compilation database directory to " + compilation_db_dir)
        compilation_db =  ycm_core.CompilationDatabase(compilation_db_dir)
        if not compilation_db:
            logging.info("Compilation database file found but unable to load")
            return None
        compilation_info = GetCompilationInfoForFile(compilation_db, filename)
        if not compilation_info:
            logging.info("No compilation info for " + filename + " in compilation database")
            return None
        return MakeRelativePathsInFlagsAbsolute(
                compilation_info.compiler_flags_,
                compilation_info.compiler_working_dir_)
    except:
        return None

def FlagsForFile(filename):
    root = os.path.realpath(filename);
    compilation_db_flags = FlagsForCompilationDatabase(root, filename)
    if compilation_db_flags:
        final_flags = compilation_db_flags
    else:
        final_flags = BASE_FLAGS
        clang_flags = FlagsForClangComplete(root)
        if clang_flags:
            final_flags = final_flags + clang_flags
        include_flags = FlagsForInclude(root)
        if include_flags:
            final_flags = final_flags + include_flags
    return {
            'flags': final_flags,
            'do_cache': True
            }

这篇关于YouCompleteMe找不到本地头文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆