1# 2# Copyright OpenEmbedded Contributors 3# 4# SPDX-License-Identifier: MIT 5# 6 7OE_TERMINAL ?= 'auto' 8OE_TERMINAL[type] = 'choice' 9OE_TERMINAL[choices] = 'auto none \ 10 ${@oe_terminal_prioritized()}' 11 12OE_TERMINAL_EXPORTS += 'EXTRA_OEMAKE CACHED_CONFIGUREVARS CONFIGUREOPTS EXTRA_OECONF' 13OE_TERMINAL_EXPORTS[type] = 'list' 14 15XAUTHORITY ?= "${HOME}/.Xauthority" 16SHELL ?= "bash" 17 18def oe_terminal_prioritized(): 19 import oe.terminal 20 return " ".join(o.name for o in oe.terminal.prioritized()) 21 22def emit_terminal_func(command, envdata, d): 23 import bb.build 24 cmd_func = 'do_terminal' 25 26 envdata.setVar(cmd_func, 'exec ' + command) 27 envdata.setVarFlag(cmd_func, 'func', '1') 28 29 runfmt = d.getVar('BB_RUNFMT') or "run.{func}.{pid}" 30 runfile = runfmt.format(func=cmd_func, task=cmd_func, taskfunc=cmd_func, pid=os.getpid()) 31 runfile = os.path.join(d.getVar('T'), runfile) 32 bb.utils.mkdirhier(os.path.dirname(runfile)) 33 34 with open(runfile, 'w') as script: 35 # Override the shell shell_trap_code specifies. 36 # If our shell is bash, we might well face silent death. 37 script.write("#!/bin/bash\n") 38 script.write(bb.build.shell_trap_code()) 39 bb.data.emit_func(cmd_func, script, envdata) 40 script.write(cmd_func) 41 script.write("\n") 42 os.chmod(runfile, 0o755) 43 44 return runfile 45 46def oe_terminal(command, title, d): 47 import oe.data 48 import oe.terminal 49 50 envdata = bb.data.init() 51 52 for v in os.environ: 53 envdata.setVar(v, os.environ[v]) 54 envdata.setVarFlag(v, 'export', '1') 55 56 for export in oe.data.typed_value('OE_TERMINAL_EXPORTS', d): 57 value = d.getVar(export) 58 if value is not None: 59 os.environ[export] = str(value) 60 envdata.setVar(export, str(value)) 61 envdata.setVarFlag(export, 'export', '1') 62 if export == "PSEUDO_DISABLED": 63 if "PSEUDO_UNLOAD" in os.environ: 64 del os.environ["PSEUDO_UNLOAD"] 65 envdata.delVar("PSEUDO_UNLOAD") 66 67 # Add in all variables from the user's original environment which 68 # haven't subsequntly been set/changed 69 origbbenv = d.getVar("BB_ORIGENV", False) or {} 70 for key in origbbenv: 71 if key in envdata: 72 continue 73 value = origbbenv.getVar(key) 74 if value is not None: 75 os.environ[key] = str(value) 76 envdata.setVar(key, str(value)) 77 envdata.setVarFlag(key, 'export', '1') 78 79 # Use original PATH as a fallback 80 path = d.getVar('PATH') + ":" + origbbenv.getVar('PATH') 81 os.environ['PATH'] = path 82 envdata.setVar('PATH', path) 83 84 # A complex PS1 might need more escaping of chars. 85 # Lets not export PS1 instead. 86 envdata.delVar("PS1") 87 88 # Replace command with an executable wrapper script 89 command = emit_terminal_func(command, envdata, d) 90 91 terminal = oe.data.typed_value('OE_TERMINAL', d).lower() 92 if terminal == 'none': 93 bb.fatal('Devshell usage disabled with OE_TERMINAL') 94 elif terminal != 'auto': 95 try: 96 oe.terminal.spawn(terminal, command, title, None, d) 97 return 98 except oe.terminal.UnsupportedTerminal: 99 bb.warn('Unsupported terminal "%s", defaulting to "auto"' % 100 terminal) 101 except oe.terminal.ExecutionError as exc: 102 bb.fatal('Unable to spawn terminal %s: %s' % (terminal, exc)) 103 104 try: 105 oe.terminal.spawn_preferred(command, title, None, d) 106 except oe.terminal.NoSupportedTerminals as nosup: 107 nosup.terms.remove("false") 108 cmds = '\n\t'.join(nosup.terms).replace("{command}", 109 "do_terminal").replace("{title}", title) 110 bb.fatal('No valid terminal found, unable to open devshell.\n' + 111 'Tried the following commands:\n\t%s' % cmds) 112 except oe.terminal.ExecutionError as exc: 113 bb.fatal('Unable to spawn terminal %s: %s' % (terminal, exc)) 114 115oe_terminal[vardepsexclude] = "BB_ORIGENV" 116