title: ycm can't find header situated in another directory
body: <p>I use the youcompleteme plugin for autocompletion in vim. However, it appears i can't make it find header files that are not located in the same directory as my source files.
  i have the following architecture :</p>
  <pre><code>root
  ├── include
  │── src
  |.ycm_extra_conf.py
  </code></pre>
  <p>my .ycm_extra_conf.py is as follow :</p>
  <pre><code>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/',                                                                  
          '-I include',                                                                       
          '-I src'                                                                            
          ]                                                                                   
                                                                                              
  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(&quot;Found nearest &quot; + target + &quot; at &quot; + candidate)                        
          return candidate;                                                                   
                                                                                              
      parent = os.path.dirname(os.path.abspath(path));                                        
      if(parent == path):                                                                     
          raise RuntimeError(&quot;Could not find &quot; + target);                                     
                                                                                              
      if(build_folder):                                                                       
          candidate = os.path.join(parent, build_folder, target)                              
          if(os.path.isfile(candidate) or os.path.isdir(candidate)):                          
              logging.info(&quot;Found nearest &quot; + target + &quot; in build folder at &quot; + 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 + [&quot;-I&quot; + dirroot]                                                
              for dir_path in dirnames:                                                       
                  real_path = os.path.join(dirroot, dir_path)                                 
                  flags = flags + [&quot;-I&quot; + 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(&quot;Set compilation database directory to &quot; + compilation_db_dir)         
          compilation_db =  ycm_core.CompilationDatabase(compilation_db_dir)                  
          if not compilation_db:                                                              
              logging.info(&quot;Compilation database file found but unable to load&quot;)              
              return None                                                                     
          compilation_info = GetCompilationInfoForFile(compilation_db, filename)              
          if not compilation_info:                                                            
              logging.info(&quot;No compilation info for &quot; + filename + &quot; in compilation database&quot;)
              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                                                                
              }                                                                               
  </code></pre>
  <p>It's taken from <a href="https://github.com/JDevlieghere/dotfiles/blob/master/.vim/.ycm_extra_conf.py" rel="nofollow noreferrer">https://github.com/JDevlieghere/dotfiles/blob/master/.vim/.ycm_extra_conf.py</a> and slightly adjusted.</p>
  <p>I set the completion engine in my vimrc :</p>
  <pre><code>let g:ycm_confirm_extra_conf = 0                                                            
  let g:ycm_clangd_binary_path = &quot;/usr/bin/clangd&quot;
  </code></pre>
  <p>The ycm debug info :</p>
  <pre><code>Printing YouCompleteMe debug information...                                                                                                                                                
  -- Resolve completions: Up front                                                                                                                                                           
  -- Client logfile: /tmp/ycm_j3wmcevl.log                                                                                                                                                   
  -- Server Python interpreter: /usr/bin/python3                                                                                                                                             
  -- Server Python version: 3.8.6                                                                                                                                                            
  -- Server has Clang support compiled in: False                                                                                                                                             
  -- Clang version: None                                                                                                                                                                     
  -- Extra configuration file found and loaded                                                                                                                                               
  -- Extra configuration path: /home/thomas/game_engine/.ycm_extra_conf.py                                                                                                                   
  -- C-family completer debug information:                                                                                                                                                   
  --   Clangd running                                                                                                                                                                        
  --   Clangd process ID: 4587                                                                                                                                                               
  --   Clangd executable: ['/usr/bin/clangd', '-header-insertion-decorators=0', '-limit-results=500']                                                                                        
  --   Clangd logfiles:                                                                                                                                                                      
  --     /tmp/clangd_stderrhqcigpx6.log                                                                                                                                                      
  --   Clangd Server State: Initialized                                                                                                                                                      
  --   Clangd Project Directory: /home/thomas/game_engine                                                                                                                                    
  --   Clangd Settings: {}                                                                                                                                                                   
  --   Clangd Compilation Command: False                                                                                                                                                     
  -- Server running at: http://127.0.0.1:45861                                                                                                                                               
  -- Server process ID: 4528                                                                                                                                                                 
  -- Server logfiles:                                                                                                                                                                        
  --   /tmp/ycmd_45861_stdout_jlaf_q37.log                                                                                                                                                   
  --   /tmp/ycmd_45861_stderr_tbwrmn0_.log    
  </code></pre>
  <p>In the client log file :</p>
  <pre><code>2020-11-21 15:56:36,990 - ERROR - HTTPConnectionPool(host='127.0.0.1', port=45861): Max retries exceeded with url: /ready (Caused by NewConnectionError('&lt;urllib3.connection.HTTPConnection object at 0x7fc4842db460&gt;: Failed to establish a new connection: [Errno 111] Connection refused'))
  </code></pre>
  <p>I looked up <a href="https://stackoverflow.com/questions/24078955/ycm-does-not-find-my-headers">this</a>, <a href="https://stackoverflow.com/questions/24438211/youcompleteme-header-files">this</a> and <a href="https://stackoverflow.com/questions/47246209/youcompleteme-cant-find-local-header-files">this</a> questions, as well as ycm documentation but i still can't figure out a solution.</p>