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
115 lines
3.6 KiB
import os |
|
import ycm_core |
|
|
|
# These are the compilation flags that will be used in case there's no |
|
# compilation database set (by default, one is not set). |
|
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR. |
|
flags = [ |
|
'-Wall', |
|
'-Werror', |
|
'-pedantic-errors', |
|
'-std=c++0x', |
|
'-fno-strict-aliasing', |
|
'-O3', |
|
'-DNDEBUG', |
|
# ...and the same thing goes for the magic -x option which specifies the |
|
# language that the files to be compiled are written in. This is mostly |
|
# relevant for c++ headers. |
|
# For a C project, you would set this to 'c' instead of 'c++'. |
|
'-x', 'c++', |
|
'-I', 'include', |
|
'-isystem', '/usr/include', |
|
'-isystem', '/usr/local/include', |
|
] |
|
|
|
|
|
# Set this to the absolute path to the folder (NOT the file!) containing the |
|
# compile_commands.json file to use that instead of 'flags'. See here for |
|
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html |
|
# |
|
# Most projects will NOT need to set this to anything; you can just change the |
|
# 'flags' list of compilation flags. Notice that YCM itself uses that approach. |
|
compilation_database_folder = '' |
|
|
|
if os.path.exists( compilation_database_folder ): |
|
database = ycm_core.CompilationDatabase( compilation_database_folder ) |
|
else: |
|
database = None |
|
|
|
SOURCE_EXTENSIONS = [ '.cc' ] |
|
|
|
def DirectoryOfThisScript(): |
|
return os.path.dirname( os.path.abspath( __file__ ) ) |
|
|
|
|
|
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 IsHeaderFile( filename ): |
|
extension = os.path.splitext( filename )[ 1 ] |
|
return extension in [ '.h', '.hxx', '.hpp', '.hh' ] |
|
|
|
|
|
def GetCompilationInfoForFile( filename ): |
|
# The compilation_commands.json file generated by CMake does not have entries |
|
# for header files. So we do our best by asking the db for flags for a |
|
# corresponding source file, if any. If one exists, the flags for that file |
|
# should be good enough. |
|
if IsHeaderFile( filename ): |
|
basename = os.path.splitext( filename )[ 0 ] |
|
for extension in SOURCE_EXTENSIONS: |
|
replacement_file = basename + extension |
|
if os.path.exists( replacement_file ): |
|
compilation_info = database.GetCompilationInfoForFile( |
|
replacement_file ) |
|
if compilation_info.compiler_flags_: |
|
return compilation_info |
|
return None |
|
return database.GetCompilationInfoForFile( filename ) |
|
|
|
|
|
def FlagsForFile( filename, **kwargs ): |
|
if database: |
|
# Bear in mind that compilation_info.compiler_flags_ does NOT return a |
|
# python list, but a "list-like" StringVec object |
|
compilation_info = GetCompilationInfoForFile( filename ) |
|
if not compilation_info: |
|
return None |
|
|
|
final_flags = MakeRelativePathsInFlagsAbsolute( |
|
compilation_info.compiler_flags_, |
|
compilation_info.compiler_working_dir_ ) |
|
else: |
|
relative_to = DirectoryOfThisScript() |
|
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) |
|
|
|
return { |
|
'flags': final_flags, |
|
'do_cache': True |
|
}
|
|
|