| #! /usr/bin/env python3 |
| |
| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import os.path |
| import sys |
| import datetime |
| import collections |
| |
| |
| class GnVariables(collections.OrderedDict): |
| |
| def __setitem__(self, key, value): |
| if isinstance(value, list): |
| value = SetGnListValue(value) |
| super().__setitem__(key, value) |
| super().move_to_end(key) |
| |
| |
| class GnListValue(object): |
| |
| def __init__(self, items): |
| assert (isinstance(items, list)) |
| self._items = items |
| |
| def __getitem__(self, idx): |
| return self._items[idx] |
| |
| def __len__(self): |
| return len(self._items) |
| |
| def __iter__(self): |
| yield from self._items |
| |
| |
| class RemoveGnListValue(GnListValue): |
| pass |
| |
| |
| class SetGnListValue(GnListValue): |
| pass |
| |
| |
| def IsSubdir(parent, child): |
| if parent == child: |
| return False |
| return (os.path.commonpath([parent, child]) == parent) |
| |
| |
| class BazelGlobals(object): |
| IGNORABLES = frozenset([ |
| 'load', |
| 'package', |
| 'licenses', |
| 'exports_files', |
| 'select', |
| ]) |
| |
| def __init__(self, build_graph, dirpath): |
| self._build_graph = build_graph |
| self._dirpath = dirpath |
| self._set_objects = {} |
| |
| def __getitem__(self, key): |
| if key in self._set_objects: |
| return self._set_objects[key] |
| |
| if key == '__builtins__': |
| raise KeyError(key) |
| |
| if key in self.IGNORABLES: |
| return lambda *args, **kwargs: None |
| |
| return self._build_graph.GetTargetAdder(self._dirpath, key) |
| |
| def __setitem__(self, key, value): |
| self._set_objects[key] = value |
| |
| def __contains__(self, key): |
| if key == '__builtins__': |
| raise KeyError(key) |
| |
| return True |
| |
| def __len__(self): |
| return 1 |
| |
| |
| class BuildGraph(object): |
| |
| def __init__(self, root_path, ignored_targets): |
| self._targets = {} |
| if not os.path.isabs(root_path): |
| raise Exception('{} is not an absolute path.'.format(root_path)) |
| self._root_path = root_path |
| self._ignored_targets = ignored_targets |
| |
| # These are specs that will be remapped. |
| self._spec_map_old_to_new = {} |
| |
| def AddTarget(self, target_cls, dirpath, name, deps=None, **kwargs): |
| if deps: |
| deps = [MakeTargetRef(dep, dirpath) for dep in deps] |
| deps = [dep for dep in deps if dep.spec() not in self._ignored_targets] |
| for i in range(len(deps)): |
| if deps[i].spec() not in self._spec_map_old_to_new: |
| continue |
| deps[i] = MakeTargetRef(self._spec_map_old_to_new[deps[i].spec()], |
| dirpath) |
| |
| target = target_cls( |
| dirpath=dirpath, |
| name=name, |
| sort_id=len(self._targets), |
| deps=deps, |
| **kwargs) |
| assert (isinstance(target, Target)) |
| self._targets[target.spec()] = target |
| |
| def GetTargetAdder(self, absdirpath, target_type): |
| if not IsSubdir(self._root_path, absdirpath): |
| Exception( |
| 'GetTargetAdder expected a path under {} which {} is not.'.format( |
| self._root_path, absdirpath)) |
| dirpath = os.path.relpath(absdirpath, self._root_path) |
| if target_type == 'proto_library': |
| return self.GetProtoLibraryAdder(dirpath) |
| elif target_type == 'cc_library': |
| return self.GetCcLibraryAdder(dirpath) |
| elif target_type == 'cc_proto_library': |
| return self.GetCcProtoLibraryAdder(dirpath) |
| return self.GetUnknownTargetAdder(dirpath, target_type) |
| |
| def GetUnknownTargetAdder(self, dirpath, target_type): |
| |
| def Add(*args, **kwargs): |
| if 'name' not in kwargs or args: |
| raise Exception( |
| '"{}" is not a target type. Please add to IGNORABLES.'.format( |
| target_type)) |
| name = kwargs['name'] |
| deps = kwargs.get('deps', []) |
| self.AddTarget( |
| UnknownTarget, dirpath, name, deps=deps, target_type=target_type) |
| |
| return Add |
| |
| def GetCcProtoLibraryAdder(self, dirpath): |
| |
| def Add(name, deps=None, **kwargs): |
| self.AddTarget(CcProtoLibTarget, dirpath, name, deps=deps) |
| |
| return Add |
| |
| def GetProtoLibraryAdder(self, dirpath): |
| |
| def Add(name, srcs, deps=None, **kwargs): |
| self.AddTarget(ProtoLibTarget, dirpath, name, srcs=srcs, deps=deps) |
| |
| return Add |
| |
| def GetCcLibraryAdder(self, dirpath): |
| |
| def Add(name, srcs=None, hdrs=None, deps=None, **kwargs): |
| self.AddTarget( |
| CcLibTarget, dirpath, name, hdrs=hdrs, srcs=srcs, deps=deps) |
| |
| return Add |
| |
| def AddToGraph(self, dirpath): |
| filepath = os.path.join(dirpath, 'BUILD.bazel') |
| fp = open(filepath, 'r') |
| content = fp.read() |
| gs = BazelGlobals(self, dirpath) |
| exec(content, {}, gs) |
| |
| def GetTarget(self, target_spec): |
| target_spec = self._spec_map_old_to_new.get(target_spec, target_spec) |
| if target_spec in self._ignored_targets: |
| raise Exception('{} is being ignored'.format(target_spec)) |
| ref = MakeTargetRef(target_spec, '') |
| if not ref.InTree(): |
| raise Exception('{} is not in the tree.'.format(target_spec)) |
| if target_spec not in self._targets: |
| dirpath, _ = ParseTargetSpec(target_spec) |
| absdirpath = os.path.join(self._root_path, dirpath) |
| self.AddToGraph(absdirpath) |
| if target_spec not in self._targets: |
| print(self._targets.keys()) |
| raise Exception('{} could not be found in {}'.format( |
| target_spec, absdirpath)) |
| |
| return self._targets[target_spec] |
| |
| |
| ############################################################## |
| # The Targets themselves. |
| ############################################################## |
| class Target(object): |
| |
| def __init__(self, dirpath, name, sort_id, deps): |
| assert (isinstance(sort_id, int)) |
| self._sort_id = sort_id |
| assert (isinstance(name, str)) |
| self._name = name |
| assert (isinstance(dirpath, str)) |
| self._dirpath = dirpath |
| self._deps = deps or [] |
| assert (all(isinstance(dep, TargetRef) for dep in self._deps)) |
| |
| def __repr__(self): |
| raise NotImplementedError |
| |
| def name(self): |
| return self._name |
| |
| def spec(self): |
| # When target is added to graph, the relative dirpath is computed by |
| # os.path.relpath(absdirpath, root_path). The function returns '.' as |
| # dirpath for the targets lives in root dir. |
| # |
| # Skip dirpath '.' to avoid returning spec like '//.:target'. |
| dirpath = self._dirpath if self._dirpath != '.' else '' |
| return '//{}:{}'.format(dirpath, self._name) |
| |
| def deps(self): |
| return self._deps |
| |
| def dirpath(self): |
| return self._dirpath |
| |
| def sort_id(self): |
| return self._sort_id |
| |
| def target_type(self): |
| raise NotImplementedError |
| |
| def IsUnknown(self): |
| return False |
| |
| def IsProto(self): |
| return False |
| |
| def RemapDep(self, old, new): |
| for i in range(len(self._deps)): |
| if self._deps[i].spec() == old: |
| self._deps[i] = MakeTargetRef(new, self._dirpath) |
| |
| |
| class UnknownTarget(Target): |
| |
| def __init__(self, dirpath, name, sort_id, target_type, deps): |
| super().__init__(dirpath, name, sort_id, deps=deps) |
| assert (isinstance(target_type, str)) |
| self._target_type = target_type |
| |
| def __repr__(self): |
| return 'UnknownTarget<{}: {}>'.format(self._target_type, self.spec()) |
| |
| def IsUnknown(self): |
| return True |
| |
| |
| class LibTarget(Target): |
| |
| def __init__(self, dirpath, name, sort_id, deps, srcs=None): |
| super().__init__(dirpath, name, sort_id, deps) |
| self.srcs = srcs or [] |
| |
| def __repr__(self): |
| return 'LibTarget<{}>'.format(self.spec()) |
| |
| |
| class ProtoLibTarget(LibTarget): |
| |
| def IsProto(self): |
| return True |
| |
| def __repr__(self): |
| return 'ProtoLibTarget<{}>'.format(self.spec()) |
| |
| def target_type(self): |
| return 'Proto Library' |
| |
| |
| class CcProtoLibTarget(Target): |
| |
| def IsProto(self): |
| return True |
| |
| def __repr__(self): |
| return 'CcProtoLibTarget<{}>'.format(self.spec()) |
| |
| def target_type(self): |
| return 'CC Proto Library' |
| |
| |
| class CcLibTarget(LibTarget): |
| |
| def __init__(self, dirpath, name, sort_id, deps, srcs=None, hdrs=None): |
| super().__init__(dirpath, name, sort_id, srcs=srcs, deps=deps) |
| self.hdrs = hdrs or [] |
| |
| def __repr__(self): |
| return 'CcLibTarget<{}>'.format(self.spec()) |
| |
| def target_type(self): |
| return 'CC Library' |
| |
| |
| ############################################################## |
| # Target references. (Used mostly for dependencies) |
| ############################################################## |
| def ParseTargetSpec(dep): |
| parts = dep.split(':') |
| dirpath = parts[0][2:] |
| if len(parts) == 1: |
| name = os.path.basename(dep) |
| elif len(parts) == 2: |
| name = parts[1] |
| else: |
| raise Exception('I do not know how to deal with this dep: "{}"'.format(dep)) |
| |
| return dirpath, name |
| |
| |
| def MakeTargetRef(dep, dirpath): |
| if dep[0] == ':': |
| return InTreeTargetRef(dirpath, dep[1:]) |
| if dep[:2] == '//': |
| dirpath, name = ParseTargetSpec(dep) |
| return InTreeTargetRef(dirpath, name) |
| |
| tink_base_prefix = '@tink_base' |
| if dep.startswith(tink_base_prefix): |
| dep = dep[len(tink_base_prefix):] |
| dirpath, name = ParseTargetSpec(dep) |
| return TinkBaseTargetRef(dirpath, name) |
| |
| absl_prefix = '@com_google_absl' |
| if dep.startswith(absl_prefix): |
| dep = dep[len(absl_prefix):] |
| dirpath, name = ParseTargetSpec(dep) |
| return AbslTargetRef(dirpath, name) |
| |
| if dep == '@com_google_protobuf//:protobuf_lite': |
| return ProtobufLiteTargetRef() |
| |
| if dep == '@com_google_protobuf//:protobuf': |
| return ProtobufLiteTargetRef() |
| |
| if dep == '@rapidjson': |
| return RapidJsonTargetRef() |
| |
| googletest_prefix = '@com_google_googletest' |
| if dep.startswith(googletest_prefix): |
| dep = dep[len(googletest_prefix):] |
| dirpath, name = ParseTargetSpec(dep) |
| return GoogleTestTargetRef(dirpath, name) |
| |
| boringssl_prefix = '@boringssl' |
| if dep.startswith(boringssl_prefix): |
| dep = dep[len(boringssl_prefix):] |
| dirpath, name = ParseTargetSpec(dep) |
| return BoringSslTargetRef(dirpath, name) |
| |
| return UnknownTargetRef(dirpath, dep) |
| |
| |
| class TargetRef(object): |
| |
| def InTree(self): |
| return False |
| |
| def IsUnknown(self): |
| return False |
| |
| |
| class UnknownTargetRef(TargetRef): |
| def __init__(self, dirpath, dep): |
| self._dirpath = dirpath |
| self._dep = dep |
| |
| def IsUnknown(self): |
| return True |
| |
| def spec(self): |
| return '<{} in {}'.format(self._dep, self._dirpath) |
| |
| |
| class PathTargetRef(TargetRef): |
| |
| def __init__(self, dirpath, name): |
| self._dirpath = dirpath |
| self._name = name |
| |
| def name(self): |
| return self._name |
| |
| def spec(self): |
| # When target is added to graph, the relative dirpath is computed by |
| # os.path.relpath(absdirpath, root_path). The function returns '.' as |
| # dirpath for the targets lives in root dir. The relative dirpath is |
| # also used to make TargetRefs for the target's dependencies. |
| # |
| # Skip dirpath '.' to avoid returning spec like '//.:target'. |
| dirpath = self._dirpath if self._dirpath != '.' else '' |
| return '//{}:{}'.format(dirpath, self._name) |
| |
| def dirpath(self): |
| return self._dirpath |
| |
| def __repr__(self): |
| return '{}<{}>'.format(type(self).__name__, self.spec()) |
| |
| |
| class TinkBaseTargetRef(PathTargetRef): |
| |
| def GetGnDep(self): |
| spec = self.spec() |
| prefix = '//' |
| if not spec.startswith(prefix): |
| raise Exception( |
| 'I do not know how to deal with Tink base dependency {}'.format(spec)) |
| return '//third_party/tink/' + spec[len(prefix):] |
| |
| |
| class InTreeTargetRef(PathTargetRef): |
| |
| def InTree(self): |
| return True |
| |
| |
| class AbslTargetRef(PathTargetRef): |
| |
| def GetGnDep(self): |
| spec = self.spec() |
| prefix = '//' |
| if not spec.startswith(prefix): |
| raise Exception( |
| 'I do not know how to deal with Absl dependency {}'.format(spec)) |
| return '//third_party/abseil-cpp/' + spec[len(prefix):] |
| |
| |
| class GoogleTestTargetRef(PathTargetRef): |
| pass |
| |
| |
| class ProtobufLiteTargetRef(TargetRef): |
| |
| def GetGnDep(self): |
| return '//third_party/protobuf:protobuf_lite' |
| |
| def spec(self): |
| return '@protobuf_lite' |
| |
| |
| class RapidJsonTargetRef(TargetRef): |
| |
| def spec(self): |
| return '@rapidjson' |
| |
| |
| class BoringSslTargetRef(PathTargetRef): |
| |
| def GetGnDep(self): |
| if self._dirpath: |
| raise Exception( |
| 'BoringSSL dep {} has dirpath {}. I do not know how to deal with that.' |
| .format(self.spec(), self._dirpath)) |
| return '//third_party/boringssl:' + self._name |
| |
| |
| ############################################################## |
| # TargetFetcher grabs all the targets we need. |
| ############################################################## |
| class TargetFetcher(object): |
| |
| def __init__(self, build_graph, initial_targets, error_on_unknown): |
| # _to_fetch is a list of target specs. |
| self._to_fetch = initial_targets |
| self._targets = [] |
| self._fetched = set() |
| self._build_graph = build_graph |
| self._error_on_unknown = error_on_unknown |
| |
| def FetchAll(self): |
| while self._to_fetch: |
| self.FetchNext() |
| return self._targets |
| |
| def FetchNext(self): |
| spec = self._to_fetch.pop(0) |
| if spec in self._fetched: |
| return |
| target = self._build_graph.GetTarget(spec) |
| if target.IsUnknown() and self._error_on_unknown: |
| raise Exception('Found unknown target: {}'.format(target)) |
| self._targets.append(target) |
| |
| # We add both the actual spec and the spec we tried to fetch just in |
| # case there was a remapping. |
| self._fetched.add(target.spec()) |
| self._fetched.add(spec) |
| for dep in target.deps(): |
| if dep.IsUnknown(): |
| raise Exception('Found unknown dep: {} for {}'.format(dep.spec(), target.spec())) |
| if not dep.InTree(): |
| continue |
| if dep.spec() not in self._fetched: |
| self._to_fetch.append(dep.spec()) |
| |
| ############################################################## |
| # BuildFile holds the information necessary to create a build file. |
| ############################################################## |
| class BuildFile(object): |
| |
| def __init__(self, dirpath, targets, subdirs): |
| self.dirpath = dirpath |
| # Directory mapping spec to target. |
| self.targets = targets |
| self.subdirs = sorted(subdirs) |
| |
| def HasProto(self): |
| return any(t.IsProto() for t in self.targets.values()) |
| |
| def HasCcLib(self): |
| return any(isinstance(t, CcLibTarget) for t in self.targets.values()) |
| |
| def __contains__(self, target_or_spec): |
| spec = target_or_spec |
| if hasattr(target_or_spec, 'spec'): |
| spec = target_or_spec.spec() |
| if not isinstance(spec, str): |
| raise Exception( |
| '{} should be a spec string or have a spec method.'.format( |
| target_or_spec)) |
| |
| return spec in self.targets |
| |
| |
| def CreateBuildFiles(targets): |
| build_file_targets = {} |
| for t in targets: |
| if t.dirpath() not in build_file_targets: |
| build_file_targets[t.dirpath()] = {} |
| build_file_targets[t.dirpath()][t.spec()] = t |
| |
| dirpaths = [k for k in build_file_targets.keys()] |
| build_files = [] |
| |
| for dirpath, targets in build_file_targets.items(): |
| subdirs = [] |
| for d in dirpaths: |
| # If d is an immediate subdirectory of dirpath, add it to subdirs |
| if not IsSubdir(dirpath, d): |
| continue |
| rel = os.path.relpath(d, dirpath) |
| if os.path.basename(rel) == rel: |
| subdirs.append(rel) |
| |
| build_files.append(BuildFile(dirpath, targets, subdirs)) |
| |
| return build_files |
| |
| |
| class BuildFileWriter(object): |
| |
| def __init__(self, rootdir, build_graph, max_line): |
| self._rootdir = rootdir |
| self._max_line = max_line |
| self._build_graph = build_graph |
| |
| def GetTargetForInTreeDep(self, dep): |
| assert (isinstance(dep, InTreeTargetRef)) |
| target = self._build_graph.GetTarget(dep.spec()) |
| |
| # We don't generate CcProtoLibTargets, so we try to dereference them to |
| # find the ProtoLibTarget that they refer to. |
| if isinstance(target, CcProtoLibTarget): |
| assert (len(target.deps()) == 1) |
| target = self._build_graph.GetTarget(target.deps()[0].spec()) |
| assert (isinstance(target, ProtoLibTarget)) |
| |
| return target |
| |
| def GetBuildFilePath(self, dirpath): |
| raise NotImplementedError |
| |
| def WriteBuildFile(self, build_file): |
| self._indent = 0 |
| self._filepath = self.GetBuildFilePath(build_file) |
| self._fp = open(self._filepath, 'w+') |
| self._build_file = build_file |
| self._nl = False |
| |
| print('Writing to {},'.format(self._filepath)) |
| self.WriteHeader() |
| # We generate a stable sort order to stabilize the .gn files. |
| targets = sorted( |
| build_file.targets.values(), key=lambda target: target.sort_id()) |
| |
| for target in targets: |
| self.WriteTarget(target) |
| |
| assert (self._indent == 0) |
| |
| def WriteHeader(self): |
| year = datetime.datetime.today().year |
| self.emitlines([ |
| '# Copyright {} The Fuchsia Authors. All rights reserved.'.format(year), |
| '# Use of this source code is governed by a BSD-style license that can be', |
| '# found in the LICENSE file.', |
| '#', |
| '# WARNING: This file is automatically generated by convert_for_cobalt.', |
| '# Do not edit manually.' |
| ]) |
| |
| def WriteTarget(self, target): |
| self.emitnl('# {} : {}'.format(target.target_type(), target.name())) |
| |
| def emit(self, s): |
| if self._nl: |
| self._fp.write(' ' * self._indent) |
| self._nl = False |
| if not isinstance(s, str): |
| raise Exception('emit expected a string, not {}'.format(s)) |
| self._fp.write(s) |
| |
| def emitnl(self, s): |
| self.emit(s) |
| self.nl() |
| |
| def emitlines(self, lines): |
| for line in lines: |
| self.emitnl(line) |
| |
| def nl(self): |
| self._fp.write('\n') |
| self._nl = True |
| |
| def indent(self): |
| self._indent += 1 |
| |
| def deindent(self): |
| self._indent -= 1 |
| |
| |
| class GnWriter(BuildFileWriter): |
| |
| def __init__(self, rootdir, deps_prefix, build_graph, max_line): |
| super().__init__( |
| rootdir=rootdir, build_graph=build_graph, max_line=max_line) |
| assert (deps_prefix.startswith('//')) |
| assert (not deps_prefix.endswith('/')) |
| self._deps_prefix = deps_prefix |
| |
| def GetBuildFilePath(self, build_file): |
| return os.path.join(self._rootdir, build_file.dirpath, 'BUILD.gn') |
| |
| def WriteHeader(self): |
| super().WriteHeader() |
| if self._build_file.HasProto(): |
| self.nl() |
| self.emitnl('import("//third_party/protobuf/proto_library.gni")') |
| self.nl() |
| |
| def WriteTarget(self, target): |
| # Skip cc_proto_lib targets. |
| if isinstance(target, CcProtoLibTarget): |
| return |
| super().WriteTarget(target) |
| |
| if isinstance(target, CcLibTarget): |
| self.WriteCcLibTarget(target) |
| elif isinstance(target, ProtoLibTarget): |
| self.WriteProtoLibTarget(target) |
| else: |
| raise NotImplementedError('I do not know how to write {}'.format( |
| str(target))) |
| |
| self.nl() |
| |
| def GnDep(self, dep): |
| if not dep.InTree(): |
| return dep.GetGnDep() |
| |
| target = self.GetTargetForInTreeDep(dep) |
| |
| if target in self._build_file: |
| return ':{}'.format(target.name()) |
| if target.spec().startswith('//:'): |
| return '{}:{}'.format(self._deps_prefix, target.spec()[3:]) |
| return '{}/{}'.format(self._deps_prefix, target.spec()[2:]) |
| |
| def FormatValue(self, value): |
| if isinstance(value, str): |
| return '"{}"'.format(value) |
| |
| if isinstance(value, TargetRef): |
| return '"{}"'.format(self.GnDep(value)) |
| |
| raise Exception('I do not know how to write the {} value'.format( |
| repr(value))) |
| |
| def WriteGnVariable(self, name, value): |
| if isinstance(value, SetGnListValue): |
| self.WriteGnSetListVariable(name, value) |
| return |
| if isinstance(value, RemoveGnListValue): |
| self.WriteGnRemoveListVariable(name, value) |
| return |
| self.emitnl('{} = {}'.format(name, self.FormatValue(value))) |
| |
| def WriteGnListVariable(self, name, value, op): |
| if len(value) == 0: |
| return |
| |
| if len(value) == 1: |
| single_line = '{} {} [ {} ]'.format(name, op, self.FormatValue(value[0])) |
| if len(single_line) <= self._max_line: |
| self.emitnl(single_line) |
| return |
| |
| self.emitnl('{} {} ['.format(name, op)) |
| self.indent() |
| |
| for item in value: |
| self.emitnl('{},'.format(self.FormatValue(item))) |
| |
| self.deindent() |
| self.emitnl(']') |
| |
| def WriteGnSetListVariable(self, name, value): |
| self.WriteGnListVariable(name, value, "=") |
| |
| def WriteGnRemoveListVariable(self, name, value): |
| # Add and then remove the variable in case the var wasn't already added |
| self.WriteGnListVariable(name, value, "+=") |
| self.WriteGnListVariable(name, value, "-=") |
| |
| def WriteGnTarget(self, target_type, name, variables): |
| self.emitnl('{}("{}") {{'.format(target_type, name)) |
| self.indent() |
| for var, value in variables.items(): |
| self.WriteGnVariable(var, value) |
| self.deindent() |
| self.emitnl('}') |
| pass |
| |
| def WriteProtoLibTarget(self, target): |
| variables = GnVariables() |
| variables['cc_generator_options'] = 'lite' |
| variables['proto_in_dir'] = '//third_party/tink/cc' |
| variables['extra_configs'] = ['//third_party/tink:tink_config'] |
| variables['sources'] = sorted(target.srcs) |
| variables['deps'] = target.deps() |
| |
| self.WriteGnTarget('proto_library', target.name(), variables) |
| |
| def WriteCcLibTarget(self, target): |
| variables = GnVariables() |
| variables['configs'] = RemoveGnListValue(['//build/config:no_rtti']) |
| variables['sources'] = sorted(target.srcs + target.hdrs) |
| variables['public_deps'] = target.deps() |
| variables['public_configs'] = ['//third_party/tink:tink_config'] |
| |
| self.WriteGnTarget('source_set', target.name(), variables) |
| |
| def FetchTargets(targets, root_path, ignored_targets): |
| graph = BuildGraph(root_path, ignored_targets) |
| fetcher = TargetFetcher(graph, targets, error_on_unknown=True) |
| targets = fetcher.FetchAll() |
| print('Found {} targets.'.format(len(targets))) |
| return targets, graph |
| |
| def WriteTargetsToGn(targets, graph, root_path, deps_prefix): |
| build_files = CreateBuildFiles(targets) |
| gn_writer = GnWriter( |
| rootdir=root_path, |
| build_graph=graph, |
| max_line=80, |
| deps_prefix=deps_prefix) |
| for f in build_files: |
| gn_writer.WriteBuildFile(f) |
| |
| def main(args): |
| script_path = os.path.abspath(args[0]) |
| tools_path = os.path.dirname(script_path) |
| tink_path = os.path.dirname(tools_path) |
| cc_path = os.path.join(tink_path, 'cc') |
| |
| # Targets listed here will be ignored. |
| ignored_targets = frozenset([]) |
| |
| # Targets listed her are the start of the fetch. Put all the targets you plan |
| # on directly depending upon here. |
| targets = [ |
| '//hybrid:config_v0', |
| '//hybrid:hybrid_config', |
| '//hybrid:hpke_config', |
| '//hybrid:hybrid_decrypt_factory', |
| '//hybrid:hybrid_encrypt_factory', |
| '//hybrid:hybrid_key_templates', |
| '//:binary_keyset_reader', |
| '//:binary_keyset_writer', |
| '//:cleartext_keyset_handle', |
| '//:hybrid_decrypt', |
| '//:hybrid_encrypt', |
| '//:keyset_handle', |
| ] |
| targets, graph = FetchTargets(targets, cc_path, ignored_targets) |
| WriteTargetsToGn(targets, graph, cc_path, '//third_party/tink/cc') |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv)) |