1# This file is NOT licensed under the GPLv3, which is the license for the rest 2# of YouCompleteMe. 3# 4# Here's the license text for this file: 5# 6# This is free and unencumbered software released into the public domain. 7# 8# Anyone is free to copy, modify, publish, use, compile, sell, or 9# distribute this software, either in source code form or as a compiled 10# binary, for any purpose, commercial or non-commercial, and by any 11# means. 12# 13# In jurisdictions that recognize copyright laws, the author or authors 14# of this software dedicate any and all copyright interest in the 15# software to the public domain. We make this dedication for the benefit 16# of the public at large and to the detriment of our heirs and 17# successors. We intend this dedication to be an overt act of 18# relinquishment in perpetuity of all present and future rights to this 19# software under copyright law. 20# 21# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27# OTHER DEALINGS IN THE SOFTWARE. 28# 29# For more information, please refer to <http://unlicense.org/> 30 31import os 32import ycm_core 33 34# These are the compilation flags that will be used in case there's no 35# compilation database set (by default, one is not set). 36# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR. 37flags = [ 38'-Wall', 39'-Wextra', 40'-Werror', 41'-Wc++98-compat', 42'-Wno-long-long', 43'-Wno-variadic-macros', 44'-fexceptions', 45'-DNDEBUG', 46'-stdlib=libc++' 47# You 100% do NOT need -DUSE_CLANG_COMPLETER in your flags; only the YCM 48# source code needs it. 49# '-DUSE_CLANG_COMPLETER', 50# THIS IS IMPORTANT! Without a "-std=<something>" flag, clang won't know which 51# language to use when compiling headers. So it will guess. Badly. So C++ 52# headers will be compiled as C headers. You don't want that so ALWAYS specify 53# a "-std=<something>". 54# For a C project, you would set this to something like 'c99' instead of 55# 'c++11'. 56'-std=c++11', 57# ...and the same thing goes for the magic -x option which specifies the 58# language that the files to be compiled are written in. This is mostly 59# relevant for c++ headers. 60# For a C project, you would set this to 'c' instead of 'c++'. 61'-x', 'c++', 62'-I', '.', 63'-I', './include', 64'-I', './thirdparty/include', 65'-isystem', '/usr/include/c++/4.8', 66'-isystem', '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1', 67'-isystem','/usr/include', 68'-isystem','/usr/local/include'] 69 70# Set this to the absolute path to the folder (NOT the file!) containing the 71# compile_commands.json file to use that instead of 'flags'. See here for 72# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html 73# 74# Most projects will NOT need to set this to anything; you can just change the 75# 'flags' list of compilation flags. Notice that YCM itself uses that approach. 76compilation_database_folder = '' 77 78if os.path.exists( compilation_database_folder ): 79 database = ycm_core.CompilationDatabase( compilation_database_folder ) 80else: 81 database = None 82 83SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] 84 85def DirectoryOfThisScript(): 86 return os.path.dirname( os.path.abspath( __file__ ) ) 87 88 89def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): 90 if not working_directory: 91 return list( flags ) 92 new_flags = [] 93 make_next_absolute = False 94 path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] 95 for flag in flags: 96 new_flag = flag 97 98 if make_next_absolute: 99 make_next_absolute = False 100 if not flag.startswith( '/' ): 101 new_flag = os.path.join( working_directory, flag ) 102 103 for path_flag in path_flags: 104 if flag == path_flag: 105 make_next_absolute = True 106 break 107 108 if flag.startswith( path_flag ): 109 path = flag[ len( path_flag ): ] 110 new_flag = path_flag + os.path.join( working_directory, path ) 111 break 112 113 if new_flag: 114 new_flags.append( new_flag ) 115 return new_flags 116 117 118def IsHeaderFile( filename ): 119 extension = os.path.splitext( filename )[ 1 ] 120 return extension in [ '.h', '.hxx', '.hpp', '.hh' ] 121 122 123def GetCompilationInfoForFile( filename ): 124 # The compilation_commands.json file generated by CMake does not have entries 125 # for header files. So we do our best by asking the db for flags for a 126 # corresponding source file, if any. If one exists, the flags for that file 127 # should be good enough. 128 if IsHeaderFile( filename ): 129 basename = os.path.splitext( filename )[ 0 ] 130 for extension in SOURCE_EXTENSIONS: 131 replacement_file = basename + extension 132 if os.path.exists( replacement_file ): 133 compilation_info = database.GetCompilationInfoForFile( 134 replacement_file ) 135 if compilation_info.compiler_flags_: 136 return compilation_info 137 return None 138 return database.GetCompilationInfoForFile( filename ) 139 140 141def FlagsForFile( filename, **kwargs ): 142 if database: 143 # Bear in mind that compilation_info.compiler_flags_ does NOT return a 144 # python list, but a "list-like" StringVec object 145 compilation_info = GetCompilationInfoForFile( filename ) 146 if not compilation_info: 147 return None 148 149 final_flags = MakeRelativePathsInFlagsAbsolute( 150 compilation_info.compiler_flags_, 151 compilation_info.compiler_working_dir_ ) 152 153 # NOTE: This is just for YouCompleteMe; it's highly likely that your project 154 # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR 155 # ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT. 156 try: 157 final_flags.remove( '-stdlib=libc++' ) 158 except ValueError: 159 pass 160 else: 161 relative_to = DirectoryOfThisScript() 162 final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) 163 164 return { 165 'flags': final_flags, 166 'do_cache': True 167 } 168