1*4882a593Smuzhiyun#!/usr/bin/env python3 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun# Query which tasks will be restored from sstate 4*4882a593Smuzhiyun# 5*4882a593Smuzhiyun# Copyright 2016 Intel Corporation 6*4882a593Smuzhiyun# Authored-by: Paul Eggleton <paul.eggleton@intel.com> 7*4882a593Smuzhiyun# 8*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only 9*4882a593Smuzhiyun# 10*4882a593Smuzhiyun 11*4882a593Smuzhiyunimport sys 12*4882a593Smuzhiyunimport os 13*4882a593Smuzhiyunimport subprocess 14*4882a593Smuzhiyunimport tempfile 15*4882a593Smuzhiyunimport shutil 16*4882a593Smuzhiyunimport re 17*4882a593Smuzhiyun 18*4882a593Smuzhiyunscripts_path = os.path.dirname(os.path.realpath(__file__)) 19*4882a593Smuzhiyunlib_path = scripts_path + '/lib' 20*4882a593Smuzhiyunsys.path = sys.path + [lib_path] 21*4882a593Smuzhiyunimport scriptpath 22*4882a593Smuzhiyunscriptpath.add_bitbake_lib_path() 23*4882a593Smuzhiyunimport argparse_oe 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun 26*4882a593Smuzhiyundef translate_virtualfns(tasks): 27*4882a593Smuzhiyun import bb.tinfoil 28*4882a593Smuzhiyun tinfoil = bb.tinfoil.Tinfoil() 29*4882a593Smuzhiyun try: 30*4882a593Smuzhiyun tinfoil.prepare(False) 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun recipecaches = tinfoil.cooker.recipecaches 33*4882a593Smuzhiyun outtasks = [] 34*4882a593Smuzhiyun for task in tasks: 35*4882a593Smuzhiyun (mc, fn, taskname) = bb.runqueue.split_tid(task) 36*4882a593Smuzhiyun if taskname.endswith('_setscene'): 37*4882a593Smuzhiyun taskname = taskname[:-9] 38*4882a593Smuzhiyun outtasks.append('%s:%s' % (recipecaches[mc].pkg_fn[fn], taskname)) 39*4882a593Smuzhiyun finally: 40*4882a593Smuzhiyun tinfoil.shutdown() 41*4882a593Smuzhiyun return outtasks 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun 44*4882a593Smuzhiyundef check(args): 45*4882a593Smuzhiyun tmpdir = tempfile.mkdtemp(prefix='oe-check-sstate-') 46*4882a593Smuzhiyun try: 47*4882a593Smuzhiyun env = os.environ.copy() 48*4882a593Smuzhiyun if not args.same_tmpdir: 49*4882a593Smuzhiyun env['BB_ENV_PASSTHROUGH_ADDITIONS'] = env.get('BB_ENV_PASSTHROUGH_ADDITIONS', '') + ' TMPDIR:forcevariable' 50*4882a593Smuzhiyun env['TMPDIR:forcevariable'] = tmpdir 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun try: 53*4882a593Smuzhiyun cmd = ['bitbake', '--dry-run', '--runall=build'] + args.target 54*4882a593Smuzhiyun output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, env=env) 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun task_re = re.compile('NOTE: Running setscene task [0-9]+ of [0-9]+ \(([^)]+)\)') 57*4882a593Smuzhiyun tasks = [] 58*4882a593Smuzhiyun for line in output.decode('utf-8').splitlines(): 59*4882a593Smuzhiyun res = task_re.match(line) 60*4882a593Smuzhiyun if res: 61*4882a593Smuzhiyun tasks.append(res.group(1)) 62*4882a593Smuzhiyun outtasks = translate_virtualfns(tasks) 63*4882a593Smuzhiyun except subprocess.CalledProcessError as e: 64*4882a593Smuzhiyun print('ERROR: bitbake failed:\n%s' % e.output.decode('utf-8')) 65*4882a593Smuzhiyun return e.returncode 66*4882a593Smuzhiyun finally: 67*4882a593Smuzhiyun shutil.rmtree(tmpdir) 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun if args.log: 70*4882a593Smuzhiyun with open(args.log, 'wb') as f: 71*4882a593Smuzhiyun f.write(output) 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun if args.outfile: 74*4882a593Smuzhiyun with open(args.outfile, 'w') as f: 75*4882a593Smuzhiyun for task in outtasks: 76*4882a593Smuzhiyun f.write('%s\n' % task) 77*4882a593Smuzhiyun else: 78*4882a593Smuzhiyun for task in outtasks: 79*4882a593Smuzhiyun print(task) 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun return 0 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun 84*4882a593Smuzhiyundef main(): 85*4882a593Smuzhiyun parser = argparse_oe.ArgumentParser(description='OpenEmbedded sstate check tool. Does a dry-run to check restoring the specified targets from shared state, and lists the tasks that would be restored. Set BB_SETSCENE_ENFORCE=1 in the environment if you wish to ensure real tasks are disallowed.') 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun parser.add_argument('target', nargs='+', help='Target to check') 88*4882a593Smuzhiyun parser.add_argument('-o', '--outfile', help='Write list to a file instead of stdout') 89*4882a593Smuzhiyun parser.add_argument('-l', '--log', help='Write full log to a file') 90*4882a593Smuzhiyun parser.add_argument('-s', '--same-tmpdir', action='store_true', help='Use same TMPDIR for check (list will then be dependent on what tasks have executed previously)') 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun parser.set_defaults(func=check) 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun args = parser.parse_args() 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun ret = args.func(args) 97*4882a593Smuzhiyun return ret 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun 100*4882a593Smuzhiyunif __name__ == "__main__": 101*4882a593Smuzhiyun try: 102*4882a593Smuzhiyun ret = main() 103*4882a593Smuzhiyun except Exception: 104*4882a593Smuzhiyun ret = 1 105*4882a593Smuzhiyun import traceback 106*4882a593Smuzhiyun traceback.print_exc() 107*4882a593Smuzhiyun sys.exit(ret) 108