• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1" Copyright (c) 2012 The Chromium Authors. All rights reserved.
2" Use of this source code is governed by a BSD-style license that can be
3" found in the LICENSE file.
4"
5" Adds a "Compile this file" function, using ninja. On Mac, binds Cmd-k to
6" this command. On Windows, Ctrl-F7 (which is the same as the VS default).
7" On Linux, <Leader>o, which is \o by default ("o"=creates .o files)
8"
9" Adds a "Build this target" function, using ninja. This is not bound
10" to any key by default, but can be used via the :CrBuild command.
11" It builds 'chrome' by default, but :CrBuild target1 target2 etc works as well.
12"
13" Requires that gyp has already generated build.ninja files, and that ninja is
14" in your path (which it is automatically if depot_tools is in your path).
15"
16" Add the following to your .vimrc file:
17"     so /path/to/src/tools/vim/ninja-build.vim
18
19python << endpython
20import os
21import vim
22
23
24def path_to_current_buffer():
25  """Returns the absolute path of the current buffer."""
26  return vim.current.buffer.name
27
28
29def path_to_source_root():
30  """Returns the absolute path to the chromium source root."""
31  candidate = os.path.dirname(path_to_current_buffer())
32  # This is a list of files that need to identify the src directory. The shorter
33  # it is, the more likely it's wrong (checking for just "build/common.gypi"
34  # would find "src/v8" for files below "src/v8", as "src/v8/build/common.gypi"
35  # exists). The longer it is, the more likely it is to break when we rename
36  # directories.
37  fingerprints = ['chrome', 'net', 'v8', 'build', 'skia']
38  while candidate and not all(
39      [os.path.isdir(os.path.join(candidate, fp)) for fp in fingerprints]):
40    candidate = os.path.dirname(candidate)
41  return candidate
42
43
44def guess_configuration():
45  """Default to the configuration with either a newer build.ninja or a newer
46  protoc."""
47  root = os.path.join(path_to_source_root(), 'out')
48  def is_release_15s_newer(test_path):
49    try:
50      debug_mtime = os.path.getmtime(os.path.join(root, 'Debug', test_path))
51    except os.error:
52      debug_mtime = 0
53    try:
54      rel_mtime = os.path.getmtime(os.path.join(root, 'Release',  test_path))
55    except os.error:
56      rel_mtime = 0
57    return rel_mtime - debug_mtime >= 15
58  configuration = 'Debug'
59  if is_release_15s_newer('build.ninja') or is_release_15s_newer('protoc'):
60    configuration = 'Release'
61  return configuration
62
63
64def compute_ninja_command_for_current_buffer(configuration=None):
65  """Returns the shell command to compile the file in the current buffer."""
66  if not configuration: configuration = guess_configuration()
67  build_dir = os.path.join(path_to_source_root(), 'out', configuration)
68
69  # ninja needs filepaths for the ^ syntax to be relative to the
70  # build directory.
71  file_to_build = path_to_current_buffer()
72  file_to_build = os.path.relpath(file_to_build, build_dir)
73
74  build_cmd = ' '.join(['ninja', '-C', build_dir, file_to_build + '^'])
75  if sys.platform == 'win32':
76    # Escape \ for Vim, and ^ for both Vim and shell.
77    build_cmd = build_cmd.replace('\\', '\\\\').replace('^', '^^^^')
78  vim.command('return "%s"' % build_cmd)
79
80
81def compute_ninja_command_for_targets(targets='', configuration=None):
82  if not configuration: configuration = guess_configuration()
83  build_dir = os.path.join(path_to_source_root(), 'out', configuration)
84  build_cmd = ' '.join(['ninja', '-C', build_dir, targets])
85  vim.command('return "%s"' % build_cmd)
86endpython
87
88fun! s:MakeWithCustomCommand(build_cmd)
89  let l:oldmakepgr = &makeprg
90  let &makeprg=a:build_cmd
91  silent make | cwindow
92  if !has('gui_running')
93    redraw!
94  endif
95  let &makeprg = l:oldmakepgr
96endfun
97
98fun! s:NinjaCommandForCurrentBuffer()
99  python compute_ninja_command_for_current_buffer()
100endfun
101
102fun! s:NinjaCommandForTargets(targets)
103  python compute_ninja_command_for_targets(vim.eval('a:targets'))
104endfun
105
106fun! CrCompileFile()
107  call s:MakeWithCustomCommand(s:NinjaCommandForCurrentBuffer())
108endfun
109
110fun! CrBuild(...)
111  let l:targets = a:0 > 0 ? join(a:000, ' ') : ''
112  if (l:targets !~ '\i')
113    let l:targets = 'chrome'
114  endif
115  call s:MakeWithCustomCommand(s:NinjaCommandForTargets(l:targets))
116endfun
117
118command! CrCompileFile call CrCompileFile()
119command! -nargs=* CrBuild call CrBuild(<q-args>)
120
121if has('mac')
122  map <D-k> :CrCompileFile<cr>
123  imap <D-k> <esc>:CrCompileFile<cr>
124elseif has('win32')
125  map <C-F7> :CrCompileFile<cr>
126  imap <C-F7> <esc>:CrCompileFile<cr>
127elseif has('unix')
128  map <Leader>o :CrCompileFile<cr>
129endif
130