You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.6 KiB

  1. import os
  2. import ycm_core
  3. # These are the compilation flags that will be used in case there's no
  4. # compilation database set (by default, one is not set).
  5. # CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
  6. flags = [
  7. '-Wall',
  8. '-Werror',
  9. '-pedantic-errors',
  10. '-std=c++0x',
  11. '-fno-strict-aliasing',
  12. '-O3',
  13. '-DNDEBUG',
  14. # ...and the same thing goes for the magic -x option which specifies the
  15. # language that the files to be compiled are written in. This is mostly
  16. # relevant for c++ headers.
  17. # For a C project, you would set this to 'c' instead of 'c++'.
  18. '-x', 'c++',
  19. '-I', 'include',
  20. '-isystem', '/usr/include',
  21. '-isystem', '/usr/local/include',
  22. ]
  23. # Set this to the absolute path to the folder (NOT the file!) containing the
  24. # compile_commands.json file to use that instead of 'flags'. See here for
  25. # more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
  26. #
  27. # Most projects will NOT need to set this to anything; you can just change the
  28. # 'flags' list of compilation flags. Notice that YCM itself uses that approach.
  29. compilation_database_folder = ''
  30. if os.path.exists( compilation_database_folder ):
  31. database = ycm_core.CompilationDatabase( compilation_database_folder )
  32. else:
  33. database = None
  34. SOURCE_EXTENSIONS = [ '.cc' ]
  35. def DirectoryOfThisScript():
  36. return os.path.dirname( os.path.abspath( __file__ ) )
  37. def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
  38. if not working_directory:
  39. return list( flags )
  40. new_flags = []
  41. make_next_absolute = False
  42. path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
  43. for flag in flags:
  44. new_flag = flag
  45. if make_next_absolute:
  46. make_next_absolute = False
  47. if not flag.startswith( '/' ):
  48. new_flag = os.path.join( working_directory, flag )
  49. for path_flag in path_flags:
  50. if flag == path_flag:
  51. make_next_absolute = True
  52. break
  53. if flag.startswith( path_flag ):
  54. path = flag[ len( path_flag ): ]
  55. new_flag = path_flag + os.path.join( working_directory, path )
  56. break
  57. if new_flag:
  58. new_flags.append( new_flag )
  59. return new_flags
  60. def IsHeaderFile( filename ):
  61. extension = os.path.splitext( filename )[ 1 ]
  62. return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
  63. def GetCompilationInfoForFile( filename ):
  64. # The compilation_commands.json file generated by CMake does not have entries
  65. # for header files. So we do our best by asking the db for flags for a
  66. # corresponding source file, if any. If one exists, the flags for that file
  67. # should be good enough.
  68. if IsHeaderFile( filename ):
  69. basename = os.path.splitext( filename )[ 0 ]
  70. for extension in SOURCE_EXTENSIONS:
  71. replacement_file = basename + extension
  72. if os.path.exists( replacement_file ):
  73. compilation_info = database.GetCompilationInfoForFile(
  74. replacement_file )
  75. if compilation_info.compiler_flags_:
  76. return compilation_info
  77. return None
  78. return database.GetCompilationInfoForFile( filename )
  79. def FlagsForFile( filename, **kwargs ):
  80. if database:
  81. # Bear in mind that compilation_info.compiler_flags_ does NOT return a
  82. # python list, but a "list-like" StringVec object
  83. compilation_info = GetCompilationInfoForFile( filename )
  84. if not compilation_info:
  85. return None
  86. final_flags = MakeRelativePathsInFlagsAbsolute(
  87. compilation_info.compiler_flags_,
  88. compilation_info.compiler_working_dir_ )
  89. else:
  90. relative_to = DirectoryOfThisScript()
  91. final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
  92. return {
  93. 'flags': final_flags,
  94. 'do_cache': True
  95. }