class GdbDebugger(cr.Debugger): """An implementation of cr.Debugger that launches gdb.""" DETECTED = cr.Config('DETECTED') @property def enabled(self): return (cr.LinuxPlatform.GetInstance().is_active and self.DETECTED.Find('CR_GDB')) def Invoke(self, context, targets, arguments): for target in targets: cr.Host.Execute( target, '{CR_GDB}', '--eval-command=run', '--args', '{CR_BINARY}', '{CR_RUN_ARGUMENTS}', *arguments ) def Attach(self, context, targets, arguments): raise NotImplementedError('Attach not currently supported for gdb.') @classmethod def ClassInit(cls): # Attempt to find a valid gdb on the path. gdb_binaries = cr.Host.SearchPath('gdb') if gdb_binaries: cls.DETECTED.Set(CR_GDB=gdb_binaries[0])
class SyncCommand(cr.Command): """The implementation of the sync command. This command is a very thin shim over the gclient sync, and should remain so. The only significant thing it adds is that the environment is set up so that the run-hooks will do their work in the selected output directory. """ # The configuration loaded to support this command. DEFAULT = cr.Config.From(GCLIENT_BINARY=os.path.join( '{DEPOT_TOOLS}', 'gclient'), ) # A placeholder for the detected gclient environment DETECTED = cr.Config('DETECTED') def __init__(self): super(SyncCommand, self).__init__() self.help = 'Sync the source tree' self.description = 'Run gclient sync with the right environment.' def AddArguments(self, subparsers): parser = super(SyncCommand, self).AddArguments(subparsers) self.ConsumeArgs(parser, 'gclient') # TODO(iancottrell): clean no-hooks support would be nice. return parser def Run(self, context): # TODO(iancottrell): we should probably run the python directly, # rather than the shell wrapper # TODO(iancottrell): try to help out when the local state is not a good # one to do a sync in cr.Host.Execute(context, '{GCLIENT_BINARY}', 'sync', *context.remains)
class NinjaBuilder(cr.Builder): """An implementation of Builder that uses ninja to do the actual build.""" # Some basic configuration installed if we are enabled. ENABLED = cr.Config.From( NINJA_BINARY=os.path.join('{DEPOT_TOOLS}', 'ninja'), NINJA_JOBS=200, NINJA_PROCESSORS=12, GOMA_DIR=os.path.join('{GOOGLE_CODE}', 'goma'), ) # A placeholder for the system detected configuration DETECTED = cr.Config('DETECTED') def __init__(self): super(NinjaBuilder, self).__init__() self._targets = [] def Build(self, context, targets, arguments): build_arguments = [target.build_target for target in targets] build_arguments.extend(arguments) cr.Host.Execute(context, '{NINJA_BINARY}', '-C{CR_BUILD_DIR}', '-j{NINJA_JOBS}', '-l{NINJA_PROCESSORS}', *build_arguments) def Clean(self, context, targets, arguments): build_arguments = [target.build_target for target in targets] build_arguments.extend(arguments) cr.Host.Execute(context, '{NINJA_BINARY}', '-C{CR_BUILD_DIR}', '-tclean', *build_arguments) def GetTargets(self, context): """Overridden from Builder.GetTargets.""" if not self._targets: try: context.Get('CR_BUILD_DIR', raise_errors=True) except KeyError: return self._targets output = cr.Host.Capture(context, '{NINJA_BINARY}', '-C{CR_BUILD_DIR}', '-ttargets', 'all') for line in output.split('\n'): line = line.strip() if line.endswith(_PHONY_SUFFIX): target = line[:-len(_PHONY_SUFFIX)].strip() self._targets.append(target) elif line.endswith(_LINK_SUFFIX): target = line[:-len(_LINK_SUFFIX)].strip() self._targets.append(target) return self._targets @classmethod def DetectNinja(cls): # TODO(iancottrell): If we can't detect ninja, we should be disabled. ninja_binaries = cr.Host.SearchPath('ninja') if ninja_binaries: cls.DETECTED.Set(NINJA_BINARY=ninja_binaries[0])
def Prepare(self, context): """Override Prepare from cr.Platform.""" super(AndroidPlatform, self).Prepare(context) # Check we are an android capable client is_android = 'android' in context.gclient.get('target_os', '') if not is_android: url = context.gclient.get('solutions', [{}])[0].get('url') is_android = ( url.startswith('https://chrome-internal.googlesource.com/') and url.endswith('/internal/apps.git')) if not is_android: print _NOT_ANDROID_MESSAGE exit(1) try: # capture the result of env setup if we have not already done so if not self._env_ready: # See what the env would be without env setup before = context.exported # Run env setup and capture/parse it's output envsetup = 'source {CR_ENVSETUP} --target-arch={CR_ENVSETUP_ARCH}' output = cr.Host.CaptureShell(context, envsetup + ' > /dev/null && env') env_setup = cr.Config('envsetup', literal=True, export=True) for line in output.split('\n'): (key, op, value) = line.partition('=') if op: key = key.strip() if key not in _IGNORE_ENV: env_setup[key] = env_setup.ParseValue( value.strip()) if key == 'PATH': self._env_paths = value.strip().split( os.path.pathsep) if key == 'GYP_DEFINES': # Make a version of GYP_DEFINES that is the combination of base # setting and envsetup, needs to override the overrides # Note: Forcing it into the top level scope - sledge-hammer context[key] = value.strip() + ' ' + before.get( key, '') items = env_setup.exported.items() if not items: # Because of the way envsetup is run, the exit code does not make it # back to us. Instead, we assume if we got no environment at all, it # must have failed. print 'Envsetup failed!' exit(1) # Find all the things that envsetup changed for key, value in env_setup.exported.items(): if str(value) != str(before.get(key, None)): self._env[key] = value self._env_ready = True except subprocess.CalledProcessError, e: exit(e.returncode)
def __init__(self): # Default the name to the lowercased class name. self._name = self.__class__.__name__.lower() # Strip the common suffix if present. self._root = _FindRoot(self.__class__) rootname = self._root.__name__.lower() if self._name.endswith(rootname) and self.__class__ != self._root: self._name = self._name[:-len(rootname)] for config_root in CONFIG_TYPES: config = cr.Config() setattr(self, config_root.property_name, config) self._is_active = False
class GdbDebugger(cr.Debugger): """An implementation of cr.Debugger that launches gdb.""" DETECTED = cr.Config('DETECTED') @property def enabled(self): return (cr.LinuxPlatform.GetInstance().is_active and self.DETECTED.Find('CR_GDB')) def Invoke(self, context, targets, arguments): for target in targets: cr.Host.Execute(target, '{CR_GDB}', '--eval-command=run', '--args', '{CR_BINARY}', '{CR_RUN_ARGUMENTS}', *arguments) def Attach(self, context, targets, arguments): raise NotImplementedError('Attach not currently supported for gdb.')
def __init__(self, target_name): super(Target, self).__init__(target_name) test_type = None if self.TEST_PATTERN.search(target_name): test_type = self.NORMAL_TEST config = cr.Config('DEFAULTS').From( CR_TARGET=target_name, CR_TARGET_NAME='{CR_TARGET}', CR_BUILD_TARGET=cr.Config.Optional('{CR_TARGET}{CR_TARGET_SUFFIX}', '{CR_TARGET}'), CR_RUN_ARGUMENTS='', CR_TEST_TYPE=test_type, ) self._data = cr.context.data self.AddChildren(config, cr.context) if hasattr(self, 'CONFIG'): self.AddChild(self.CONFIG) if not self.valid: self.Set(CR_TARGET_SUFFIX='') self.test_type = self.Find('CR_TEST_TYPE') self.target_name = self.Find('CR_TARGET_NAME')
def Prepare(self): """Override Prepare from cr.Platform.""" super(AndroidPlatform, self).Prepare() try: # capture the result of env setup if we have not already done so if not self._env_ready: # See what the env would be without env setup before = cr.context.exported # Run env setup and capture/parse its output envsetup = 'source {CR_ENVSETUP}' output = cr.Host.CaptureShell(envsetup + ' > /dev/null && env') env_setup = cr.Config('envsetup', literal=True, export=True) for line in output.split('\n'): (key, op, value) = line.partition('=') if op: key = key.strip() if key not in _IGNORE_ENV: env_setup[key] = env_setup.ParseValue( value.strip()) if key == 'PATH': self._env_paths = value.strip().split( os.path.pathsep) items = env_setup.exported.items() if not items: # Because of the way envsetup is run, the exit code does not make it # back to us. Instead, we assume if we got no environment at all, it # must have failed. print 'Envsetup failed!' exit(1) # Find all the things that envsetup changed for key, value in env_setup.exported.items(): if str(value) != str(before.get(key, None)): self._env[key] = value self._env_ready = True except subprocess.CalledProcessError, e: exit(e.returncode)
class FakeModule(object): OVERRIDES = cr.Config('OVERRIDES') def __init__(self): self.__name__ = 'config'
class NinjaBuilder(cr.Builder): """An implementation of Builder that uses ninja to do the actual build.""" # Some basic configuration installed if we are enabled. EXTRA_FOR_IO_BOUND_JOBS = 2 ENABLED = cr.Config.From( NINJA_BINARY=os.path.join('{DEPOT_TOOLS}', 'ninja'), NINJA_JOBS=multiprocessing.cpu_count() + EXTRA_FOR_IO_BOUND_JOBS, NINJA_PROCESSORS=multiprocessing.cpu_count(), NINJA_BUILD_FILE=os.path.join('{CR_BUILD_DIR}', 'build.ninja'), # Don't rename to GOMA_* or Goma will complain: "unkown GOMA_ parameter". NINJA_GOMA_LINE='cc = {CR_GOMA_CC} $', ) # A config block only included if goma is detected. GOMA = cr.Config.From( CR_GOMA_CC=os.path.join('{GOMA_DIR}', 'gomacc'), CR_GOMA_CTL=os.path.join('{GOMA_DIR}', 'goma_ctl.py'), GOMA_DIR='{CR_GOMA_DIR}', GYP_DEF_gomadir='{CR_GOMA_DIR}', GYP_DEF_use_goma=1, NINJA_JOBS=multiprocessing.cpu_count() * 10, ) # A placeholder for the system detected configuration DETECTED = cr.Config('DETECTED') def __init__(self): super(NinjaBuilder, self).__init__() self._targets = [] def Build(self, targets, arguments): # Make sure Goma is started if Ninja is set to use it. # This may be redundant, but it currently improves reliability. try: with open(cr.context.Get('NINJA_BUILD_FILE'), 'r') as f: if f.readline().rstrip('\n') == cr.context.Get('NINJA_GOMA_LINE'): # Goma is active, so make sure it's started. cr.Host.ExecuteSilently( '{CR_GOMA_CTL}', 'ensure_start' ) except IOError: pass build_arguments = [target.build_target for target in targets] build_arguments.extend(arguments) cr.Host.Execute( '{NINJA_BINARY}', '-C{CR_BUILD_DIR}', '-j{NINJA_JOBS}', '-l{NINJA_PROCESSORS}', *build_arguments ) def Clean(self, targets, arguments): build_arguments = [target.build_target for target in targets] build_arguments.extend(arguments) cr.Host.Execute( '{NINJA_BINARY}', '-C{CR_BUILD_DIR}', '-tclean', *build_arguments ) def GetTargets(self): """Overridden from Builder.GetTargets.""" if not self._targets: try: cr.context.Get('CR_BUILD_DIR', raise_errors=True) except KeyError: return self._targets output = cr.Host.Capture( '{NINJA_BINARY}', '-C{CR_BUILD_DIR}', '-ttargets', 'all' ) for line in output.split('\n'): line = line.strip() if line.endswith(_PHONY_SUFFIX): target = line[:-len(_PHONY_SUFFIX)].strip() self._targets.append(target) elif line.endswith(_LINK_SUFFIX): target = line[:-len(_LINK_SUFFIX)].strip() self._targets.append(target) return self._targets @classmethod def ClassInit(cls): # TODO(iancottrell): If we can't detect ninja, we should be disabled. ninja_binaries = cr.Host.SearchPath('ninja') if ninja_binaries: cls.DETECTED.Set(NINJA_BINARY=ninja_binaries[0]) goma_binaries = cr.Host.SearchPath('gomacc', [ '{GOMA_DIR}', '/usr/local/google/code/goma', os.path.expanduser('~/goma') ]) if goma_binaries: cls.DETECTED.Set(CR_GOMA_DIR=os.path.dirname(goma_binaries[0])) cls.DETECTED.AddChildren(cls.GOMA)
def __init__(self): super(AndroidPlatform, self).__init__() self._env = cr.Config('android-env', literal=True, export=True) self.detected_config.AddChild(self._env) self._env_ready = False self._env_paths = []
def _PluginConfig(name, only_enabled=False, only_active=False): config = cr.Config(name) config.only_active = only_active config.only_enabled = only_enabled or config.only_active config.property_name = name.lower() + '_config' return config
""" from operator import attrgetter import cr import cr.loader def _PluginConfig(name, only_enabled=False, only_active=False): config = cr.Config(name) config.only_active = only_active config.only_enabled = only_enabled or config.only_active config.property_name = name.lower() + '_config' return config _selectors = cr.Config('PRIORITY') CONFIG_TYPES = [ # Lowest priority, always there default values. _PluginConfig('DEFAULT').AddChild(_selectors), # Only turned on if the plugin is enabled. _PluginConfig('ENABLED', only_enabled=True), # Only turned on while the plugin is the active one. _PluginConfig('ACTIVE', only_active=True), # Holds detected values for active plugins. _PluginConfig('DETECTED', only_active=True), # Holds overrides, used in custom setup plugins. _PluginConfig('OVERRIDES'), ] cr.config.GLOBALS.extend(CONFIG_TYPES) _plugins = {}