Skip to content

Commit

Permalink
cr: Add support for GN build file generation
Browse files Browse the repository at this point in the history
To use, invoke cr init with --generator gn:

$ cr init -o out_linux/Debug --generator gn
$ cr build ...
$ cr run ...
$ etc.

You can also pass in additional arguments:

$ cr init -o out_linux/Debug --generator gn -s GN_ARG_foo=bar

Note that gn args works normally, although you need to specify the out directory manually:

$ gn args out_linux/Debug

Review URL: https://codereview.chromium.org/1095613002

Cr-Commit-Position: refs/heads/master@{#325664}
  • Loading branch information
skyostil authored and Commit bot committed Apr 17, 2015
1 parent cb0da85 commit 1c0cfff
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 8 deletions.
72 changes: 72 additions & 0 deletions tools/cr/cr/actions/gn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A module to add gn support to cr."""

import cr
import shlex
import os

GN_ARG_PREFIX = 'GN_ARG_'


class GnPrepareOut(cr.PrepareOut):
"""A prepare action that runs gn whenever you select an output directory."""

ACTIVE = cr.Config.From(
GN_ARG_is_component_build='true',
)

@property
def enabled(self):
# Disabled on Android for now.
return not cr.AndroidPlatform.GetInstance().is_active

def UpdateContext(self):
# Collapse GN_ARGS from all GN_ARG prefixes
gn_args = cr.context.Find('GN_ARGS') or ''
for key, value in cr.context.exported.items():
if key.startswith(GN_ARG_PREFIX):
gn_args += ' %s=%s' % (key[len(GN_ARG_PREFIX):], value)

gn_args += (' is_debug=%s' %
'true' if cr.context['CR_BUILDTYPE'] == 'Debug' else 'false')

cr.context['GN_ARGS'] = gn_args.strip()
if cr.context.verbose >= 1:
print cr.context.Substitute('GN_ARGS = {GN_ARGS}')

def Prepare(self):
if cr.context.verbose >= 1:
print cr.context.Substitute('Invoking gn with {GN_ARGS}')

args_file = os.path.join(cr.context['CR_SRC'],
cr.context['CR_OUT_FULL'],
'args.gn')
args = {}
for arg in shlex.split(cr.context['GN_ARGS']):
key, value = arg.split('=', 1)
args[key] = value

# Override any existing settings.
arg_lines = []
if os.path.exists(args_file):
with open(args_file) as f:
for line in f:
key = line.split('=', 1)[0].strip()
if key not in args:
arg_lines.append(line.strip())

# Append new settings.
for key, value in args.items():
arg_lines.append('%s = %s' % (key, value))

with open(args_file, 'w') as f:
f.write('\n'.join(arg_lines) + '\n')

cr.Host.Execute(
'gn',
'gen',
'{CR_OUT_FULL}',
)
2 changes: 1 addition & 1 deletion tools/cr/cr/actions/gyp.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
class GypPrepareOut(cr.PrepareOut):
"""A prepare action that runs gyp whenever you select an output directory."""

ENABLED = cr.Config.From(
ACTIVE = cr.Config.From(
GYP_GENERATORS='ninja',
GYP_GENERATOR_FLAGS='output_dir={CR_OUT_BASE} config={CR_BUILDTYPE}',
GYP_DEF_target_arch='{CR_ENVSETUP_ARCH}',
Expand Down
3 changes: 2 additions & 1 deletion tools/cr/cr/base/android.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class AndroidPlatform(cr.Platform):
'{CR_SRC}', 'build', 'android', 'test_runner.py'),
CR_ADB_GDB=os.path.join('{CR_SRC}', 'build', 'android', 'adb_gdb'),
CR_DEFAULT_TARGET='chrome_shell',
GYP_DEF_OS='android'
GYP_DEF_OS='android',
GN_ARG_os='"android"'
)

def __init__(self):
Expand Down
13 changes: 11 additions & 2 deletions tools/cr/cr/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@
# The set of variables to store in the per output configuration.
OUT_CONFIG_VARS = [
'CR_VERSION',
cr.Platform.SELECTOR, cr.BuildType.SELECTOR, cr.Arch.SELECTOR,
'CR_OUT_BASE', 'CR_OUT_FULL',
cr.Platform.SELECTOR,
cr.BuildType.SELECTOR,
cr.Arch.SELECTOR,
cr.PrepareOut.SELECTOR,
'CR_OUT_BASE',
'CR_OUT_FULL',
]


Expand Down Expand Up @@ -43,6 +47,7 @@ def AddArguments(self, subparsers):
cr.BuildType.AddArguments(parser)
cr.Arch.AddArguments(parser)
cr.SelectCommand.AddPrepareArguments(parser)
cr.PrepareOut.AddArguments(parser)
parser.add_argument(
'-s', '--set', dest='_settings', metavar='settings',
action='append',
Expand Down Expand Up @@ -85,11 +90,15 @@ def EarlyArgProcessing(self):
print 'Matched all of', ','.join(matches)
exit(1)
platform = matches[0]
generator = cr.context.args.CR_GENERATOR
if not generator:
generator = 'gyp'
cr.context.derived.Set(
CR_OUT_FULL=out,
CR_OUT_BASE=base,
CR_PLATFORM=platform,
CR_BUILDTYPE=buildtype,
CR_GENERATOR=generator
)
if not 'CR_OUT_BASE' in cr.context:
cr.context.derived['CR_OUT_BASE'] = 'out_{CR_PLATFORM}'
Expand Down
18 changes: 14 additions & 4 deletions tools/cr/cr/commands/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@ def Run(self):

@classmethod
def UpdateContext(cls):
for preparation in PrepareOut.Plugins():
preparation.UpdateContext()
PrepareOut.GetActivePlugin().UpdateContext()

@classmethod
def Prepare(cls):
cls.UpdateContext()
for preparation in PrepareOut.Plugins():
preparation.Prepare()
PrepareOut.GetActivePlugin().Prepare()


class PrepareOut(cr.Plugin, cr.Plugin.Type):
Expand All @@ -47,6 +45,18 @@ class PrepareOut(cr.Plugin, cr.Plugin.Type):
See PrepareCommand for details.
"""

SELECTOR = 'CR_GENERATOR'

@classmethod
def AddArguments(cls, parser):
parser.add_argument(
'--generator', dest=cls.SELECTOR,
choices=cls.Choices(),
default=None,
help=('Sets the build file generator to use. ' +
'Overrides %s.' % cls.SELECTOR)
)

def UpdateContext(self):
"""Update the context if needed.
Expand Down

0 comments on commit 1c0cfff

Please sign in to comment.