diff --git a/build-userland b/build-userland index 13bf4fc..cf005bd 100755 --- a/build-userland +++ b/build-userland @@ -167,6 +167,7 @@ Default: build all examples that have their package dependencies met, e.g.: else: targets = [self.env['userland_source_dir']] for target in targets: + target = self.resolve_userland_source(target) for path, in_dirnames, in_filenames in self.sh.walk(target): in_dirnames.sort() path_abs = os.path.abspath(path) diff --git a/common.py b/common.py index 93893cb..38c41e5 100644 --- a/common.py +++ b/common.py @@ -95,6 +95,11 @@ consts['github_repo_id'] = 'cirosantilli/linux-kernel-module-cheat' consts['asm_ext'] = '.S' consts['c_ext'] = '.c' consts['cxx_ext'] = '.cpp' +consts['userland_in_exts'] = [ + consts['asm_ext'], + consts['c_ext'], + consts['cxx_ext'], +] consts['header_ext'] = '.h' consts['kernel_module_ext'] = '.ko' consts['obj_ext'] = '.o' @@ -1102,6 +1107,50 @@ lunch aosp_{}-eng argcopy.__dict__ = dict(list(defaults.items()) + list(argcopy.__dict__.items()) + list(extra_args.items())) return argcopy + def resolve_source(self, in_path, magic_in_dir, in_exts): + ''' + Convert a path-like string to a source file to the full source path, + e.g. all follogin work and to do the same: + + - hello + - hello. + - hello.c + - userland/hello + - userland/hello. + - userland/hello.c + - /full/path/to/userland/hello + - /full/path/to/userland/hello. + - /full/path/to/userland/hello.c + + Also works on directories: + + - arch + - userland/arch + - /full/path/to/userland/arch + ''' + if os.path.isabs(in_path): + return in_path + else: + paths = [ + os.path.join(magic_in_dir, in_path), + os.path.join( + magic_in_dir, + os.path.relpath(in_path, magic_in_dir), + ) + ] + for path in paths: + name, ext = os.path.splitext(path) + if len(ext) > 1: + try_exts = [ext] + else: + try_exts = in_exts + [''] + for in_ext in try_exts: + path = name + in_ext + if os.path.exists(path): + return path + if not self.env['dry_run']: + raise Exception('Source file not found for input: ' + in_path) + def resolve_executable(self, in_path, magic_in_dir, magic_out_dir, out_ext): if os.path.isabs(in_path): return in_path @@ -1113,14 +1162,18 @@ lunch aosp_{}-eng os.path.relpath(in_path, magic_in_dir), ) ] - paths[:] = [os.path.splitext(path)[0] + out_ext for path in paths] for path in paths: + path = os.path.splitext(path)[0] + out_ext if os.path.exists(path): return path if not self.env['dry_run']: raise Exception('Executable file not found. Tried:\n' + '\n'.join(paths)) - def resolve_userland(self, path): + def resolve_userland_executable(self, path): + ''' + Convert an userland source path-like string to an + absolute userland build output path. + ''' return self.resolve_executable( path, self.env['userland_source_dir'], @@ -1128,6 +1181,13 @@ lunch aosp_{}-eng self.env['userland_build_ext'], ) + def resolve_userland_source(self, path): + return self.resolve_source( + path, + self.env['userland_source_dir'], + self.env['userland_in_exts'] + ) + def setup(self): ''' Similar to timed_main, but gets run only once for all --arch and --emulator, diff --git a/run b/run index 897ef6e..eea3dad 100755 --- a/run +++ b/run @@ -350,7 +350,7 @@ Run QEMU with VNC instead of the default SDL. Connect to it with: if self.env['userland'] is not None: cmd.extend([ self.env['gem5_se_file'], LF, - '--cmd', self.resolve_userland(self.env['userland']), LF, + '--cmd', self.resolve_userland_executable(self.env['userland']), LF, ]) if self.env['userland_args'] is not None: cmd.extend(['--options', self.env['userland_args'], LF]) @@ -607,7 +607,7 @@ Run QEMU with VNC instead of the default SDL. Connect to it with: cmd.extend(self.env['extra_emulator_args']) if self.env['emulator'] == 'qemu' and self.env['userland']: # The program and arguments must come at the every end of the CLI. - cmd.extend([self.resolve_userland(self.env['userland']), LF]) + cmd.extend([self.resolve_userland_executable(self.env['userland']), LF]) if self.env['userland_args'] is not None: cmd.extend(self.sh.shlex_split(self.env['userland_args'])) if debug_vm or self.env['terminal']: diff --git a/run-gdb b/run-gdb index 0ce6fa0..afbaa71 100755 --- a/run-gdb +++ b/run-gdb @@ -146,7 +146,7 @@ See: https://github.com/cirosantilli/linux-kernel-module-cheat#gdb-builtin-cpu-s break_at = [] linux_full_system = (self.env['baremetal'] is None and self.env['userland'] is None) if self.env['userland']: - image = self.resolve_userland(self.env['userland']) + image = self.resolve_userland_executable(self.env['userland']) elif self.env['baremetal']: image = self.env['image'] test_script_path = os.path.splitext(self.env['source_path'])[0] + '.py' diff --git a/run-gdb-user b/run-gdb-user index 14c5bdf..0e2d406 100755 --- a/run-gdb-user +++ b/run-gdb-user @@ -24,7 +24,7 @@ parser.add_argument( nargs='?' ) args = self.setup(parser) -executable = self.resolve_userland(kwargs['executable']) +executable = self.resolve_userland_executable(kwargs['executable']) addr = self.get_elf_entry(os.path.join(kwargs['buildroot_build_build_dir'], executable)) extra_args = {} extra_args['before'] = '-ex \"add-symbol-file {} {}\"'.format(executable, hex(addr)) diff --git a/run-gdbserver b/run-gdbserver index f67002b..fbb2a1e 100755 --- a/run-gdbserver +++ b/run-gdbserver @@ -25,5 +25,5 @@ sys.exit(subprocess.Popen([ '-ex', 'target remote localhost:{}'.format(kwargs['qemu_hostfwd_generic_port']), '-ex', 'tbreak {}'.format(kwargs['break_at']), '-ex', 'continue', - os.path.join(kwargs['buildroot_build_build_dir'], self.resolve_userland(kwargs['executable'])), + os.path.join(kwargs['buildroot_build_build_dir'], self.resolve_userland_executable(kwargs['executable'])), ]).wait())