2014-05-06 43 views
1

我正在嘗試使用我的Qt項目運行YouCompleteMe。問題是,我有很多子項目(數百個)都有不同的編譯器標誌。因此,一個全球.ycm_extra_conf.py是不夠的。每個子項目都有一個Makefile(由qmake生成),其中包含要傳遞給GCC的所有編譯器標誌。如何配置Vim插件YouCompleteMe來讀取Makefile?

是否可以將YouCompleteMe配置爲讀取項目的Makefile,而不是爲每個項目創建不同的.ycm_extra_conf.py

+0

如何詢問關於插件的問題跟蹤器?! –

回答

1

直到一個更好的解決方案出現,我寫了這個醜陋的Bash腳本來完成工作。你需要設置的目錄在頂部遞歸,如果你要使用它:

#!/bin/bash 
    declare -a dirs_to_recurse=('project1' 'project2' 'project3') 

template_file="ycm-template.txt" 

generate_ycm_config() 
{ 
    file=.ycmtmp.txt 
    dir=$(echo "$1" | sed -e 's/ /\\ /g') 
    if [ -d "$dir" ]; then 
     cd "$dir" 
     if [ -f "Makefile" ] && $(ls -U *.pro > /dev/null 2>&1); then 
      list="" 
      for i in DEFINES CXXFLAG INCPATH; do 
       list="${list} '$(cat Makefile | grep "$i.*=" | sed -e "s/$i.*= //g" | sed -e "s/ \$(DEFINES)//g" | sed -e "s/ -Wno-unused-local-typedefs//g" | sed -e "s/ /\', \'/g")', " 
      done 
      echo "$list" 
      rm -f $file 
      preifs="$IFS" 
      IFS='' 
      while read line; do 
       echo $line >> $file 
       if [[ $line =~ ^compilation_database_folder ]]; then 
        read -r -d '' VAR << __EOF__ 

flags = [ 
$list 
] 

__EOF__ 
        echo "$VAR" >> $file 
       fi 
      done < $template_file 
      mv $file .ycm_extra_conf.py 
      IFS=$preifs 
     fi 
    fi 
} 


for dir in ${dirs_to_recurse[@]}; do 
    for i in $(find $HOME/$dir -type d 2> /dev/null); do 
     generate_ycm_config "$i" 
    done 
done 

這裏是我的模板文件:

import os 
import ycm_core 
from clang_helpers import PrepareClangFlags 

# 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 compilation_database_folder: 
    database = ycm_core.CompilationDatabase(compilation_database_folder) 
else: 
    database = None 


def DirectoryOfThisScript(): 
    return os.path.dirname(os.path.abspath(__file__)) 


def MakeRelativePathsInFlagsAbsolute(flags, working_directory): 
    if not working_directory: 
    return 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 FlagsForFile(filename): 
    if database: 
    # Bear in mind that compilation_info.compiler_flags_ does NOT return a 
    # python list, but a "list-like" StringVec object 
    compilation_info = database.GetCompilationInfoForFile(filename) 
    final_flags = PrepareClangFlags(
     MakeRelativePathsInFlagsAbsolute(
      compilation_info.compiler_flags_, 
      compilation_info.compiler_working_dir_), 
     filename) 
    else: 
    relative_to = DirectoryOfThisScript() 
    final_flags = MakeRelativePathsInFlagsAbsolute(flags, relative_to) 

    return { 
    'flags': final_flags, 
    'do_cache': True 
    }