summaryrefslogtreecommitdiff
path: root/.ycm_extra_conf.py
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <thiago@mapbox.com>2015-12-08 14:49:44 -0800
committerThiago Marcos P. Santos <thiago@mapbox.com>2015-12-08 15:47:23 -0800
commit40b2d81a22201ceccd9448a0b6e906a34f167314 (patch)
treee963b383848e0e2e95fc426706007fc359681258 /.ycm_extra_conf.py
parentb7037bb4b1ead048fcb8afecb13e74ef2b27080c (diff)
downloadqtlocation-mapboxgl-40b2d81a22201ceccd9448a0b6e906a34f167314.tar.gz
[core] Use compilation database for YCM
Now the .ycm_extra_conf.py is very close to the YCM upstream reference file.
Diffstat (limited to '.ycm_extra_conf.py')
-rw-r--r--.ycm_extra_conf.py201
1 files changed, 82 insertions, 119 deletions
diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py
index be5e3a5c1f..41578b3366 100644
--- a/.ycm_extra_conf.py
+++ b/.ycm_extra_conf.py
@@ -33,130 +33,93 @@
import os
import subprocess
-import sys
import ycm_core
-
-def DirectoryOfThisScript():
- return os.path.dirname(os.path.abspath(__file__))
-
-
-default_flags = [
- '-std=c++14',
- '-I%s' % (os.path.join(DirectoryOfThisScript(), 'src')),
- '-I%s' % (os.path.join(DirectoryOfThisScript(), 'include')),
+compilation_database_folders = [
+ 'build/linux-x86_64/Release',
+ 'build/osx-x86_64/Release',
]
+subprocess.call(['make compdb'], shell=True)
-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 FlagsForFileDefault():
- return {
- 'flags': default_flags,
- 'do_cache': False,
- }
-
-
-def FlagsForFileLinux(filename):
- working_directory = os.path.join('build', 'linux')
-
- if not os.path.exists(os.path.join(DirectoryOfThisScript(), working_directory)):
- return FlagsForFileDefault()
-
- relative_source_path = filename.replace(DirectoryOfThisScript() + '/', '')
- relative_obj_path = os.path.splitext(relative_source_path)[0] + '.o'
-
- make_cmd = 'make -pn |grep %s: |grep GYP_CXXFLAGS |cut -d\' \' -f4-' % relative_obj_path
-
- p = subprocess.Popen([make_cmd], shell=True, stdout=subprocess.PIPE)
- stdout, stderr = p.communicate()
+for folder in compilation_database_folders:
+ if os.path.exists( folder ):
+ database = ycm_core.CompilationDatabase( folder )
- if p.returncode:
- return FlagsForFileDefault()
+SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
- flags = stdout.split(' ')
- flags_relative = MakeRelativePathsInFlagsAbsolute(flags, os.path.join(DirectoryOfThisScript(), working_directory))
- flags_final = [flag for flag in flags_relative if flag.startswith("-")]
- return {
- 'flags': flags_final,
- 'do_cache': True,
- }
-
-
-def FlagsForFileDarwin(filename):
- working_directory = os.path.join('build', 'osx')
-
- if not os.path.exists(os.path.join(DirectoryOfThisScript(), working_directory)):
- return FlagsForFileDefault()
-
- relative_source_path = filename.replace(DirectoryOfThisScript() + '/', '')
- relative_obj_path = os.path.splitext(relative_source_path)[0] + '.o'
-
- make_cmd = 'make -pn |grep "%s :=" |grep "NDEBUG" |tail -n 1 | cut -d\' \' -f4-' % relative_obj_path
-
- p = subprocess.Popen([make_cmd], shell=True, stdout=subprocess.PIPE)
- stdout, stderr = p.communicate()
-
- if p.returncode:
- return FlagsForFileDefault()
-
- flags = stdout.split(' ')
- flags_relative = MakeRelativePathsInFlagsAbsolute(flags, os.path.join(DirectoryOfThisScript(), working_directory))
- flags_final = [flag for flag in flags_relative if flag.startswith("-")]
-
- # Append OSX sysroot SDK path
- xcrun_cmd = 'xcrun --show-sdk-path'
-
- p = subprocess.Popen([xcrun_cmd], shell=True, stdout=subprocess.PIPE)
- stdout, stderr = p.communicate()
-
- if p.returncode:
- return FlagsForFileDefault()
-
- flags_final.append('-isysroot ' + stdout)
-
- return {
- 'flags': flags_final,
- 'do_cache': True,
- }
-
-
-def FlagsForFile(filename, **kwargs):
- if sys.platform.startswith('linux'):
- return FlagsForFileLinux(filename)
-
- if sys.platform.startswith('darwin'):
- return FlagsForFileDarwin(filename)
-
- return FlagsForFileDefault()
+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 not database:
+ return None
+
+ # 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_ )
+
+ return {
+ 'flags': final_flags,
+ 'do_cache': True
+ }