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