def cmd_files(args): cfg_file = _ConfigFile("") cfg = Config(file=cfg_file) # logging.basicConfig(level=logging.DEBUG) cm = CoreManager(cfg) packages_dir = get_packages_dir() project_dir = os.path.dirname(packages_dir) cm.add_library(Library("project", project_dir)) if args.library_path is not None: for lib in args.library_path: colon_i = lib.find(':') if colon_i > 1: path = lib[colon_i + 1:] lib_name = lib[:colon_i] else: path = lib lib_name = "cmdline" cm.add_library(Library(lib_name, path)) top_flags = {"is_toplevel": True} if hasattr(args, "target") and args.target is not None: top_flags["target"] = args.target # Use detailed arguments core_deps = cm.get_depends(Vlnv(args.vlnv), flags=top_flags) flags = {} if hasattr(args, "flags") and args.flags is not None: for f in args.flags: subflags = f.split(',') for sf in subflags: flags[sf] = True file_type = None if args.file_type is not None: file_type = set() for t in args.file_type: subtypes = t.split(',') for st in subtypes: file_type.add(st) _extract_files(sys.stdout, core_deps, file_type, flags, args.include)
def test_virtual(): import os import tempfile from fusesoc.config import Config from fusesoc.coremanager import CoreManager from fusesoc.edalizer import Edalizer from fusesoc.librarymanager import Library from fusesoc.vlnv import Vlnv flags = {"tool": "icarus"} build_root = tempfile.mkdtemp(prefix="export_") work_root = os.path.join(build_root, "work") core_dir = os.path.join(os.path.dirname(__file__), "capi2_cores", "virtual") cm = CoreManager(Config()) cm.add_library(Library("virtual", core_dir)) root_core = cm.get_core(Vlnv("::user")) edalizer = Edalizer( toplevel=root_core.name, flags=flags, core_manager=cm, work_root=work_root, ) edalizer.run() deps = cm.get_depends(root_core.name, {}) deps_names = [str(c) for c in deps] assert deps_names == ["::impl2:0", "::user:0"]
def __init__(self): cfg_file = _ConfigFile("") cfg = Config(file=cfg_file) self.cm = CoreManagerW(cfg) packages_dir = get_packages_dir() project_dir = os.path.dirname(packages_dir) self.cm.add_library(Library("project", project_dir))
def init(cm, args): warnings.warn( "The 'init' subcommand is deprecated and will be removed in the next " "release. It was intended to fetch the FuseSoC standard library. This can be done with 'fusesoc library add fusesoc_cores https://github.com/fusesoc/fusesoc-cores' instead.", FutureWarning, ) # Fix Python 2.x. global input try: input = raw_input except NameError: pass xdg_config_home = os.environ.get("XDG_CONFIG_HOME") or os.path.join( os.path.expanduser("~"), ".config") config_file = os.path.join(xdg_config_home, "fusesoc", "fusesoc.conf") if os.path.exists(config_file): logger.warning(f"'{config_file}' already exists. Aborting") exit(1) # TODO. Prepend cores_root to file if it doesn't exist f = open(config_file, "w+") else: logger.info(f"Writing configuration file to '{config_file}'") if not os.path.exists(os.path.dirname(config_file)): os.makedirs(os.path.dirname(config_file)) f = open(config_file, "w+") config = Config(file=f) _repo_paths = [] for repo in REPOS: name = repo[0] uri = repo[1] default_dir = os.path.join(cm._lm.library_root, name) prompt = "Directory to use for {} ({}) [{}] : " if args.y: location = None else: location = input(prompt.format(repo[0], repo[2], default_dir)) if not location: location = default_dir if os.path.exists(location): logger.warning( "'{}' already exists. This library will not be added to fusesoc.conf" .format(location)) # TODO: Prompt for overwrite else: logger.info(f"Initializing {name}") try: library = Library(name, location, "git", uri, True) config.add_library(library) except RuntimeError as e: logger.error("Init failed: " + str(e)) exit(1) logger.info("FuseSoC is ready to use!")
def init(cm, args): # Fix Python 2.x. global input try: input = raw_input except NameError: pass xdg_config_home = os.environ.get("XDG_CONFIG_HOME") or os.path.join( os.path.expanduser("~"), ".config" ) config_file = os.path.join(xdg_config_home, "fusesoc", "fusesoc.conf") if os.path.exists(config_file): logger.warning("'{}' already exists. Aborting".format(config_file)) exit(1) # TODO. Prepend cores_root to file if it doesn't exist f = open(config_file, "w+") else: logger.info("Writing configuration file to '{}'".format(config_file)) if not os.path.exists(os.path.dirname(config_file)): os.makedirs(os.path.dirname(config_file)) f = open(config_file, "w+") config = Config(file=f) _repo_paths = [] for repo in REPOS: name = repo[0] uri = repo[1] default_dir = os.path.join(cm._lm.library_root, name) prompt = "Directory to use for {} ({}) [{}] : " if args.y: location = None else: location = input(prompt.format(repo[0], repo[2], default_dir)) if not location: location = default_dir if os.path.exists(location): logger.warning( "'{}' already exists. This library will not be added to fusesoc.conf".format( location ) ) # TODO: Prompt for overwrite else: logger.info("Initializing {}".format(name)) try: library = Library(name, location, "git", uri, True) config.add_library(library) except RuntimeError as e: logger.error("Init failed: " + str(e)) exit(1) logger.info("FuseSoC is ready to use!")
def test_copyto(): import os import tempfile from fusesoc.config import Config from fusesoc.coremanager import CoreManager from fusesoc.edalizer import Edalizer from fusesoc.librarymanager import Library from fusesoc.vlnv import Vlnv flags = {"tool": "icarus"} work_root = tempfile.mkdtemp(prefix="copyto_") core_dir = os.path.join(os.path.dirname(__file__), "cores", "misc", "copytocore") lib = Library("misc", core_dir) cm = CoreManager(Config()) cm.add_library(lib) core = cm.get_core(Vlnv("::copytocore")) edalizer = Edalizer( toplevel=core.name, flags=flags, core_manager=cm, cache_root=None, work_root=work_root, export_root=None, system_name=None, ) edalizer.run() eda_api = edalizer.edalize assert eda_api["files"] == [ { "file_type": "user", "core": "::copytocore:0", "logical_name": "", "name": "copied.file", "is_include_file": False, }, { "file_type": "tclSource", "core": "::copytocore:0", "logical_name": "", "name": "subdir/another.file", "is_include_file": False, }, ] assert os.path.exists(os.path.join(work_root, "copied.file")) assert os.path.exists(os.path.join(work_root, "subdir", "another.file"))
def init_coremanager(config, args_cores_root): logger.debug("Initializing core manager") cm = CoreManager(config) args_libs = [Library(acr, acr) for acr in args_cores_root] # Add libraries from config file, env var and command-line for library in config.libraries + args_libs: try: cm.add_library(library) except (RuntimeError, IOError) as e: _s = "Failed to register library '{}'" logger.warning(_s.format(str(e))) return cm
def add_library(cm, args): sync_uri = vars(args)["sync-uri"] if args.location: location = args.location elif vars(args).get("global", False): location = os.path.join(cm._lm.library_root, args.name) else: location = os.path.join("fusesoc_libraries", args.name) if "sync-type" in vars(args): sync_type = vars(args)["sync-type"] else: sync_type = None # Check if it's a dir. Otherwise fall back to git repo if not sync_type: if os.path.isdir(sync_uri): sync_type = "local" else: sync_type = "git" if sync_type == "local": logger.info( "Interpreting sync-uri '{}' as location for local provider.".format( sync_uri ) ) location = os.path.abspath(sync_uri) auto_sync = not args.no_auto_sync library = Library(args.name, location, sync_type, sync_uri, auto_sync) if args.config: config = Config(file=args.config) elif vars(args)["global"]: xdg_config_home = os.environ.get("XDG_CONFIG_HOME") or os.path.join( os.path.expanduser("~"), ".config" ) config_file = os.path.join(xdg_config_home, "fusesoc", "fusesoc.conf") config = Config(path=config_file) else: config = Config(path="fusesoc.conf") try: config.add_library(library) except RuntimeError as e: logger.error("`add library` failed: " + str(e)) exit(1)
def test_export(): import os import tempfile from fusesoc.config import Config from fusesoc.coremanager import CoreManager from fusesoc.edalizer import Edalizer from fusesoc.librarymanager import Library from fusesoc.vlnv import Vlnv flags = {"tool": "icarus"} build_root = tempfile.mkdtemp(prefix="export_") export_root = os.path.join(build_root, "exported_files") work_root = os.path.join(build_root, "work") core_dir = os.path.join(os.path.dirname(__file__), "cores") cm = CoreManager(Config()) cm.add_library(Library("cores", core_dir)) core = cm.get_core(Vlnv("::wb_intercon")) edalizer = Edalizer( toplevel=core.name, flags=flags, core_manager=cm, cache_root=None, work_root=work_root, export_root=export_root, system_name=None, ) edalizer.run() for f in [ "wb_intercon_1.0/dummy_icarus.v", "wb_intercon_1.0/bench/wb_mux_tb.v", "wb_intercon_1.0/bench/wb_upsizer_tb.v", "wb_intercon_1.0/bench/wb_intercon_tb.v", "wb_intercon_1.0/bench/wb_arbiter_tb.v", "wb_intercon_1.0/rtl/verilog/wb_data_resize.v", "wb_intercon_1.0/rtl/verilog/wb_mux.v", "wb_intercon_1.0/rtl/verilog/wb_arbiter.v", "wb_intercon_1.0/rtl/verilog/wb_upsizer.v", ]: assert os.path.isfile(os.path.join(export_root, f))
def add_library(cm, args): sync_uri = vars(args)['sync-uri'] if args.location: location = args.location elif vars(args).get('global', False): location = os.path.join(cm._lm.library_root, args.name) else: location = os.path.join('fusesoc_libraries', args.name) if 'sync-type' in vars(args): sync_type = vars(args)['sync-type'] else: sync_type = None #Check if it's a dir. Otherwise fall back to git repo if not sync_type: if os.path.isdir(sync_uri): sync_type = 'local' else: sync_type = 'git' if sync_type == 'local': logger.info( "Interpreting sync-uri '{}' as location for local provider.". format(sync_uri)) location = os.path.abspath(sync_uri) auto_sync = not args.no_auto_sync library = Library(args.name, location, sync_type, sync_uri, auto_sync) if args.config: config = Config(file=args.config) elif vars(args)['global']: xdg_config_home = os.environ.get('XDG_CONFIG_HOME') or \ os.path.join(os.path.expanduser('~'), '.config') config_file = os.path.join(xdg_config_home, 'fusesoc', 'fusesoc.conf') config = Config(path=config_file) else: config = Config(path="fusesoc.conf") try: config.add_library(library) except RuntimeError as e: logger.error("`add library` failed: " + str(e)) exit(1)
def test_deptree(): from fusesoc.coremanager import CoreManager from fusesoc.config import Config from fusesoc.librarymanager import Library from fusesoc.vlnv import Vlnv import os tests_dir = os.path.dirname(__file__) deptree_cores_dir = os.path.join(tests_dir, "capi2_cores", "deptree") lib = Library("deptree", deptree_cores_dir) cm = CoreManager(Config()) cm.add_library(lib) root_core = cm.get_core(Vlnv("::deptree-root")) # Check dependency tree deps = cm.get_depends(root_core.name, {}) deps_names = [str(c) for c in deps] deps_names_expected = [ "::deptree-child2:0", "::deptree-child3:0", "::deptree-child1:0", "::deptree-root:0", ] assert deps_names == deps_names_expected # Check files in dependency tree files_expected = [ "child2-fs1-f1.sv", "child2-fs1-f2.sv", "child3-fs1-f1.sv", "child3-fs1-f2.sv", "child1-fs1-f1.sv", "child1-fs1-f2.sv", "root-fs1-f1.sv", "root-fs1-f2.sv", "root-fs2-f1.sv", "root-fs2-f2.sv", ] files = [] for d in deps: files += [f["name"] for f in d.get_files({})] assert files == files_expected
def test_generators(): import os import tempfile from fusesoc.config import Config from fusesoc.coremanager import CoreManager from fusesoc.edalizer import Edalizer from fusesoc.librarymanager import Library from fusesoc.vlnv import Vlnv tests_dir = os.path.dirname(__file__) cores_dir = os.path.join(tests_dir, "capi2_cores", "misc", "generate") lib = Library("edalizer", cores_dir) cm = CoreManager(Config()) cm.add_library(lib) core = cm.get_core(Vlnv("::generate")) build_root = tempfile.mkdtemp(prefix="export_") cache_root = tempfile.mkdtemp(prefix="export_cache_") export_root = os.path.join(build_root, "exported_files") edalizer = Edalizer( toplevel=core.name, flags={"tool": "icarus"}, core_manager=cm, cache_root=cache_root, work_root=os.path.join(build_root, "work"), export_root=export_root, system_name=None, ) edalizer.run() gendir = os.path.join(cache_root, "generated", "generate-testgenerate_without_params_0") assert os.path.isfile(os.path.join(gendir, "generated.core")) assert os.path.isfile( os.path.join(gendir, "testgenerate_without_params_input.yml")) gendir = os.path.join(cache_root, "generated", "generate-testgenerate_with_params_0") assert os.path.isfile(os.path.join(gendir, "generated.core")) assert os.path.isfile( os.path.join(gendir, "testgenerate_with_params_input.yml"))
def test_generators(): import os import tempfile from fusesoc.config import Config from fusesoc.coremanager import CoreManager from fusesoc.edalizer import Edalizer from fusesoc.librarymanager import Library from fusesoc.vlnv import Vlnv tests_dir = os.path.dirname(__file__) cores_dir = os.path.join(tests_dir, "capi2_cores", "misc", "generate") lib = Library("edalizer", cores_dir) cm = CoreManager(Config()) cm.add_library(lib) core = cm.get_core(Vlnv("::generate")) build_root = tempfile.mkdtemp(prefix="export_") export_root = os.path.join(build_root, "exported_files") edalizer = Edalizer( toplevel=core.name, flags={"tool": "icarus"}, core_manager=cm, work_root=os.path.join(build_root, "work"), export_root=export_root, system_name=None, ) edalizer.run() name_to_core = {str(core.name): core for core in edalizer.cores} for flavour in ["testgenerate_with_params", "testgenerate_without_params"]: core_name = f"::generate-{flavour}:0" assert core_name in name_to_core core = name_to_core[core_name] # ttptttg temporary directory should be removed by now assert not os.path.isdir(core.core_root)
def test_smoke(self): unit_dir = os.path.dirname(os.path.abspath(__file__)) data_dir = os.path.join(unit_dir, "data", "fusesoc", "data1") # logging.basicConfig(level=logging.DEBUG) cfg_file = TestFuseSoc.ConfigFile(content=""" """) cfg = Config(file=cfg_file) cm = CoreManager(cfg) lib = Library("packages", data_dir) cm.add_library(lib) print("Cores: %s" % str(cm.get_cores())) data1: Core = cm.get_core(Vlnv('data1::core1')) print("Core: %s" % data1.core_root) print("Filesets: %s" % str(data1.filesets.keys())) print("Targets: %s" % str(data1.targets.keys())) depends = cm.get_depends( Vlnv('data1::core13'), { # "is_toplevel": True, "target": "pss" }) print("depends: %s" % str(depends)) print("--> get_files") files = depends[0].get_files({"is_toplevel": True, "target": "pss"}) print("<-- get_files") print("files[pss]: %s" % str(files)) pss_files = [] for dep in depends: files = dep.get_files({"is_toplevel": True, "target": "pss"}) for f in files: if f['file_type'] == 'pssSource': pss_files.append(os.path.join(dep.core_root, f['name'])) print("pss_files: %s" % str(pss_files))
def cmd_filespec(args): cfg_file = _ConfigFile("") cfg = Config(file=cfg_file) if args.debug: logging.basicConfig(level=logging.DEBUG) cm = CoreManager(cfg) if not hasattr(args, "output") or args.output is None: args.output = "-" packages_dir = get_packages_dir() project_dir = os.path.dirname(packages_dir) cm.add_library(Library("project", project_dir)) if args.library_path is not None: for lib in args.library_path: colon_i = lib.find(':') if colon_i > 1: path = lib[colon_i + 1:] lib_name = lib[:colon_i] else: path = lib lib_name = "cmdline" cm.add_library(Library(lib_name, path)) top_flags = {"is_toplevel": True} filepath_m = {} template_m = _find_builtin_templates() if not hasattr(args, "template") or args.template is None: # Report on available templates raise Exception("No template specified. Avaiable: %s" % " ".join(list(template_m.keys()))) if os.path.isfile(args.template): template = args.template else: if args.template not in template_m.keys(): raise Exception("Template %s not present. Avaiable: %s" % (args.template, " ".join(list(template_m.keys())))) else: template = template_m[args.template] with open(args.filespec, "r") as fp: filespec = yaml.load(fp, Loader=yaml.loader.FullLoader) if "filespec" not in filespec.keys(): raise Exception("YAML filespec does not contain 'filespec'") fs = filespec["filespec"] for v in fs: out = v["out"] for e in out: top_flags = {"is_toplevel": True} if "flags" in e.keys(): f = e["flags"] if isinstance(f, list): for fi in f: top_flags[fi] = True else: top_flags[f] = True core_deps = cm.get_depends(Vlnv(v["vlnv"]), flags=top_flags) name = e["name"] flags = {} file_type = set() t = e["type"] if isinstance(t, list): for ti in t: file_type.add(ti) else: file_type.add(t) if "flags" in e.keys(): f = e["flags"] if isinstance(f, list): for fi in f: flags[fi] = True else: flags[f] = True if "include" in e.keys(): include = e["include"] else: include = False # print("file_type: %s ; include=%s" % (str(file_type), str(include))) files = _collect_files(core_deps, file_type, flags, include) filepath_m[name] = files # Now, generate the output t_loader = _TemplateLoader(template) env = jinja2.Environment(loader=t_loader) templ = env.get_template(template) out = templ.render({"files": filepath_m}) if args.output == "-": sys.stdout.write(out) else: with open(args.output, "w") as fp: fp.write(out)
def __init__(self, path=None, file=None): self.build_root = None self.cache_root = None cores_root = [] systems_root = [] self.library_root = None self.libraries = [] config = CP() if file is None: if path is None: xdg_config_home = os.environ.get('XDG_CONFIG_HOME') or \ os.path.join(os.path.expanduser('~'), '.config') config_files = [ '/etc/fusesoc/fusesoc.conf', os.path.join(xdg_config_home, 'fusesoc', 'fusesoc.conf'), 'fusesoc.conf' ] else: logger.debug("Using config file '{}'".format(path)) if not os.path.isfile(path): with open(path, 'a'): pass config_files = [path] logger.debug('Looking for config files from ' + ':'.join(config_files)) files_read = config.read(config_files) logger.debug('Found config files in ' + ':'.join(files_read)) if files_read: self._path = files_read[-1] else: logger.debug('Using supplied config file') if sys.version[0] == '2': config.readfp(file) else: config.read_file(file) file.seek(0) self._path = file.name for item in [ 'build_root', 'cache_root', 'systems_root', 'library_root' ]: try: setattr(self, item, os.path.expanduser(config.get('main', item))) if item == 'systems_root': systems_root = [ os.path.expanduser(config.get('main', item)) ] logger.warn( 'The systems_root option in fusesoc.conf is deprecated. Please migrate to libraries instead' ) except configparser.NoOptionError: pass except configparser.NoSectionError: pass try: cores_root = config.get('main', 'cores_root').split() logger.warn( 'The cores_root option in fusesoc.conf is deprecated. Please migrate to libraries instead' ) except configparser.NoOptionError: pass except configparser.NoSectionError: pass #Set fallback values if self.build_root is None: self.build_root = os.path.abspath('build') if self.cache_root is None: xdg_cache_home = os.environ.get('XDG_CACHE_HOME') or \ os.path.join(os.path.expanduser('~'), '.cache') self.cache_root = os.path.join(xdg_cache_home, 'fusesoc') if not os.path.exists(self.cache_root): os.makedirs(self.cache_root) if not cores_root and os.path.exists('cores'): cores_root = [os.path.abspath('cores')] if (not systems_root) and os.path.exists('systems'): systems_root = [os.path.abspath('systems')] if self.library_root is None: xdg_data_home = os.environ.get('XDG_DATA_HOME') or \ os.path.join(os.path.expanduser('~'), '.local/share') self.library_root = os.path.join(xdg_data_home, 'fusesoc') # Parse library sections libraries = [] library_sections = [ x for x in config.sections() if x.startswith('library') ] for section in library_sections: name = section.partition('.')[2] try: location = config.get(section, 'location') except configparser.NoOptionError: location = os.path.join(self.library_root, name) try: auto_sync = config.getboolean(section, 'auto-sync') except configparser.NoOptionError: auto_sync = True except ValueError as e: _s = "Error parsing auto-sync '{}'. Ignoring library '{}'" logger.warn(_s.format(str(e), name)) continue try: sync_uri = config.get(section, 'sync-uri') except configparser.NoOptionError: # sync-uri is absent for local libraries sync_uri = None try: sync_type = config.get(section, 'sync-type') except configparser.NoOptionError: # sync-uri is absent for local libraries sync_type = None libraries.append( Library(name, location, sync_type, sync_uri, auto_sync)) # Get the environment variable for further cores env_cores_root = [] if os.getenv("FUSESOC_CORES"): env_cores_root = os.getenv("FUSESOC_CORES").split(":") env_cores_root.reverse() for root in cores_root + systems_root + env_cores_root: self.libraries.append(Library(root, root)) self.libraries += libraries logger.debug('cache_root=' + self.cache_root) logger.debug('library_root=' + self.library_root)
def cmd_regress(args): specfiles = [] cm = CoreManagerW() packages_dir = get_packages_dir() project_dir = os.path.dirname(packages_dir) cm.add_library(Library("project", project_dir)) cwd_is_lib = False if args.library_path is not None: for path in args.library_path: if os.getcwd().startswith(path): cwd_is_lib = True cm.add_library(Library(os.path.basename(path), path)) if not cwd_is_lib: cm.add_library(Library(os.path.basename(os.getcwd()), os.getcwd())) if hasattr(args, "jobspecs") and args.jobspecs is not None: specfiles.extend(args.jobspecs) if len(specfiles) == 0: if os.path.isfile(os.path.join(os.getcwd(), "mkdv.yaml")): specfiles.append(os.path.join(os.getcwd(), "mkdv.yaml")) else: raise Exception("No specfiles specified") loader = JobspecLoader(core_mgr=cm) jobset_s = loader.load_specs(specfiles) regress = os.path.join(os.getcwd(), "regress") rundir = os.path.join(regress, datetime.now().strftime("%Y%m%d_%H%M%S")) gendir = os.path.join(rundir, "gen") specs = jobset_s.jobspecs.copy() gen_specs = [] for s in jobset_s.jobspec_gen: spec_gendir = os.path.join(gendir, s.root_id) os.makedirs(spec_gendir) gen_jobset_s = JobSpecGenLoader(spec_gendir).load(s) specs.extend(gen_jobset_s.jobspecs) # filter specs specs = JobSpecFilter( args.include if args.include is not None else [], args.exclude if args.exclude is not None else []).filter(specs) # Expand any jobs that have a count >1 specs_exp = JobCountExpander.expand(specs) # Now, assign each unique job an id and seed for i, s in enumerate(specs_exp): s.id = i s.seed = i os.makedirs(rundir, exist_ok=True) backend = backends.backend(args.backend) r = JobRunner(rundir, backend, specs_exp) if hasattr(args, "limit_time") and args.limit_time is not None: r.limit_time = args.limit_time r.tool = args.tool r.rerun_failing = args.rerun_failing # TODO: should query the job runner if args.max_par is not None: r.maxpar = int(args.max_par) print("--> run " + str(r)) loop = asyncio.get_event_loop() loop.run_until_complete(r.runjobs()) print("<-- run")
def test_deptree(tmp_path): import os from fusesoc.config import Config from fusesoc.coremanager import CoreManager from fusesoc.edalizer import Edalizer from fusesoc.librarymanager import Library from fusesoc.vlnv import Vlnv flags = {"tool": "icarus"} tests_dir = os.path.dirname(__file__) deptree_cores_dir = os.path.join(tests_dir, "capi2_cores", "deptree") lib = Library("deptree", deptree_cores_dir) cm = CoreManager(Config()) cm.add_library(lib) root_core = cm.get_core(Vlnv("::deptree-root")) # This is an array of (child, parent) core name tuples and # is used for checking that the flattened list of core # names is consistent with the dependencies. dependencies = ( # Dependencies of the root core ("::deptree-child3:0", "::deptree-root:0"), ("::deptree-child2:0", "::deptree-root:0"), ("::deptree-child1:0", "::deptree-root:0"), ("::deptree-child-a:0", "::deptree-root:0"), # Dependencies of child1 core ("::deptree-child3:0", "::deptree-child1:0"), # Dependencies of child-a core ("::deptree-child4:0", "::deptree-child-a:0"), ) # The ordered files that we expect from each core. expected_core_files = { "::deptree-child3:0": ( "child3-fs1-f1.sv", "child3-fs1-f2.sv", ), "::deptree-child2:0": ( "child2-fs1-f1.sv", "child2-fs1-f2.sv", ), "::deptree-child1:0": ( "child1-fs1-f1.sv", "child1-fs1-f2.sv", ), "::deptree-child4:0": ("child4.sv", ), "::deptree-child-a:0": ( # Files from filesets are always included before any # files from generators with "position: append". # This is because generated files are often dependent on files # that are not generated, and it convenient to be able to # include them in the same core. "child-a2.sv", "generated-child-a.sv", "generated-child-a-append.sv", ), "::deptree-root:0": ( "root-fs1-f1.sv", "root-fs1-f2.sv", "root-fs2-f1.sv", "root-fs2-f2.sv", ), } # Use Edalizer to get the files. # This is necessary because we need to run generators. work_root = str(tmp_path / "work") os.mkdir(work_root) edalizer = Edalizer( toplevel=root_core.name, flags=flags, work_root=work_root, core_manager=cm, ) edam = edalizer.run() # Check dependency tree (after running all generators) deps = cm.get_depends(root_core.name, {}) deps_names = [str(c) for c in deps] all_core_names = set() for child, parent in dependencies: assert child in deps_names assert parent in deps_names all_core_names.add(child) all_core_names.add(parent) # Confirm that we don't have any extra or missing core names. assert all_core_names == set(deps_names) # Make sure there are no repeats in deps_names assert len(all_core_names) == len(deps_names) # Now work out what order we expect to get the filenames. # The order of filenames within each core in deterministic. # Each fileset in order. Followed by each generator in order. # The order between the cores is taken the above `dep_names`. expected_filenames = [] # A generator-created core with "position: first" expected_filenames.append("generated-child-a-first.sv") for dep_name in deps_names: expected_filenames += list(expected_core_files[dep_name]) # A generator-created core with "position: last" expected_filenames.append("generated-child-a-last.sv") edalized_filenames = [os.path.basename(f["name"]) for f in edam["files"]] assert edalized_filenames == expected_filenames
def __init__(self, path=None, file=None): self.build_root = None self.cache_root = None cores_root = [] systems_root = [] self.library_root = None self.libraries = [] config = CP() if file is None: if path is None: xdg_config_home = os.environ.get("XDG_CONFIG_HOME") or os.path.join( os.path.expanduser("~"), ".config" ) config_files = [ "/etc/fusesoc/fusesoc.conf", os.path.join(xdg_config_home, "fusesoc", "fusesoc.conf"), "fusesoc.conf", ] else: logger.debug("Using config file '{}'".format(path)) if not os.path.isfile(path): with open(path, "a"): pass config_files = [path] logger.debug("Looking for config files from " + ":".join(config_files)) files_read = config.read(config_files) logger.debug("Found config files in " + ":".join(files_read)) if files_read: self._path = files_read[-1] else: logger.debug("Using supplied config file") if sys.version[0] == "2": config.readfp(file) else: config.read_file(file) file.seek(0) self._path = file.name for item in ["build_root", "cache_root", "systems_root", "library_root"]: try: setattr(self, item, os.path.expanduser(config.get("main", item))) if item == "systems_root": systems_root = [os.path.expanduser(config.get("main", item))] logger.warning( "The systems_root option in fusesoc.conf is deprecated. Please migrate to libraries instead" ) except configparser.NoOptionError: pass except configparser.NoSectionError: pass try: cores_root = config.get("main", "cores_root").split() logger.warning( "The cores_root option in fusesoc.conf is deprecated. Please migrate to libraries instead" ) except configparser.NoOptionError: pass except configparser.NoSectionError: pass # Set fallback values if self.build_root is None: self.build_root = os.path.abspath("build") if self.cache_root is None: xdg_cache_home = os.environ.get("XDG_CACHE_HOME") or os.path.join( os.path.expanduser("~"), ".cache" ) self.cache_root = os.path.join(xdg_cache_home, "fusesoc") os.makedirs(self.cache_root, exist_ok=True) if not cores_root and os.path.exists("cores"): cores_root = [os.path.abspath("cores")] if (not systems_root) and os.path.exists("systems"): systems_root = [os.path.abspath("systems")] if self.library_root is None: xdg_data_home = os.environ.get("XDG_DATA_HOME") or os.path.join( os.path.expanduser("~"), ".local/share" ) self.library_root = os.path.join(xdg_data_home, "fusesoc") # Parse library sections libraries = [] library_sections = [x for x in config.sections() if x.startswith("library")] for section in library_sections: name = section.partition(".")[2] try: location = config.get(section, "location") except configparser.NoOptionError: location = os.path.join(self.library_root, name) try: auto_sync = config.getboolean(section, "auto-sync") except configparser.NoOptionError: auto_sync = True except ValueError as e: _s = "Error parsing auto-sync '{}'. Ignoring library '{}'" logger.warning(_s.format(str(e), name)) continue try: sync_uri = config.get(section, "sync-uri") except configparser.NoOptionError: # sync-uri is absent for local libraries sync_uri = None try: sync_type = config.get(section, "sync-type") except configparser.NoOptionError: # sync-uri is absent for local libraries sync_type = None libraries.append(Library(name, location, sync_type, sync_uri, auto_sync)) # Get the environment variable for further cores env_cores_root = [] if os.getenv("FUSESOC_CORES"): env_cores_root = os.getenv("FUSESOC_CORES").split(":") env_cores_root.reverse() for root in cores_root + systems_root + env_cores_root: self.libraries.append(Library(root, root)) self.libraries += libraries logger.debug("cache_root=" + self.cache_root) logger.debug("library_root=" + self.library_root)