manually encode newlines on all printed commands

This way we group key value arguments: e.g.:

    make \
    -j 8 \
    all

instead of:

    make \
    -j \
    8 \
    all

and reach CLI nirvana, while also subtly breaking several commands due to
lack of testing.
This commit is contained in:
Ciro Santilli 六四事件 法轮功
2018-11-04 00:00:00 +00:00
parent 196dd616ff
commit 8fb9db3931
16 changed files with 263 additions and 211 deletions

4
build
View File

@@ -76,6 +76,9 @@ name_to_component_map = {
'qemu': Component( 'qemu': Component(
lambda arch: run_cmd(['build-qemu'], arch), lambda arch: run_cmd(['build-qemu'], arch),
), ),
'qemu-user': Component(
lambda arch: run_cmd(['build-qemu', '--userland'], arch),
),
'userland': Component( 'userland': Component(
lambda arch: run_cmd(['build-userland'], arch), lambda arch: run_cmd(['build-userland'], arch),
), ),
@@ -85,6 +88,7 @@ name_to_component_map = {
'qemu-gem5-buildroot', 'qemu-gem5-buildroot',
'gem5-debug', 'gem5-debug',
'gem5-fast', 'gem5-fast',
'qemu-user',
]), ]),
'gem5-buildroot': Component(dependencies=[ 'gem5-buildroot': Component(dependencies=[
'buildroot-gcc', 'buildroot-gcc',

View File

@@ -11,10 +11,10 @@ class BaremetalComponent(common.Component):
bootloader_obj = os.path.join(common.baremetal_build_lib_dir, 'bootloader{}'.format(common.obj_ext)) bootloader_obj = os.path.join(common.baremetal_build_lib_dir, 'bootloader{}'.format(common.obj_ext))
common_obj = os.path.join(common.baremetal_build_lib_dir, 'common{}'.format(common.obj_ext)) common_obj = os.path.join(common.baremetal_build_lib_dir, 'common{}'.format(common.obj_ext))
cflags = [ cflags = [
'-ggdb3', '-ggdb3', common.Newline,
'-mcpu={}'.format(common.mcpu), '-mcpu={}'.format(common.mcpu), common.Newline,
'-nostartfiles', '-nostartfiles', common.Newline,
'-O0', '-O0', common.Newline,
] ]
if args.prebuilt: if args.prebuilt:
gcc = 'arm-none-eabi-gcc' gcc = 'arm-none-eabi-gcc'
@@ -36,23 +36,23 @@ class BaremetalComponent(common.Component):
os.makedirs(build_dir, exist_ok=True) os.makedirs(build_dir, exist_ok=True)
os.makedirs(common.baremetal_build_lib_dir, exist_ok=True) os.makedirs(common.baremetal_build_lib_dir, exist_ok=True)
common.run_cmd( common.run_cmd(
[gcc] + [gcc, common.Newline] +
cflags + cflags +
[ [
'-c', '-c', common.Newline,
'-o', bootloader_obj, '-o', bootloader_obj, common.Newline,
os.path.join(common.baremetal_src_lib_dir, '{}{}'.format(args.arch, common.asm_ext)), os.path.join(common.baremetal_src_lib_dir, '{}{}'.format(args.arch, common.asm_ext)), common.Newline,
] ]
) )
common.run_cmd( common.run_cmd(
[gcc] + [gcc, common.Newline] +
cflags + cflags +
[ [
'-c', '-c', common.Newline,
'-D', '-D', common.Newline,
'UART0_ADDR={:#x}'.format(uart_address), 'UART0_ADDR={:#x}'.format(uart_address), common.Newline,
'-o', common_obj, '-o', common_obj, common.Newline,
os.path.join(common.baremetal_src_lib_dir, 'common' + common.c_ext), os.path.join(common.baremetal_src_lib_dir, 'common' + common.c_ext), common.Newline,
] ]
) )
self._build_dir( self._build_dir(
@@ -117,7 +117,7 @@ Build the baremetal examples with crosstool-NG.
out_dir = os.path.join(common.baremetal_build_dir, subpath) out_dir = os.path.join(common.baremetal_build_dir, subpath)
os.makedirs(out_dir, exist_ok=True) os.makedirs(out_dir, exist_ok=True)
if bootloader: if bootloader:
bootloader_cmd = [bootloader_obj] bootloader_cmd = [bootloader_obj, common.Newline]
else: else:
bootloader_cmd = [] bootloader_cmd = []
for in_basename in os.listdir(in_dir): for in_basename in os.listdir(in_dir):
@@ -126,26 +126,26 @@ Build the baremetal examples with crosstool-NG.
in_name = os.path.splitext(in_basename)[0] in_name = os.path.splitext(in_basename)[0]
main_obj = os.path.join(common.baremetal_build_dir, subpath, '{}{}'.format(in_name, common.obj_ext)) main_obj = os.path.join(common.baremetal_build_dir, subpath, '{}{}'.format(in_name, common.obj_ext))
common.run_cmd( common.run_cmd(
[gcc] + [gcc, common.Newline] +
cflags + cflags +
[ [
'-c', '-c', common.Newline,
'-o', main_obj, '-o', main_obj, common.Newline,
os.path.join(common.baremetal_src_dir, in_path), os.path.join(common.baremetal_src_dir, in_path), common.Newline,
] ]
) )
common.run_cmd( common.run_cmd(
[gcc] + [gcc, common.Newline] +
cflags + cflags +
[ [
'-Wl,--section-start=.text={:#x}'.format(entry_address), '-Wl,--section-start=.text={:#x}'.format(entry_address), common.Newline,
'-o', os.path.join(common.baremetal_build_dir, subpath, in_name + common.baremetal_build_ext), '-o', os.path.join(common.baremetal_build_dir, subpath, in_name + common.baremetal_build_ext), common.Newline,
'-T', os.path.join(common.baremetal_src_dir, 'link.ld'), '-T', os.path.join(common.baremetal_src_dir, 'link.ld'), common.Newline,
] + ] +
bootloader_cmd + bootloader_cmd +
[ [
common_obj, common_obj, common.Newline,
main_obj, main_obj, common.Newline,
] ]
) )

View File

@@ -59,11 +59,11 @@ usually extra Buildroot targets.
def do_build(self, args): def do_build(self, args):
build_dir = self.get_build_dir(args) build_dir = self.get_build_dir(args)
os.makedirs(common.out_dir, exist_ok=True) os.makedirs(common.out_dir, exist_ok=True)
extra_make_args = args.extra_make_args.copy() extra_make_args = common.add_newlines(args.extra_make_args)
if args.build_linux: if args.build_linux:
extra_make_args.append('linux-reconfigure') extra_make_args.extend(['linux-reconfigure', common.Newline])
if args.gem5: if args.gem5:
extra_make_args.append('gem5-reconfigure') extra_make_args.extend(['gem5-reconfigure', common.Newline])
if args.arch == 'x86_64': if args.arch == 'x86_64':
defconfig = 'qemu_x86_64_defconfig' defconfig = 'qemu_x86_64_defconfig'
elif args.arch == 'arm': elif args.arch == 'arm':
@@ -78,10 +78,10 @@ usually extra Buildroot targets.
br2_external_str = ':'.join(br2_external_dirs) br2_external_str = ':'.join(br2_external_dirs)
common.run_cmd( common.run_cmd(
[ [
'make', 'make', common.Newline,
'O={}'.format(common.buildroot_build_dir), 'O={}'.format(common.buildroot_build_dir), common.Newline,
'BR2_EXTERNAL={}'.format(br2_external_str), 'BR2_EXTERNAL={}'.format(br2_external_str), common.Newline,
defconfig, defconfig, common.Newline,
], ],
cwd=common.buildroot_src_dir, cwd=common.buildroot_src_dir,
) )
@@ -122,22 +122,22 @@ usually extra Buildroot targets.
common.write_configs(common.buildroot_config_file, configs, config_fragments) common.write_configs(common.buildroot_config_file, configs, config_fragments)
common.run_cmd( common.run_cmd(
[ [
'make', 'make', common.Newline,
'O={}'.format(common.buildroot_build_dir), 'O={}'.format(common.buildroot_build_dir), common.Newline,
'olddefconfig', 'olddefconfig', common.Newline,
], ],
cwd=common.buildroot_src_dir, cwd=common.buildroot_src_dir,
) )
common.make_build_dirs() common.make_build_dirs()
if not args.no_all: if not args.no_all:
extra_make_args.append('all') extra_make_args.extend(['all', common.Newline])
common.run_cmd( common.run_cmd(
[ [
'make', 'make', common.Newline,
'LKMC_GEM5_SRCDIR="{}"'.format(common.gem5_src_dir), 'LKMC_GEM5_SRCDIR="{}"'.format(common.gem5_src_dir), common.Newline,
'LKMC_PARSEC_BENCHMARK_SRCDIR="{}"'.format(common.parsec_benchmark_src_dir), 'LKMC_PARSEC_BENCHMARK_SRCDIR="{}"'.format(common.parsec_benchmark_src_dir), common.Newline,
'O={}'.format(common.buildroot_build_dir), 'O={}'.format(common.buildroot_build_dir), common.Newline,
'V={}'.format(int(args.verbose)), 'V={}'.format(int(args.verbose)), common.Newline,
] + ] +
extra_make_args extra_make_args
, ,

View File

@@ -16,19 +16,19 @@ class CrosstoolNgComponent(common.Component):
# https://github.com/crosstool-ng/crosstool-ng/issues/1021 # https://github.com/crosstool-ng/crosstool-ng/issues/1021
os.chdir(common.crosstool_ng_src_dir) os.chdir(common.crosstool_ng_src_dir)
common.run_cmd( common.run_cmd(
[os.path.join(common.crosstool_ng_src_dir, 'bootstrap')], [os.path.join(common.crosstool_ng_src_dir, 'bootstrap'), common.Newline],
) )
os.chdir(common.crosstool_ng_util_dir) os.chdir(common.crosstool_ng_util_dir)
common.run_cmd( common.run_cmd(
[ [
os.path.join(common.crosstool_ng_src_dir, 'configure'), os.path.join(common.crosstool_ng_src_dir, 'configure'), common.Newline,
'--enable-local', '--enable-local', common.Newline,
], ],
) )
common.run_cmd( common.run_cmd(
[ [
'make', 'make', common.Newline,
'-j', str(args.nproc), '-j', str(args.nproc), common.Newline,
], ],
) )
@@ -47,16 +47,16 @@ class CrosstoolNgComponent(common.Component):
) )
common.run_cmd( common.run_cmd(
[ [
common.crosstool_ng_executable, common.crosstool_ng_executable, common.Newline,
'defconfig', 'defconfig', common.Newline,
], ],
) )
os.unlink(defconfig_dest) os.unlink(defconfig_dest)
common.run_cmd( common.run_cmd(
[ [
common.crosstool_ng_executable, common.crosstool_ng_executable, common.Newline,
'build', 'build', common.Newline,
'CT_JOBS={}'.format(str(args.nproc)), 'CT_JOBS={}'.format(str(args.nproc)), common.Newline,
], ],
out_file=os.path.join(build_dir, 'lkmc.log'), out_file=os.path.join(build_dir, 'lkmc.log'),
delete_env=['LD_LIBRARY_PATH'], delete_env=['LD_LIBRARY_PATH'],

View File

@@ -26,14 +26,14 @@ class Gem5Component(common.Component):
if common.gem5_src_dir == common.gem5_default_src_dir: if common.gem5_src_dir == common.gem5_default_src_dir:
raise Exception('gem5 submodule not checked out') raise Exception('gem5 submodule not checked out')
common.run_cmd([ common.run_cmd([
'git', 'git', common.Newline,
'-C', common.gem5_default_src_dir, '-C', common.gem5_default_src_dir, common.Newline,
'worktree', 'add', 'worktree', 'add', common.Newline,
'-b', os.path.join('wt', args.gem5_build_id), '-b', os.path.join('wt', args.gem5_build_id), common.Newline,
common.gem5_src_dir common.gem5_src_dir, common.Newline,
]) ])
if args.verbose: if args.verbose:
verbose = ['--verbose'] verbose = ['--verbose', common.Newline]
else: else:
verbose = [] verbose = []
if args.arch == 'x86_64': if args.arch == 'x86_64':
@@ -53,7 +53,10 @@ class Gem5Component(common.Component):
# dtb # dtb
dt_src_dir = os.path.join(gem5_system_src_dir, 'arm', 'dt') dt_src_dir = os.path.join(gem5_system_src_dir, 'arm', 'dt')
dt_build_dir = os.path.join(common.gem5_system_dir, 'arm', 'dt') dt_build_dir = os.path.join(common.gem5_system_dir, 'arm', 'dt')
common.run_cmd(['make', '-C', dt_src_dir]) common.run_cmd([
'make', common.Newline,
'-C', dt_src_dir, common.Newline,
])
common.copy_dir_if_update_non_recursive( common.copy_dir_if_update_non_recursive(
srcdir=dt_src_dir, srcdir=dt_src_dir,
destdir=dt_build_dir, destdir=dt_build_dir,
@@ -63,25 +66,31 @@ class Gem5Component(common.Component):
# Bootloader 32. # Bootloader 32.
bootloader32_dir = os.path.join(gem5_system_src_dir, 'arm', 'simple_bootloader') bootloader32_dir = os.path.join(gem5_system_src_dir, 'arm', 'simple_bootloader')
# TODO use the buildroot cross compiler here, and remove the dependencies from configure. # TODO use the buildroot cross compiler here, and remove the dependencies from configure.
common.run_cmd(['make', '-C', bootloader32_dir]) common.run_cmd([
'make', common.Newline,
'-C', bootloader32_dir, common.Newline,
])
# bootloader # bootloader
common.cp(os.path.join(bootloader32_dir, 'boot_emm.arm'), binaries_dir) common.cp(os.path.join(bootloader32_dir, 'boot_emm.arm'), binaries_dir)
# Bootloader 64. # Bootloader 64.
bootloader64_dir = os.path.join(gem5_system_src_dir, 'arm', 'aarch64_bootloader') bootloader64_dir = os.path.join(gem5_system_src_dir, 'arm', 'aarch64_bootloader')
# TODO cross_compile is ignored because the make does not use CC... # TODO cross_compile is ignored because the make does not use CC...
common.run_cmd(['make', '-C', bootloader64_dir]) common.run_cmd([
'make', common.Newline,
'-C', bootloader64_dir, common.Newline
])
common.cp(os.path.join(bootloader64_dir, 'boot_emm.arm64'), binaries_dir) common.cp(os.path.join(bootloader64_dir, 'boot_emm.arm64'), binaries_dir)
common.run_cmd( common.run_cmd(
( (
[ [
'scons', 'scons', common.Newline,
'-j', str(args.nproc), '-j', str(args.nproc), common.Newline,
'--ignore-style', '--ignore-style', common.Newline,
common.gem5_executable common.gem5_executable, common.Newline,
] + ] +
verbose + verbose +
args.extra_scons_args common.add_newlines(args.extra_scons_args)
), ),
cwd=common.gem5_src_dir, cwd=common.gem5_src_dir,
extra_paths=[common.ccache_dir], extra_paths=[common.ccache_dir],

View File

@@ -66,12 +66,12 @@ Configure the kernel, but don't build it.
else: else:
cc = gcc cc = gcc
common_make_args = [ common_make_args = [
'make', 'make', common.Newline,
'-j', str(args.nproc), '-j', str(args.nproc), common.Newline,
'ARCH={}'.format(common.linux_arch), 'ARCH={}'.format(common.linux_arch), common.Newline,
'CROSS_COMPILE={}'.format(prefix), 'CROSS_COMPILE={}'.format(prefix), common.Newline,
'CC={}'.format(cc), 'CC={}'.format(cc), common.Newline,
'O={}'.format(build_dir), 'O={}'.format(build_dir), common.Newline,
] ]
if args.verbose: if args.verbose:
verbose = ['V=1'] verbose = ['V=1']
@@ -99,17 +99,17 @@ Configure the kernel, but don't build it.
) )
common.run_cmd( common.run_cmd(
[ [
os.path.join(common.linux_src_dir, 'scripts', 'kconfig', 'merge_config.sh'), os.path.join(common.linux_src_dir, 'scripts', 'kconfig', 'merge_config.sh'), common.Newline,
'-m', '-m', common.Newline,
'-O', build_dir, '-O', build_dir, common.Newline,
os.path.join(build_dir, '.config'), os.path.join(build_dir, '.config'), common.Newline,
] + ] +
config_fragments config_fragments
) )
common.run_cmd( common.run_cmd(
( (
common_make_args + common_make_args +
['olddefconfig'] ['olddefconfig', common.Newline]
), ),
**common_args **common_args
) )
@@ -117,7 +117,7 @@ Configure the kernel, but don't build it.
common.run_cmd( common.run_cmd(
( (
common_make_args + common_make_args +
args.extra_make_args common.add_newlines(args.extra_make_args)
), ),
**common_args **common_args
) )

View File

@@ -14,12 +14,12 @@ class M5Component(common.Component):
else: else:
arch = args.arch arch = args.arch
return [ return [
'make', 'make', common.Newline,
'-j', str(args.nproc), '-j', str(args.nproc), common.Newline,
'-f', 'Makefile.{}'.format(arch), '-f', 'Makefile.{}'.format(arch), common.Newline,
'CC={}'.format(cc), 'CC={}'.format(cc), common.Newline,
'LD={}'.format(ld), 'LD={}'.format(ld), common.Newline,
'PWD={}'.format(common.gem5_m5_src_dir), 'PWD={}'.format(common.gem5_m5_src_dir), common.Newline,
] ]
def do_build(self, args): def do_build(self, args):
@@ -36,7 +36,7 @@ class M5Component(common.Component):
def clean(self, args): def clean(self, args):
common.run_cmd( common.run_cmd(
self.get_make_cmd(args) + ['clean'], self.get_make_cmd(args) + ['clean', common.Newline],
cwd=common.gem5_m5_src_dir, cwd=common.gem5_m5_src_dir,
) )

View File

@@ -3,7 +3,6 @@
import distutils.dir_util import distutils.dir_util
import os import os
import platform import platform
import shlex
import shutil import shutil
import common import common
@@ -90,16 +89,16 @@ Use the host packaged cross toolchain.
common.run_cmd( common.run_cmd(
( (
[ [
'make', 'make', common.Newline,
'-j', str(args.nproc), '-j', str(args.nproc), common.Newline,
'ARCH={}'.format(common.linux_arch), 'ARCH={}'.format(common.linux_arch), common.Newline,
'CC={}'.format(cc), 'CC={}'.format(cc), common.Newline,
'CROSS_COMPILE={}'.format(prefix), 'CROSS_COMPILE={}'.format(prefix), common.Newline,
'LINUX_DIR={}'.format(linux_dir), 'LINUX_DIR={}'.format(linux_dir), common.Newline,
'M={}'.format(build_subdir), 'M={}'.format(build_subdir), common.Newline,
'OBJECT_FILES={}'.format(' '.join(object_files)), 'OBJECT_FILES={}'.format(' '.join(object_files)), common.Newline,
] + ] +
shlex.split(args.make_args) + common.shlex_split(args.make_args) +
verbose verbose
), ),
cwd=os.path.join(common.kernel_modules_build_subdir), cwd=os.path.join(common.kernel_modules_build_subdir),

View File

@@ -32,22 +32,22 @@ class QemuComponent(common.Component):
target_list = '{}-softmmu'.format(args.arch) target_list = '{}-softmmu'.format(args.arch)
common.run_cmd( common.run_cmd(
[ [
os.path.join(common.qemu_src_dir, 'configure'), os.path.join(common.qemu_src_dir, 'configure'), common.Newline,
'--enable-debug', '--enable-debug', common.Newline,
'--enable-trace-backends=simple', '--enable-trace-backends=simple', common.Newline,
'--target-list={}'.format(target_list), '--target-list={}'.format(target_list), common.Newline,
'--enable-sdl', '--enable-sdl', common.Newline,
'--with-sdlabi=2.0', '--with-sdlabi=2.0', common.Newline,
] + ] +
args.extra_config_args, common.add_newlines(args.extra_config_args),
extra_paths=[common.ccache_dir], extra_paths=[common.ccache_dir],
cwd=build_dir cwd=build_dir
) )
common.run_cmd( common.run_cmd(
( (
[ [
'make', 'make', common.Newline,
'-j', str(args.nproc), '-j', str(args.nproc), common.Newline,
] + ] +
verbose verbose

View File

@@ -56,17 +56,17 @@ has the OpenBLAS libraries and headers installed.
common.run_cmd( common.run_cmd(
( (
[ [
'make', 'make', common.Newline,
'-j', str(args.nproc), '-j', str(args.nproc), common.Newline,
'CC={}'.format(cc), 'CC={}'.format(cc), common.Newline,
'CXX={}'.format(cxx), 'CXX={}'.format(cxx), common.Newline,
'PKG_CONFIG={}'.format(common.buildroot_pkg_config), 'PKG_CONFIG={}'.format(common.buildroot_pkg_config), common.Newline,
'STAGING_DIR={}'.format(common.buildroot_staging_dir), 'STAGING_DIR={}'.format(common.buildroot_staging_dir), common.Newline,
'OUT_DIR={}'.format(build_dir), 'OUT_DIR={}'.format(build_dir), common.Newline,
] + ] +
['HAS_{}=y'.format(package.upper()) for package in args.has_package] + common.add_newlines(['HAS_{}=y'.format(package.upper()) for package in args.has_package]) +
shlex.split(args.make_args) + shlex.split(args.make_args) +
[os.path.join(build_dir, os.path.splitext(os.path.split(target)[1])[0]) + common.userland_build_ext for target in args.targets] common.add_newlines([os.path.join(build_dir, os.path.splitext(os.path.split(target)[1])[0]) + common.userland_build_ext for target in args.targets])
), ),
cwd=common.userland_src_dir, cwd=common.userland_src_dir,
extra_paths=[common.ccache_dir], extra_paths=[common.ccache_dir],

View File

@@ -8,6 +8,7 @@ import datetime
import distutils.file_util import distutils.file_util
import glob import glob
import imp import imp
import itertools
import json import json
import multiprocessing import multiprocessing
import os import os
@@ -144,6 +145,13 @@ class Component:
''' '''
return {} return {}
class Newline:
'''
Singleton class. Can be used in print_cmd to print out nicer command lines
with -key on the same line as "-key value".
'''
pass
def add_dry_run_argument(parser): def add_dry_run_argument(parser):
parser.add_argument('--dry-run', default=False, action='store_true', help='''\ parser.add_argument('--dry-run', default=False, action='store_true', help='''\
Print the commands that would be run, but don't run them. Print the commands that would be run, but don't run them.
@@ -154,6 +162,12 @@ Bash equivalents even for actions taken directly in Python without shelling out.
mkdir are generally omitted since those are obvious. mkdir are generally omitted since those are obvious.
''') ''')
def add_newlines(cmd):
out = []
for arg in cmd:
out.extend([arg, this_module.Newline])
return out
def base64_encode(string): def base64_encode(string):
return base64.b64encode(string.encode()).decode() return base64.b64encode(string.encode()).decode()
@@ -456,19 +470,29 @@ def cmd_to_string(cmd, cwd=None, extra_env=None, extra_paths=None):
Format a command given as a list of strings so that it can Format a command given as a list of strings so that it can
be viewed nicely and executed by bash directly and print it to stdout. be viewed nicely and executed by bash directly and print it to stdout.
''' '''
newline_separator = ' \\\n' last_newline = ' \\\n'
newline_separator = last_newline + ' '
out = [] out = []
if extra_env is None: if extra_env is None:
extra_env = {} extra_env = {}
if cwd is not None: if cwd is not None:
out.append('cd {} &&{}'.format(shlex.quote(cwd), newline_separator)) out.append('cd {} &&'.format(shlex.quote(cwd)))
if extra_paths is not None: if extra_paths is not None:
out.append('PATH="{}:${{PATH}}"'.format(':'.join(extra_paths)) + newline_separator) out.append('PATH="{}:${{PATH}}"'.format(':'.join(extra_paths)))
for key in extra_env: for key in extra_env:
out.append('{}={}'.format(shlex.quote(key), shlex.quote(extra_env[key])) + newline_separator) out.append('{}={}'.format(shlex.quote(key), shlex.quote(extra_env[key])))
cmd_quote = []
has_newline = False
for arg in cmd: for arg in cmd:
out.append(shlex.quote(arg) + newline_separator) if arg == this_module.Newline:
return ' '.join(out) + ';' cmd_quote.append(arg)
has_newline = True
else:
cmd_quote.append(shlex.quote(arg))
if has_newline:
cmd_quote = [' '.join(list(y)) for x, y in itertools.groupby(cmd_quote, lambda z: z == this_module.Newline) if not x]
out.extend(cmd_quote)
return newline_separator.join(out) + last_newline + ';'
def print_cmd(cmd, cwd=None, cmd_file=None, extra_env=None, extra_paths=None): def print_cmd(cmd, cwd=None, cmd_file=None, extra_env=None, extra_paths=None):
''' '''
@@ -476,6 +500,9 @@ def print_cmd(cmd, cwd=None, cmd_file=None, extra_env=None, extra_paths=None):
Optionally save the command to cmd_file file, and add extra_env Optionally save the command to cmd_file file, and add extra_env
environment variables to the command generated. environment variables to the command generated.
If cmd contains at least one common.Newline, newlines are only added on common.Newline.
Otherwise, newlines are added automatically after every word.
''' '''
global dry_run global dry_run
if type(cmd) is str: if type(cmd) is str:
@@ -513,14 +540,14 @@ def raw_to_qcow2(prebuilt=False, reverse=False):
infile = outfile infile = outfile
outfile = tmp outfile = tmp
this_module.run_cmd([ this_module.run_cmd([
qemu_img_executable, qemu_img_executable, this_module.Newline,
# Prevent qemu-img from generating trace files like QEMU. Disgusting. # Prevent qemu-img from generating trace files like QEMU. Disgusting.
'-T', 'pr_manager_run,file=/dev/null', '-T', 'pr_manager_run,file=/dev/null', this_module.Newline,
'convert', 'convert', this_module.Newline,
'-f', infmt, '-f', infmt, this_module.Newline,
'-O', outfmt, '-O', outfmt, this_module.Newline,
infile, infile, this_module.Newline,
outfile, outfile, this_module.Newline,
]) ])
def raise_no_x86(arch): def raise_no_x86(arch):
@@ -563,7 +590,7 @@ def run_cmd(
Wait until the command finishes execution. Wait until the command finishes execution.
:param cmd: command to run :param cmd: command to run. common.Newline entries are magic get skipped.
:type cmd: List[str] :type cmd: List[str]
:param cmd_file: if not None, write the command to be run to that file :param cmd_file: if not None, write the command to be run to that file
@@ -625,6 +652,7 @@ def run_cmd(
#sigpipe_old = signal.getsignal(signal.SIGPIPE) #sigpipe_old = signal.getsignal(signal.SIGPIPE)
#signal.signal(signal.SIGPIPE, signal.SIG_DFL) #signal.signal(signal.SIGPIPE, signal.SIG_DFL)
cmd = [x for x in cmd if x != this_module.Newline]
if not dry_run and not this_module.dry_run: if not dry_run and not this_module.dry_run:
# https://stackoverflow.com/questions/15535240/python-popen-write-to-stdout-and-log-file-simultaneously/52090802#52090802 # https://stackoverflow.com/questions/15535240/python-popen-write-to-stdout-and-log-file-simultaneously/52090802#52090802
with subprocess.Popen(cmd, stdout=stdout, stderr=stderr, env=env, **kwargs) as proc: with subprocess.Popen(cmd, stdout=stdout, stderr=stderr, env=env, **kwargs) as proc:
@@ -886,6 +914,14 @@ def setup(parser):
def setup_dry_run_arguments(args): def setup_dry_run_arguments(args):
this_module.dry_run = args.dry_run this_module.dry_run = args.dry_run
def shlex_split(string):
'''
shlex_split, but also add Newline after every word.
Not perfect since it does not group arguments, but I don't see a solution.
'''
return this_module.add_newlines(shlex.split(string))
def resolve_executable(in_path, magic_in_dir, magic_out_dir, out_ext): def resolve_executable(in_path, magic_in_dir, magic_out_dir, out_ext):
if os.path.isabs(in_path): if os.path.isabs(in_path):
return in_path return in_path

View File

@@ -1,6 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import subprocess
import sys import sys
import common import common
@@ -10,4 +9,8 @@ parser = common.get_argparse(
argparse_args={'description':'Connect a terminal to a running gem5 instance'} argparse_args={'description':'Connect a terminal to a running gem5 instance'}
) )
args = common.setup(parser) args = common.setup(parser)
sys.exit(common.run_cmd([str(common.gem5_m5term), 'localhost', str(common.gem5_telnet_port)])) sys.exit(common.run_cmd([
common.gem5_m5term, common.Newline,
'localhost', common.Newline,
str(common.gem5_telnet_port), common.Newline,
]))

View File

@@ -7,13 +7,12 @@ import sys
import common import common
def main(): def main():
cmd = [
os.path.join(common.qemu_src_dir, 'scripts/simpletrace.py'),
os.path.join(common.qemu_build_dir, 'trace-events-all'),
os.path.join(common.qemu_trace_file),
]
return common.run_cmd( return common.run_cmd(
cmd, [
os.path.join(common.qemu_src_dir, 'scripts/simpletrace.py'), common.Newline,
os.path.join(common.qemu_build_dir, 'trace-events-all'), common.Newline,
os.path.join(common.qemu_trace_file), common.Newline,
],
cmd_file=os.path.join(common.run_dir, 'qemu-trace2txt'), cmd_file=os.path.join(common.run_dir, 'qemu-trace2txt'),
out_file=common.qemu_trace_txt_file, out_file=common.qemu_trace_txt_file,
show_stdout=False, show_stdout=False,

131
run
View File

@@ -2,7 +2,6 @@
import os import os
import re import re
import shlex
import shutil import shutil
import subprocess import subprocess
import sys import sys
@@ -55,18 +54,17 @@ def main(args, extra_args=None):
extra_emulator_args = [] extra_emulator_args = []
extra_qemu_args = [] extra_qemu_args = []
if args.debug_vm is not None: if args.debug_vm is not None:
print(args.debug_vm) debug_vm = ['gdb', common.Newline, '-q', common.Newline] + common.shlex_split(args.debug_vm) + ['--args', common.Newline]
debug_vm = ['gdb', '-q'] + shlex.split(args.debug_vm) + ['--args']
else: else:
debug_vm = [] debug_vm = []
if args.wait_gdb: if args.wait_gdb:
extra_qemu_args.append('-S') extra_qemu_args.extend(['-S', common.Newline])
if args.eval_busybox is not None: if args.eval_busybox is not None:
kernel_cli_after_dash += ' lkmc_eval_base64="{}"'.format(common.base64_encode(args.eval_busybox)) kernel_cli_after_dash += ' lkmc_eval_base64="{}"'.format(common.base64_encode(args.eval_busybox))
if args.kernel_cli_after_dash is not None: if args.kernel_cli_after_dash is not None:
kernel_cli_after_dash += ' {}'.format(args.kernel_cli_after_dash) kernel_cli_after_dash += ' {}'.format(args.kernel_cli_after_dash)
if args.vnc: if args.vnc:
vnc = ['-vnc', ':0'] vnc = ['-vnc', ':0', common.Newline]
else: else:
vnc = [] vnc = []
if args.initrd or args.initramfs: if args.initrd or args.initramfs:
@@ -81,7 +79,7 @@ def main(args, extra_args=None):
kernel_cli += ' {}=/eval_base64.sh'.format(initarg) kernel_cli += ' {}=/eval_base64.sh'.format(initarg)
kernel_cli_after_dash += ' lkmc_eval="{}"'.format(common.base64_encode(args.eval)) kernel_cli_after_dash += ' lkmc_eval="{}"'.format(common.base64_encode(args.eval))
if not args.graphic: if not args.graphic:
extra_qemu_args.append('-nographic') extra_qemu_args.extend(['-nographic', common.Newline])
console = None console = None
console_type = None console_type = None
console_count = 0 console_count = 0
@@ -144,24 +142,27 @@ def main(args, extra_args=None):
os.makedirs(os.path.dirname(common.gem5_readfile), exist_ok=True) os.makedirs(os.path.dirname(common.gem5_readfile), exist_ok=True)
common.write_string_to_file(common.gem5_readfile, args.gem5_readfile) common.write_string_to_file(common.gem5_readfile, args.gem5_readfile)
memory = '{}B'.format(args.memory) memory = '{}B'.format(args.memory)
gem5_exe_args = shlex.split(args.gem5_exe_args) gem5_exe_args = common.shlex_split(args.gem5_exe_args)
if do_trace: if do_trace:
gem5_exe_args.append('--debug-flags={}'.format(trace_type)) gem5_exe_args.extend(['--debug-flags={}'.format(trace_type), common.Newline])
extra_env['M5_PATH'] = common.gem5_system_dir extra_env['M5_PATH'] = common.gem5_system_dir
# https://stackoverflow.com/questions/52312070/how-to-modify-a-file-under-src-python-and-run-it-without-rebuilding-in-gem5/52312071#52312071 # https://stackoverflow.com/questions/52312070/how-to-modify-a-file-under-src-python-and-run-it-without-rebuilding-in-gem5/52312071#52312071
extra_env['M5_OVERRIDE_PY_SOURCE'] = 'true' extra_env['M5_OVERRIDE_PY_SOURCE'] = 'true'
cmd.extend( cmd.extend(
[ [
common.executable, common.executable, common.Newline,
'--debug-file=trace.txt', '--debug-file=trace.txt', common.Newline
] + ] +
gem5_exe_args + gem5_exe_args +
[ [
'-d', common.m5out_dir '-d', common.m5out_dir, common.Newline
] ]
) )
if args.userland is not None: if args.userland is not None:
cmd.extend([common.gem5_se_file, '-c', common.resolve_userland(args.userland)]) cmd.extend([
common.gem5_se_file, common.Newline,
'-c', common.resolve_userland(args.userland), common.Newline,
])
else: else:
if args.gem5_script == 'fs': if args.gem5_script == 'fs':
# TODO port # TODO port
@@ -170,67 +171,67 @@ def main(args, extra_args=None):
cpt_dir = cpt_dirs[-args.gem5_restore] cpt_dir = cpt_dirs[-args.gem5_restore]
extra_emulator_args.extend(['-r', str(sorted(cpt_dirs).index(cpt_dir) + 1)]) extra_emulator_args.extend(['-r', str(sorted(cpt_dirs).index(cpt_dir) + 1)])
cmd.extend([ cmd.extend([
common.gem5_fs_file, common.gem5_fs_file, common.Newline,
'--disk-image', common.disk_image, '--disk-image', common.disk_image, common.Newline,
'--kernel', common.image, '--kernel', common.image, common.Newline,
'--mem-size', memory, '--mem-size', memory, common.Newline,
'--num-cpus', str(args.cpus), '--num-cpus', str(args.cpus), common.Newline,
'--script', common.gem5_readfile, '--script', common.gem5_readfile, common.Newline,
]) ])
if args.arch == 'x86_64': if args.arch == 'x86_64':
if args.kvm: if args.kvm:
cmd.extend(['--cpu-type', 'X86KvmCPU']) cmd.extend(['--cpu-type', 'X86KvmCPU', common.Newline])
cmd.extend(['--command-line', 'earlyprintk={} lpj=7999923 root=/dev/sda {}'.format(console, kernel_cli)]) cmd.extend(['--command-line', 'earlyprintk={} lpj=7999923 root=/dev/sda {}'.format(console, kernel_cli), common.Newline])
elif common.is_arm: elif common.is_arm:
# TODO why is it mandatory to pass mem= here? Not true for QEMU. # TODO why is it mandatory to pass mem= here? Not true for QEMU.
# Anything smaller than physical blows up as expected, but why can't it auto-detect the right value? # Anything smaller than physical blows up as expected, but why can't it auto-detect the right value?
cmd.extend([ cmd.extend([
'--command-line', 'earlyprintk=pl011,0x1c090000 lpj=19988480 rw loglevel=8 mem={} root=/dev/sda {}'.format(memory, kernel_cli), '--command-line', 'earlyprintk=pl011,0x1c090000 lpj=19988480 rw loglevel=8 mem={} root=/dev/sda {}'.format(memory, kernel_cli), common.Newline,
'--dtb-filename', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv{}_gem5_v1_{}cpu.dtb'.format(common.armv, args.cpus)), '--dtb-filename', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv{}_gem5_v1_{}cpu.dtb'.format(common.armv, args.cpus)), common.Newline,
'--machine-type', common.machine, '--machine-type', common.machine, common.Newline,
'--param', 'system.panic_on_panic = True', '--param', 'system.panic_on_panic = True', common.Newline,
]) ])
if not args.baremetal is None: if not args.baremetal is None:
cmd.append('--bare-metal') cmd.extend(['--bare-metal', common.Newline])
if args.arch == 'aarch64': if args.arch == 'aarch64':
# https://stackoverflow.com/questions/43682311/uart-communication-in-gem5-with-arm-bare-metal/50983650#50983650 # https://stackoverflow.com/questions/43682311/uart-communication-in-gem5-with-arm-bare-metal/50983650#50983650
cmd.extend(['--param', 'system.highest_el_is_64 = True']) cmd.extend(['--param', 'system.highest_el_is_64 = True', common.Newline])
cmd.extend(['--param', 'system.auto_reset_addr_64 = True']) cmd.extend(['--param', 'system.auto_reset_addr_64 = True', common.Newline])
elif args.gem5_script == 'biglittle': elif args.gem5_script == 'biglittle':
if args.gem5_restore is not None: if args.gem5_restore is not None:
cpt_dir = common.gem_list_checkpoint_dirs()[-args.gem5_restore] cpt_dir = common.gem_list_checkpoint_dirs()[-args.gem5_restore]
extra_emulator_args.extend(['--restore-from', os.path.join(common.m5out_dir, cpt_dir)]) extra_emulator_args.extend(['--restore-from', os.path.join(common.m5out_dir, cpt_dir)])
cmd.extend([ cmd.extend([
os.path.join(common.gem5_src_dir, 'configs', 'example', 'arm', 'fs_bigLITTLE.py'), os.path.join(common.gem5_src_dir, 'configs', 'example', 'arm', 'fs_bigLITTLE.py'), common.Newline,
'--big-cpus', '2', '--big-cpus', '2', common.Newline,
'--cpu-type', 'atomic', '--cpu-type', 'atomic', common.Newline,
'--disk', common.disk_image, '--disk', common.disk_image, common.Newline,
'--dtb', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv8_gem5_v1_big_little_2_2.dtb'), '--dtb', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv8_gem5_v1_big_little_2_2.dtb'), common.Newline,
'--kernel', common.image, '--kernel', common.image, common.Newline,
'--little-cpus', '2' '--little-cpus', '2', common.Newline,
]) ])
if args.wait_gdb: if args.wait_gdb:
# https://stackoverflow.com/questions/49296092/how-to-make-gem5-wait-for-gdb-to-connect-to-reliably-break-at-start-kernel-of-th # https://stackoverflow.com/questions/49296092/how-to-make-gem5-wait-for-gdb-to-connect-to-reliably-break-at-start-kernel-of-th
cmd.extend(['--param', 'system.cpu[0].wait_for_remote_gdb = True']) cmd.extend(['--param', 'system.cpu[0].wait_for_remote_gdb = True', common.Newline])
else: else:
qemu_user_and_system_options = [ qemu_user_and_system_options = [
'-trace', 'enable={},file={}'.format(trace_type, common.qemu_trace_file), '-trace', 'enable={},file={}'.format(trace_type, common.qemu_trace_file), common.Newline,
] ]
if args.userland is not None: if args.userland is not None:
if args.wait_gdb: if args.wait_gdb:
debug_args = ['-g', str(common.gdb_port)] debug_args = ['-g', str(common.gdb_port), common.Newline]
else: else:
debug_args = [] debug_args = []
cmd.extend( cmd.extend(
[ [
os.path.join(common.qemu_build_dir, '{}-linux-user'.format(args.arch), 'qemu-{}'.format(args.arch)), os.path.join(common.qemu_build_dir, '{}-linux-user'.format(args.arch), 'qemu-{}'.format(args.arch)), common.Newline,
'-L', common.target_dir, '-L', common.target_dir, common.Newline
] + ] +
qemu_user_and_system_options + qemu_user_and_system_options +
shlex.split(args.userland_before) + common.shlex_split(args.userland_before) +
debug_args + debug_args +
[ [
common.resolve_userland(args.userland) common.resolve_userland(args.userland), common.Newline
] ]
) )
else: else:
@@ -250,10 +251,10 @@ def main(args, extra_args=None):
if args.debug_vm: if args.debug_vm:
serial_monitor = [] serial_monitor = []
else: else:
serial_monitor = ['-serial', 'mon:stdio'] serial_monitor = ['-serial', 'mon:stdio', common.Newline]
if args.kvm: if args.kvm:
extra_emulator_args.append('-enable-kvm') extra_emulator_args.extend(['-enable-kvm', common.Newline])
extra_emulator_args.extend(['-serial', 'tcp::{},server,nowait'.format(common.extra_serial_port)]) extra_emulator_args.extend(['-serial', 'tcp::{},server,nowait'.format(common.extra_serial_port), common.Newline])
virtfs_data = [ virtfs_data = [
(common.p9_dir, 'host_data'), (common.p9_dir, 'host_data'),
(common.out_dir, 'host_out'), (common.out_dir, 'host_out'),
@@ -266,19 +267,20 @@ def main(args, extra_args=None):
virtfs_cmd.extend([ virtfs_cmd.extend([
'-virtfs', '-virtfs',
'local,path={virtfs_dir},mount_tag={virtfs_tag},security_model=mapped,id={virtfs_tag}' \ 'local,path={virtfs_dir},mount_tag={virtfs_tag},security_model=mapped,id={virtfs_tag}' \
.format(virtfs_dir=virtfs_dir, virtfs_tag=virtfs_tag .format(virtfs_dir=virtfs_dir, virtfs_tag=virtfs_tag),
)]) common.Newline,
])
cmd.extend( cmd.extend(
[ [
qemu_executable, qemu_executable, common.Newline,
'-device', 'rtl8139,netdev=net0', '-device', 'rtl8139,netdev=net0', common.Newline,
'-gdb', 'tcp::{}'.format(common.gdb_port), '-gdb', 'tcp::{}'.format(common.gdb_port), common.Newline,
'-kernel', common.image, '-kernel', common.image, common.Newline,
'-m', args.memory, '-m', args.memory, common.Newline,
'-monitor', 'telnet::{},server,nowait'.format(common.qemu_monitor_port), '-monitor', 'telnet::{},server,nowait'.format(common.qemu_monitor_port), common.Newline,
'-netdev', 'user,hostfwd=tcp::{}-:{},hostfwd=tcp::{}-:22,id=net0'.format(common.qemu_hostfwd_generic_port, common.qemu_hostfwd_generic_port, common.qemu_hostfwd_ssh_port), '-netdev', 'user,hostfwd=tcp::{}-:{},hostfwd=tcp::{}-:22,id=net0'.format(common.qemu_hostfwd_generic_port, common.qemu_hostfwd_generic_port, common.qemu_hostfwd_ssh_port), common.Newline,
'-no-reboot', '-no-reboot', common.Newline,
'-smp', str(args.cpus), '-smp', str(args.cpus), common.Newline,
] + ] +
virtfs_cmd + virtfs_cmd +
qemu_user_and_system_options + qemu_user_and_system_options +
@@ -309,12 +311,13 @@ def main(args, extra_args=None):
common.raw_to_qcow2(prebuilt=args.prebuilt) common.raw_to_qcow2(prebuilt=args.prebuilt)
extra_emulator_args.extend([ extra_emulator_args.extend([
'-drive', '-drive',
'file={},format=qcow2,if={}{}{}'.format(common.disk_image, driveif, snapshot, rrid) 'file={},format=qcow2,if={}{}{}'.format(common.disk_image, driveif, snapshot, rrid),
common.Newline,
]) ])
if rr: if rr:
extra_emulator_args.extend([ extra_emulator_args.extend([
'-drive', 'driver=blkreplay,if=none,image=img-direct,id=img-blkreplay', '-drive', 'driver=blkreplay,if=none,image=img-direct,id=img-blkreplay', common.Newline,
'-device', 'ide-hd,drive=img-blkreplay' '-device', 'ide-hd,drive=img-blkreplay', common.Newline,
]) ])
if rr: if rr:
extra_emulator_args.extend([ extra_emulator_args.extend([
@@ -325,13 +328,13 @@ def main(args, extra_args=None):
else: else:
virtio_gpu_pci = ['-device', 'virtio-gpu-pci'] virtio_gpu_pci = ['-device', 'virtio-gpu-pci']
if args.arch == 'x86_64': if args.arch == 'x86_64':
append = ['-append', '{} nopat {}'.format(root, kernel_cli)] append = ['-append', '{} nopat {}'.format(root, kernel_cli), common.Newline]
cmd.extend([ cmd.extend([
'-M', common.machine, '-M', common.machine, common.Newline,
'-device', 'edu', '-device', 'edu', common.Newline,
]) ])
elif common.is_arm: elif common.is_arm:
extra_emulator_args.append('-semihosting') extra_emulator_args.extend(['-semihosting', common.Newline])
if args.arch == 'arm': if args.arch == 'arm':
cpu = 'cortex-a15' cpu = 'cortex-a15'
else: else:
@@ -341,8 +344,8 @@ def main(args, extra_args=None):
[ [
# highmem=off needed since v3.0.0 due to: # highmem=off needed since v3.0.0 due to:
# http://lists.nongnu.org/archive/html/qemu-discuss/2018-08/msg00034.html # http://lists.nongnu.org/archive/html/qemu-discuss/2018-08/msg00034.html
'-M', '{},highmem=off'.format(common.machine), '-M', '{},highmem=off'.format(common.machine), common.Newline,
'-cpu', cpu, '-cpu', cpu, common.Newline,
] + ] +
virtio_gpu_pci virtio_gpu_pci
) )

21
run-gdb
View File

@@ -1,7 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os import os
import shlex
import sys import sys
import signal import signal
import subprocess import subprocess
@@ -33,10 +32,10 @@ def main(args, extra_args=None):
''' '''
global defaults global defaults
args = common.resolve_args(defaults, args, extra_args) args = common.resolve_args(defaults, args, extra_args)
after = shlex.split(args.after) after = common.shlex_split(args.after)
before = shlex.split(args.before) before = common.shlex_split(args.before)
if args.break_at is not None: if args.break_at is not None:
break_at = ['-ex', 'break {}'.format(args.break_at)] break_at = ['-ex', 'break {}'.format(args.break_at), common.Newline]
else: else:
break_at = [] break_at = []
linux_full_system = (args.baremetal is None and args.userland is None) linux_full_system = (args.baremetal is None and args.userland is None)
@@ -51,12 +50,12 @@ def main(args, extra_args=None):
else: else:
allowed_toolchains = ['buildroot', 'crosstool-ng', 'host'] allowed_toolchains = ['buildroot', 'crosstool-ng', 'host']
cmd = ( cmd = (
[common.get_toolchain_tool('gdb', allowed_toolchains=allowed_toolchains)] + [common.get_toolchain_tool('gdb', allowed_toolchains=allowed_toolchains), common.Newline] +
before + before +
['-q'] ['-q', common.Newline]
) )
if linux_full_system: if linux_full_system:
cmd.extend(['-ex', 'add-auto-load-safe-path {}'.format(common.linux_build_dir)]) cmd.extend(['-ex', 'add-auto-load-safe-path {}'.format(common.linux_build_dir), common.Newline])
if args.sim: if args.sim:
target = 'sim' target = 'sim'
else: else:
@@ -66,8 +65,8 @@ def main(args, extra_args=None):
port = common.gdb_port port = common.gdb_port
target = 'remote localhost:{}'.format(port) target = 'remote localhost:{}'.format(port)
cmd.extend([ cmd.extend([
'-ex', 'file {}'.format(image), '-ex', 'file {}'.format(image), common.Newline,
'-ex', 'target {}'.format(target), '-ex', 'target {}'.format(target), common.Newline,
]) ])
if not args.kgdb: if not args.kgdb:
cmd.extend(break_at) cmd.extend(break_at)
@@ -91,9 +90,9 @@ def main(args, extra_args=None):
# #
# The lx-symbols commands gets loaded through the file vmlinux-gdb.py # The lx-symbols commands gets loaded through the file vmlinux-gdb.py
# which gets put on the kernel build root when python debugging scripts are enabled. # which gets put on the kernel build root when python debugging scripts are enabled.
cmd.extend(['-ex', 'continue']) cmd.extend(['-ex', 'continue', common.Newline])
if not args.no_lxsymbols and linux_full_system: if not args.no_lxsymbols and linux_full_system:
cmd.extend(['-ex', 'lx-symbols {}'.format(common.kernel_modules_build_subdir)]) cmd.extend(['-ex', 'lx-symbols {}'.format(common.kernel_modules_build_subdir), common.Newline])
cmd.extend(after) cmd.extend(after)
# I would rather have cwd be out_rootfs_overlay_dir, # I would rather have cwd be out_rootfs_overlay_dir,
# but then lx-symbols cannot fine the vmlinux and fails with: # but then lx-symbols cannot fine the vmlinux and fails with:

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os import os
import subprocess
import sys import sys
import common import common
@@ -45,6 +44,7 @@ if args.dry:
print(tool) print(tool)
else: else:
sys.exit(common.run_cmd( sys.exit(common.run_cmd(
[tool] + args.extra_args, [tool, common.Newline]
+ common.add_newlines(args.extra_args),
cmd_file=os.path.join(common.run_dir, 'run-toolchain.sh'), cmd_file=os.path.join(common.run_dir, 'run-toolchain.sh'),
)) ))