Hi,

i've been using vim + YouCompleteMe [0] for some time know and it works
pretty well with OpenBSD's src tree.  I want to share my
.ycm_extra_conf.py ([1] and below) with you.  Maybe someone will
find it usefull.

This configuration will gather compiler flags (CFLAGS  / CPPFLAGS)
from the appropriate Makefiles and should work for userland as well as
the kernel.

Just put .ycm_extra_conf.py under your SRCDIR (/usr/src) and follow the
HOWTO instructions which you can find in the .ycm_extra_conf.py file.

This .ycm_extra_conf.py will probably work for other projects as long as
all relevant flags are in CFLAGS / CPPFLAGS.



If someone knows a better solution to read variables from Makefiles,
let me know!  :)

Cheers,
Fabian


[0] - https://github.com/Valloric/YouCompleteMe
[1] - https://gist.github.com/Mischi/b8d57f8732b27239469a

.ycm_extra_conf.py
------------------------------

# Based on
# https://github.com/Valloric/ycmd/blob/master/cpp/ycm/.ycm_extra_conf.py

#############################################
# HOWTO
#############################################
#
# =============== Step 1 ====================
#
# For kernel .c files, CFLAGS / CPPFLAGS from
# the actual kernel configuration are used.
# These are gathered via uname(1).
#
# If you want a specific arch/config, override
# them with 'default_arch' / 'default_config'
#
# NOTE: The choosen kernel configuration must
#       exist.
#
# =============== Step 2 ====================
#
# The following target mimics 'make show'
# from bsd.port.mk(5) and is used to retrieve
# CFLAGS / CPPFLAGS variables from Makefiles.
#
# Copy & Paste the folloing make target
# into your /etc/mk.conf:
#
# myshow:
# .for v in ${myshowvar}
#       @echo ${$v}
# .endfor
#
#
# .PHONY: myshow
#

import os
import ycm_core

default_arch = None
default_config = None

# You can add additional CFLAGS / CPPFLAGS here.
additional_userland_flags = [
#  "-Weverything"
]

additional_kernel_flags = [
#  "-Weverything"
]

srcdir = os.path.dirname( os.path.abspath( __file__ ) )
sysdir = os.path.join(srcdir, "sys")

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 GetKernelFlags( darch, dconfig ):
  if darch != None:
    arch = darch
  else:
    arch = os.popen("uname -m").read().rstrip()

  if dconfig != None:
    config = dconfig
  else:
    config = os.popen("uname -v").read().split('#')[0]

  makefiledir = "arch/%s/compile/%s" % ( arch, config )
  makefiledir = os.path.join(sysdir, makefiledir)
  return GetFlags( makefiledir )


def GetUserlandFlags( filename ):
  makefiledir = os.path.dirname( filename )
  while not "Makefile" in os.listdir( makefiledir ):
    makefiledir = os.path.join(makefiledir, "..")

  return GetFlags( makefiledir )


def GetFlags( makefiledir ):
  cd_cmd = "cd %s" % makefiledir
  make_cmd = "make myshowvar=\"CFLAGS CPPFLAGS\" myshow"
  make_flags = os.popen("%s && %s" % (cd_cmd, make_cmd)).read().split()
  return MakeRelativePathsInFlagsAbsolute( make_flags, makefiledir )




def FlagsForFile( filename ):
  if filename.startswith( sysdir ):
    final_flags = GetKernelFlags( default_arch , default_config )
    final_flags.extend( additional_kernel_flags )

  elif filename.startswith( srcdir ):
    final_flags = GetUserlandFlags( filename )
    final_flags.extend( additional_userland_flags )

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

Reply via email to