|
|
|
#!/usr/bin/env python2
|
|
|
|
|
|
|
|
from __future__ import print_function
|
|
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import pprint
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
def die(msg):
|
|
|
|
print(msg, file=sys.stderr)
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
def do_unbundle(gypdata, targets):
|
|
|
|
gyptargets = {t['target_name']: t for t in gypdata['targets']}
|
|
|
|
dropped_deps = set()
|
|
|
|
|
|
|
|
def _unbundle_in_block(gypblock):
|
|
|
|
gypdeps = gypblock.get('dependencies') or {}
|
|
|
|
|
|
|
|
for dep, (libs, defines) in unbundlings.items():
|
|
|
|
if dep not in gypdeps:
|
|
|
|
continue
|
|
|
|
|
|
|
|
gypdeps.remove(dep)
|
|
|
|
|
|
|
|
try:
|
|
|
|
ls = gyptarget['link_settings']
|
|
|
|
except KeyError:
|
|
|
|
ls = gyptarget['link_settings'] = {}
|
|
|
|
|
|
|
|
try:
|
|
|
|
gyplibs = ls['libraries']
|
|
|
|
except KeyError:
|
|
|
|
gyplibs = ls['libraries'] = []
|
|
|
|
|
|
|
|
gyplibs.extend('-l{}'.format(lib) for lib in libs)
|
|
|
|
|
|
|
|
if defines:
|
|
|
|
try:
|
|
|
|
dd = gyptarget['defines']
|
|
|
|
except KeyError:
|
|
|
|
dd = gyptarget['defines'] = []
|
|
|
|
|
|
|
|
dd.extend(defines)
|
|
|
|
|
|
|
|
dropped_deps.add(dep)
|
|
|
|
|
|
|
|
gypconds = gypblock.get('conditions') or []
|
|
|
|
for cond in gypconds:
|
|
|
|
condblocks = cond[1:]
|
|
|
|
for condblock in condblocks:
|
|
|
|
_unbundle_in_block(condblock)
|
|
|
|
|
|
|
|
for target, unbundlings in targets.items():
|
|
|
|
if target not in gyptargets:
|
|
|
|
die('There is no {} target in gyp file'.format(target))
|
|
|
|
|
|
|
|
gyptarget = gyptargets[target]
|
|
|
|
|
|
|
|
_unbundle_in_block(gyptarget)
|
|
|
|
|
|
|
|
for gyptarget in gypdata['targets']:
|
|
|
|
if gyptarget['target_name'] in dropped_deps:
|
|
|
|
if gyptarget.get('dependencies'):
|
|
|
|
dropped_deps.update(gyptarget.get('dependencies'))
|
|
|
|
|
|
|
|
new_targets = []
|
|
|
|
for gyptarget in gypdata['targets']:
|
|
|
|
if gyptarget['target_name'] not in dropped_deps:
|
|
|
|
new_targets.append(gyptarget)
|
|
|
|
|
|
|
|
gypdata['targets'] = new_targets
|
|
|
|
|
|
|
|
gypconds = gypdata.get('conditions')
|
|
|
|
if gypconds:
|
|
|
|
for cond in gypconds:
|
|
|
|
condblocks = cond[1:]
|
|
|
|
for condblock in condblocks:
|
|
|
|
new_targets = []
|
|
|
|
blocktargets = condblock.get('targets')
|
|
|
|
if blocktargets:
|
|
|
|
for blocktarget in blocktargets:
|
|
|
|
if blocktarget['target_name'] not in dropped_deps:
|
|
|
|
new_targets.append(blocktarget)
|
|
|
|
condblock['targets'] = new_targets
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
parser = argparse.ArgumentParser(description='Unbundle libs in gyp files')
|
|
|
|
parser.add_argument('gypfile', type=str, help='input gyp file')
|
|
|
|
parser.add_argument(
|
|
|
|
'--unbundle', type=str, action='append',
|
|
|
|
help='unbundle rule in the format '
|
|
|
|
'<target>;<dep>;<lib>[;lib][;-DMACRO]')
|
|
|
|
parser.add_argument(
|
|
|
|
'-i', '--inplace', action='store_true',
|
|
|
|
help='modify gyp file in-place')
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
targets = {}
|
|
|
|
|
|
|
|
for unbundle in args.unbundle:
|
|
|
|
rule = list(filter(None, (i.strip() for i in unbundle.split(';'))))
|
|
|
|
if len(rule) < 3:
|
|
|
|
die('Invalid unbundle rule: {!r}'.format(unbundle))
|
|
|
|
target, dep = rule[:2]
|
|
|
|
|
|
|
|
defines = []
|
|
|
|
libs = []
|
|
|
|
|
|
|
|
for item in rule[2:]:
|
|
|
|
if item.startswith('-D'):
|
|
|
|
defines.append(item[2:])
|
|
|
|
else:
|
|
|
|
libs.append(item)
|
|
|
|
|
|
|
|
try:
|
|
|
|
target_unbundlings = targets[target]
|
|
|
|
except KeyError:
|
|
|
|
target_unbundlings = targets[target] = {}
|
|
|
|
|
|
|
|
target_unbundlings[dep] = libs, defines
|
|
|
|
|
|
|
|
with open(args.gypfile, 'rt') as f:
|
|
|
|
gypdata = eval(f.read())
|
|
|
|
|
|
|
|
do_unbundle(gypdata, targets)
|
|
|
|
|
|
|
|
if args.inplace:
|
|
|
|
with open(args.gypfile, 'wt') as f:
|
|
|
|
pprint.pprint(gypdata, stream=f)
|
|
|
|
else:
|
|
|
|
pprint.pprint(gypdata)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|