mirror of
				https://github.com/YosysHQ/sby.git
				synced 2025-10-31 04:52:30 +00:00 
			
		
		
		
	Merge pull request #336 from YosysHQ/krys/dir_basenames
Output directory handling improvements
This commit is contained in:
		
						commit
						b4348974c1
					
				
					 5 changed files with 74 additions and 37 deletions
				
			
		|  | @ -45,12 +45,8 @@ signal.signal(signal.SIGINT, force_shutdown) | ||||||
| signal.signal(signal.SIGTERM, force_shutdown) | signal.signal(signal.SIGTERM, force_shutdown) | ||||||
| 
 | 
 | ||||||
| def process_filename(filename): | def process_filename(filename): | ||||||
|     if filename.startswith("~/"): |  | ||||||
|         filename = os.environ['HOME'] + filename[1:] |  | ||||||
| 
 |  | ||||||
|     filename = os.path.expandvars(filename) |     filename = os.path.expandvars(filename) | ||||||
| 
 |     return Path(filename).expanduser() | ||||||
|     return filename |  | ||||||
| 
 | 
 | ||||||
| def dress_message(workdir, logmessage): | def dress_message(workdir, logmessage): | ||||||
|     tm = localtime() |     tm = localtime() | ||||||
|  | @ -579,7 +575,7 @@ class SbyConfig: | ||||||
|                     self.error(f"sby file syntax error: '[files]' section entry expects up to 2 arguments, {len(entries)} specified") |                     self.error(f"sby file syntax error: '[files]' section entry expects up to 2 arguments, {len(entries)} specified") | ||||||
| 
 | 
 | ||||||
|                 if len(entries) == 1: |                 if len(entries) == 1: | ||||||
|                     self.files[os.path.basename(entries[0])] = entries[0] |                     self.files[Path(entries[0]).name] = entries[0] | ||||||
|                 elif len(entries) == 2: |                 elif len(entries) == 2: | ||||||
|                     self.files[entries[0]] = entries[1] |                     self.files[entries[0]] = entries[1] | ||||||
| 
 | 
 | ||||||
|  | @ -1033,42 +1029,44 @@ class SbyTask(SbyConfig): | ||||||
|         raise SbyAbort(logmessage) |         raise SbyAbort(logmessage) | ||||||
| 
 | 
 | ||||||
|     def makedirs(self, path): |     def makedirs(self, path): | ||||||
|         if self.reusedir and os.path.isdir(path): |         path = Path(path) | ||||||
|  |         if self.reusedir and path.is_dir(): | ||||||
|             rmtree(path, ignore_errors=True) |             rmtree(path, ignore_errors=True) | ||||||
|         if not os.path.isdir(path): |         path.mkdir(parents=True, exist_ok=True) | ||||||
|             os.makedirs(path) |  | ||||||
| 
 | 
 | ||||||
|     def copy_src(self, linkmode=False): |     def copy_src(self, linkmode=False): | ||||||
|         self.makedirs(self.workdir + "/src") |         outdir = Path(self.workdir) / "src" | ||||||
|  |         self.makedirs(outdir) | ||||||
| 
 | 
 | ||||||
|         for dstfile, lines in self.verbatim_files.items(): |         for dstfile, lines in self.verbatim_files.items(): | ||||||
|             dstfile = self.workdir + "/src/" + dstfile |             dstfile = outdir / dstfile | ||||||
|             self.log(f"Writing '{dstfile}'.") |             self.log(f"Writing '{dstfile.absolute()}'.") | ||||||
|  |             dstfile.parent.mkdir(parents=True, exist_ok=True) | ||||||
| 
 | 
 | ||||||
|             with open(dstfile, "w") as f: |             with open(dstfile, "w") as f: | ||||||
|                 for line in lines: |                 for line in lines: | ||||||
|                     f.write(line) |                     f.write(line) | ||||||
| 
 | 
 | ||||||
|         for dstfile, srcfile in self.files.items(): |         for dstfile, srcfile in self.files.items(): | ||||||
|             if dstfile.startswith("/") or dstfile.startswith("../") or ("/../" in dstfile): |             dstfile = Path(dstfile) | ||||||
|  |             if dstfile.is_absolute() or ".." in dstfile.parts: | ||||||
|                 self.error(f"destination filename must be a relative path without /../: {dstfile}") |                 self.error(f"destination filename must be a relative path without /../: {dstfile}") | ||||||
|             dstfile = self.workdir + "/src/" + dstfile |             dstfile = outdir / dstfile | ||||||
| 
 | 
 | ||||||
|             srcfile = process_filename(srcfile) |             srcfile = process_filename(srcfile) | ||||||
| 
 | 
 | ||||||
|             basedir = os.path.dirname(dstfile) |             basedir = dstfile.parent | ||||||
|             if basedir != "" and not os.path.exists(basedir): |             basedir.mkdir(parents=True, exist_ok=True) | ||||||
|                 os.makedirs(basedir) |  | ||||||
| 
 | 
 | ||||||
|             if linkmode: |             if linkmode: | ||||||
|                 verb = "Link" |                 verb = "Link" | ||||||
|             else: |             else: | ||||||
|                 verb = "Copy" |                 verb = "Copy" | ||||||
|             self.log(f"{verb} '{os.path.abspath(srcfile)}' to '{os.path.abspath(dstfile)}'.") |             self.log(f"{verb} '{srcfile.absolute()}' to '{dstfile.absolute()}'.") | ||||||
| 
 | 
 | ||||||
|             if linkmode: |             if linkmode: | ||||||
|                 os.symlink(os.path.relpath(srcfile, basedir), dstfile) |                 os.symlink(srcfile.resolve(), dstfile) | ||||||
|             elif os.path.isdir(srcfile): |             elif srcfile.is_dir(): | ||||||
|                 copytree(srcfile, dstfile, dirs_exist_ok=True) |                 copytree(srcfile, dstfile, dirs_exist_ok=True) | ||||||
|             else: |             else: | ||||||
|                 copyfile(srcfile, dstfile) |                 copyfile(srcfile, dstfile) | ||||||
|  | @ -1097,12 +1095,12 @@ class SbyTask(SbyConfig): | ||||||
|             self.__dict__["opt_" + option_name] = default_value |             self.__dict__["opt_" + option_name] = default_value | ||||||
| 
 | 
 | ||||||
|     def make_model(self, model_name): |     def make_model(self, model_name): | ||||||
|         if not os.path.isdir(f"{self.workdir}/model"): |         modeldir = Path(self.workdir) / "model" | ||||||
|             os.makedirs(f"{self.workdir}/model") |         modeldir.mkdir(exist_ok=True) | ||||||
| 
 | 
 | ||||||
|         if model_name == "prep": |         if model_name == "prep": | ||||||
|             with open(f"""{self.workdir}/model/design_prep.ys""", "w") as f: |             with open(modeldir / "design_prep.ys", "w") as f: | ||||||
|                 print(f"# running in {self.workdir}/model/", file=f) |                 print(f"# running in {modeldir}/", file=f) | ||||||
|                 print(f"""read_rtlil design.il""", file=f) |                 print(f"""read_rtlil design.il""", file=f) | ||||||
|                 if not self.opt_skip_prep: |                 if not self.opt_skip_prep: | ||||||
|                     print("scc -select; simplemap; select -clear", file=f) |                     print("scc -select; simplemap; select -clear", file=f) | ||||||
|  | @ -1146,7 +1144,7 @@ class SbyTask(SbyConfig): | ||||||
|             return [proc] |             return [proc] | ||||||
| 
 | 
 | ||||||
|         if model_name == "base": |         if model_name == "base": | ||||||
|             with open(f"""{self.workdir}/model/design.ys""", "w") as f: |             with open(modeldir / "design.ys", "w") as f: | ||||||
|                 print(f"# running in {self.workdir}/src/", file=f) |                 print(f"# running in {self.workdir}/src/", file=f) | ||||||
|                 for cmd in self.script: |                 for cmd in self.script: | ||||||
|                     print(cmd, file=f) |                     print(cmd, file=f) | ||||||
|  | @ -1168,7 +1166,7 @@ class SbyTask(SbyConfig): | ||||||
| 
 | 
 | ||||||
|             def instance_hierarchy_callback(retcode): |             def instance_hierarchy_callback(retcode): | ||||||
|                 if self.design == None: |                 if self.design == None: | ||||||
|                     with open(f"{self.workdir}/model/design.json") as f: |                     with open(modeldir / "design.json") as f: | ||||||
|                         self.design = design_hierarchy(f) |                         self.design = design_hierarchy(f) | ||||||
|                         self.status_db.create_task_properties([ |                         self.status_db.create_task_properties([ | ||||||
|                             prop for prop in self.design.properties_by_path.values() |                             prop for prop in self.design.properties_by_path.values() | ||||||
|  | @ -1184,8 +1182,8 @@ class SbyTask(SbyConfig): | ||||||
|             return [proc] |             return [proc] | ||||||
| 
 | 
 | ||||||
|         if re.match(r"^smt2(_syn)?(_nomem)?(_stbv|_stdt)?$", model_name): |         if re.match(r"^smt2(_syn)?(_nomem)?(_stbv|_stdt)?$", model_name): | ||||||
|             with open(f"{self.workdir}/model/design_{model_name}.ys", "w") as f: |             with open(modeldir / f"design_{model_name}.ys", "w") as f: | ||||||
|                 print(f"# running in {self.workdir}/model/", file=f) |                 print(f"# running in {modeldir}/", file=f) | ||||||
|                 print(f"""read_rtlil design_prep.il""", file=f) |                 print(f"""read_rtlil design_prep.il""", file=f) | ||||||
|                 print("hierarchy -smtcheck", file=f) |                 print("hierarchy -smtcheck", file=f) | ||||||
|                 print("delete */t:$print", file=f) |                 print("delete */t:$print", file=f) | ||||||
|  | @ -1218,8 +1216,8 @@ class SbyTask(SbyConfig): | ||||||
|             return [proc] |             return [proc] | ||||||
| 
 | 
 | ||||||
|         if re.match(r"^btor(_syn)?(_nomem)?$", model_name): |         if re.match(r"^btor(_syn)?(_nomem)?$", model_name): | ||||||
|             with open(f"{self.workdir}/model/design_{model_name}.ys", "w") as f: |             with open(modeldir / f"design_{model_name}.ys", "w") as f: | ||||||
|                 print(f"# running in {self.workdir}/model/", file=f) |                 print(f"# running in {modeldir}/", file=f) | ||||||
|                 print(f"""read_rtlil design_prep.il""", file=f) |                 print(f"""read_rtlil design_prep.il""", file=f) | ||||||
|                 print("hierarchy -simcheck", file=f) |                 print("hierarchy -simcheck", file=f) | ||||||
|                 print("delete */t:$print", file=f) |                 print("delete */t:$print", file=f) | ||||||
|  | @ -1254,8 +1252,8 @@ class SbyTask(SbyConfig): | ||||||
|             return [proc] |             return [proc] | ||||||
| 
 | 
 | ||||||
|         if model_name == "aig": |         if model_name == "aig": | ||||||
|             with open(f"{self.workdir}/model/design_aiger.ys", "w") as f: |             with open(modeldir / "design_aiger.ys", "w") as f: | ||||||
|                 print(f"# running in {self.workdir}/model/", file=f) |                 print(f"# running in {modeldir}/", file=f) | ||||||
|                 print("read_rtlil design_prep.il", file=f) |                 print("read_rtlil design_prep.il", file=f) | ||||||
|                 print("delete */t:$print", file=f) |                 print("delete */t:$print", file=f) | ||||||
|                 print("hierarchy -simcheck", file=f) |                 print("hierarchy -simcheck", file=f) | ||||||
|  | @ -1281,7 +1279,7 @@ class SbyTask(SbyConfig): | ||||||
|                 self, |                 self, | ||||||
|                 "aig", |                 "aig", | ||||||
|                 self.model("prep"), |                 self.model("prep"), | ||||||
|                 f"""cd {self.workdir}/model; {self.exe_paths["yosys"]} -ql design_aiger.log design_aiger.ys""" |                 f"""cd {modeldir}; {self.exe_paths["yosys"]} -ql design_aiger.log design_aiger.ys""" | ||||||
|             ) |             ) | ||||||
|             proc.checkretcode = True |             proc.checkretcode = True | ||||||
| 
 | 
 | ||||||
|  | @ -1292,8 +1290,8 @@ class SbyTask(SbyConfig): | ||||||
|                 self, |                 self, | ||||||
|                 model_name, |                 model_name, | ||||||
|                 self.model("aig"), |                 self.model("aig"), | ||||||
|                 f"""cd {self.workdir}/model; {self.exe_paths["abc"]} -c 'read_aiger design_aiger.aig; fold{" -s" if self.opt_aigfolds else ""}; strash; write_aiger design_aiger_fold.aig'""", |                 f"""cd {modeldir}; {self.exe_paths["abc"]} -c 'read_aiger design_aiger.aig; fold{" -s" if self.opt_aigfolds else ""}; strash; write_aiger design_aiger_fold.aig'""", | ||||||
|                 logfile=open(f"{self.workdir}/model/design_aiger_fold.log", "w") |                 logfile=open(f"{modeldir}/design_aiger_fold.log", "w") | ||||||
|             ) |             ) | ||||||
|             proc.checkretcode = True |             proc.checkretcode = True | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								tests/links/more_dirs.sby
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								tests/links/more_dirs.sby
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | [tasks] | ||||||
|  | link | ||||||
|  | copy | ||||||
|  | 
 | ||||||
|  | [options] | ||||||
|  | mode prep | ||||||
|  | 
 | ||||||
|  | [engines] | ||||||
|  | btor btormc | ||||||
|  | 
 | ||||||
|  | [script] | ||||||
|  | read -noverific | ||||||
|  | script dir/script.ys | ||||||
|  | 
 | ||||||
|  | [files] | ||||||
|  | here/dir ${WORKDIR}/../dir | ||||||
|  | a/b/c.v prv32fmcmp.v | ||||||
|  | 
 | ||||||
|  | [file here/doc] | ||||||
|  | log foo | ||||||
							
								
								
									
										10
									
								
								tests/links/more_dirs.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/links/more_dirs.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | set -e | ||||||
|  | if [[ $TASK == link ]]; then | ||||||
|  |     flags="--setup --link" | ||||||
|  | else | ||||||
|  |     flags="--setup" | ||||||
|  | fi | ||||||
|  | python3 $SBY_MAIN -f $SBY_FILE $TASK $flags | ||||||
|  | 
 | ||||||
|  | test -e ${WORKDIR}/src/here/dir -a -e ${WORKDIR}/src/a/b/c.v -a -e ${WORKDIR}/src/here/doc | ||||||
|  | @ -1,10 +1,10 @@ | ||||||
| import os |  | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| import sys | import sys | ||||||
| 
 | 
 | ||||||
| def main(): | def main(): | ||||||
|     workdir, task = sys.argv[1:] |     workdir, task = sys.argv[1:] | ||||||
|     src = Path(workdir) / "src" |     src = Path(workdir) / "src" | ||||||
|  |     count = 0 | ||||||
|     for srcfile in src.iterdir(): |     for srcfile in src.iterdir(): | ||||||
|         if srcfile.name == "heredoc": |         if srcfile.name == "heredoc": | ||||||
|             assert(not srcfile.is_symlink()) |             assert(not srcfile.is_symlink()) | ||||||
|  | @ -13,6 +13,11 @@ def main(): | ||||||
|                 assert(local_contents.strip() == 'log foo') |                 assert(local_contents.strip() == 'log foo') | ||||||
|         else: |         else: | ||||||
|             assert(srcfile.is_symlink() == (task == "link")) |             assert(srcfile.is_symlink() == (task == "link")) | ||||||
|  |             assert(srcfile.name != "script.ys") | ||||||
|  |         count += 1 | ||||||
|  |     assert(count == 4) | ||||||
|  |     script_ys = src / "dir" / "script.ys" | ||||||
|  |     assert(script_ys.exists()) | ||||||
| 
 | 
 | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     main() |     main() | ||||||
|  |  | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| [tasks] | [tasks] | ||||||
| link | link | ||||||
| copy | copy | ||||||
|  | dir_implicit: dir | ||||||
|  | dir_explicit: dir | ||||||
| 
 | 
 | ||||||
| [options] | [options] | ||||||
| mode prep | mode prep | ||||||
|  | @ -15,7 +17,9 @@ script dir/script.ys | ||||||
| [files] | [files] | ||||||
| ../../docs/examples/demos/picorv32.v | ../../docs/examples/demos/picorv32.v | ||||||
| prv32fmcmp.v | prv32fmcmp.v | ||||||
| dir | ~dir: dir | ||||||
|  | dir_implicit: dir/ | ||||||
|  | dir_explicit: dir/ dir/ | ||||||
| 
 | 
 | ||||||
| [file heredoc] | [file heredoc] | ||||||
| log foo | log foo | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue