diff --git a/sbysrc/sby.py b/sbysrc/sby.py index 843fabd..0e966e7 100644 --- a/sbysrc/sby.py +++ b/sbysrc/sby.py @@ -54,6 +54,7 @@ dump_taskinfo = args.dump_taskinfo dump_files = args.dump_files reusedir = False setupmode = args.setupmode +linkmode = args.linkmode autotune = args.autotune autotune_config = args.autotune_config sequential = args.sequential @@ -65,6 +66,10 @@ status_live_csv = args.livecsv status_show_csv = args.statuscsv status_latest = args.status_latest +if autotune and linkmode: + print("ERROR: --link flag currently not available with --autotune") + sys.exit(1) + if status_show or status_reset or status_show_csv: target = workdir_prefix or workdir or sbyfile if target is None: @@ -515,7 +520,7 @@ def start_task(taskloop, taskname): task.exit_callback = exit_callback if not autotune: - task.setup_procs(setupmode) + task.setup_procs(setupmode, linkmode) task.task_local_abort = not throw_err return task diff --git a/sbysrc/sby_autotune.py b/sbysrc/sby_autotune.py index b861890..aa40134 100644 --- a/sbysrc/sby_autotune.py +++ b/sbysrc/sby_autotune.py @@ -649,7 +649,7 @@ class SbyAutotuneTask(SbyTask): def engine_list(self): return [(self.candidate.engine_idx, self.candidate.engine)] - def copy_src(self): + def copy_src(self, _): pass def model(self, model_name): diff --git a/sbysrc/sby_cmdline.py b/sbysrc/sby_cmdline.py index f99c439..c94d9c2 100644 --- a/sbysrc/sby_cmdline.py +++ b/sbysrc/sby_cmdline.py @@ -72,6 +72,8 @@ def parser_func(release_version='unknown SBY version'): help="print the list of source files") parser.add_argument("--setup", action="store_true", dest="setupmode", help="set up the working directory and exit") + parser.add_argument("--link", action="store_true", dest="linkmode", + help="make symbolic links to source files instead of copying them") parser.add_argument("--status", action="store_true", dest="status", help="summarize the contents of the status database") diff --git a/sbysrc/sby_core.py b/sbysrc/sby_core.py index c9a3ff4..7d37f93 100644 --- a/sbysrc/sby_core.py +++ b/sbysrc/sby_core.py @@ -986,7 +986,7 @@ class SbyTask(SbyConfig): if not os.path.isdir(path): os.makedirs(path) - def copy_src(self): + def copy_src(self, linkmode=False): self.makedirs(self.workdir + "/src") for dstfile, lines in self.verbatim_files.items(): @@ -1008,8 +1008,15 @@ class SbyTask(SbyConfig): if basedir != "" and not os.path.exists(basedir): os.makedirs(basedir) - self.log(f"Copy '{os.path.abspath(srcfile)}' to '{os.path.abspath(dstfile)}'.") - if os.path.isdir(srcfile): + if linkmode: + verb = "Link" + else: + verb = "Copy" + self.log(f"{verb} '{os.path.abspath(srcfile)}' to '{os.path.abspath(dstfile)}'.") + + if linkmode: + os.symlink(os.path.relpath(srcfile, basedir), dstfile) + elif os.path.isdir(srcfile): copytree(srcfile, dstfile, dirs_exist_ok=True) else: copyfile(srcfile, dstfile) @@ -1366,7 +1373,7 @@ class SbyTask(SbyConfig): self.status_db = SbyStatusDb(status_path, self, live_csv=self.live_csv) - def setup_procs(self, setupmode): + def setup_procs(self, setupmode, linkmode=False): self.handle_non_engine_options() if self.opt_smtc is not None: for engine_idx, engine in self.engine_list(): @@ -1387,7 +1394,7 @@ class SbyTask(SbyConfig): if self.reusedir: rmtree(f"{self.workdir}/model", ignore_errors=True) else: - self.copy_src() + self.copy_src(linkmode) if setupmode: self.retcode = 0 diff --git a/tests/links/Makefile b/tests/links/Makefile new file mode 100644 index 0000000..758a7f7 --- /dev/null +++ b/tests/links/Makefile @@ -0,0 +1,2 @@ +SUBDIR=links +include ../make/subdir.mk diff --git a/tests/links/dir/script.ys b/tests/links/dir/script.ys new file mode 100644 index 0000000..4daa0c1 --- /dev/null +++ b/tests/links/dir/script.ys @@ -0,0 +1,3 @@ +read -sv picorv32.v +read -sv prv32fmcmp.v +prep -top prv32fmcmp diff --git a/tests/links/prv32fmcmp.v b/tests/links/prv32fmcmp.v new file mode 120000 index 0000000..6c064ca --- /dev/null +++ b/tests/links/prv32fmcmp.v @@ -0,0 +1 @@ +../unsorted/prv32fmcmp.v \ No newline at end of file diff --git a/tests/links/symlink.py b/tests/links/symlink.py new file mode 100644 index 0000000..a6a06d5 --- /dev/null +++ b/tests/links/symlink.py @@ -0,0 +1,18 @@ +import os +from pathlib import Path +import sys + +def main(): + workdir, task = sys.argv[1:] + src = Path(workdir) / "src" + for srcfile in src.iterdir(): + if srcfile.name == "heredoc": + assert(not srcfile.is_symlink()) + with open(srcfile, "r") as f: + local_contents = f.readline() + assert(local_contents.strip() == 'log foo') + else: + assert(srcfile.is_symlink() == (task == "link")) + +if __name__ == "__main__": + main() diff --git a/tests/links/symlink.sby b/tests/links/symlink.sby new file mode 100644 index 0000000..52fa881 --- /dev/null +++ b/tests/links/symlink.sby @@ -0,0 +1,21 @@ +[tasks] +link +copy + +[options] +mode prep + +[engines] +btor btormc + +[script] +read -noverific +script dir/script.ys + +[files] +../../docs/examples/demos/picorv32.v +prv32fmcmp.v +dir + +[file heredoc] +log foo diff --git a/tests/links/symlink.sh b/tests/links/symlink.sh new file mode 100644 index 0000000..e919293 --- /dev/null +++ b/tests/links/symlink.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +if [[ $TASK == link ]]; then + flags="--setup --link" +else + flags="--setup" +fi +python3 $SBY_MAIN -f $SBY_FILE $TASK $flags +python3 ${SBY_FILE%.sby}.py $WORKDIR $TASK diff --git a/tests/make/collect_tests.py b/tests/make/collect_tests.py index acfb799..1f9b2c9 100644 --- a/tests/make/collect_tests.py +++ b/tests/make/collect_tests.py @@ -52,6 +52,8 @@ def collect(path): continue tests.append(entry) for entry in path.glob("*"): + if entry.with_suffix(".sby").exists(): + continue if entry.is_dir(): collect(entry)