f4pga/sfbuild: get INSTALL_DIR from environ
Signed-off-by: Unai Martinez-Corral <umartinezcorral@antmicro.com>
This commit is contained in:
parent
898eab8232
commit
72913daac2
|
@ -23,6 +23,7 @@ such as list of source code files.
|
||||||
|
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
import os
|
import os
|
||||||
|
from os import environ
|
||||||
import json
|
import json
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
from colorama import Fore, Style
|
from colorama import Fore, Style
|
||||||
|
@ -45,7 +46,7 @@ mypath = os.path.realpath(os.sys.argv[0])
|
||||||
mypath = os.path.dirname(mypath)
|
mypath = os.path.dirname(mypath)
|
||||||
binpath = os.path.realpath(os.path.join(mypath, '..'))
|
binpath = os.path.realpath(os.path.join(mypath, '..'))
|
||||||
|
|
||||||
share_dir_path = os.path.realpath(os.path.join(mypath, '../../share/symbiflow'))
|
share_dir_path = os.path.realpath(f"{environ.get('INSTALL_DIR', '/usr/local')}/xc7/install/share/symbiflow")
|
||||||
|
|
||||||
class DependencyNotProducedException(Exception):
|
class DependencyNotProducedException(Exception):
|
||||||
dep_name: str
|
dep_name: str
|
||||||
|
@ -54,7 +55,7 @@ class DependencyNotProducedException(Exception):
|
||||||
def __init__(self, dep_name: str, provider: str):
|
def __init__(self, dep_name: str, provider: str):
|
||||||
self.dep_name = dep_name
|
self.dep_name = dep_name
|
||||||
self.provider = provider
|
self.provider = provider
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f'Stage `{self.provider}` did not produce promised ' \
|
return f'Stage `{self.provider}` did not produce promised ' \
|
||||||
f'dependency `{self.dep_name}`'
|
f'dependency `{self.dep_name}`'
|
||||||
|
@ -69,10 +70,10 @@ def platform_stages(platform_flow, r_env):
|
||||||
for stage_name, modulestr in platform_flow['stages'].items():
|
for stage_name, modulestr in platform_flow['stages'].items():
|
||||||
mod_opts = stage_options.get(stage_name) if stage_options else None
|
mod_opts = stage_options.get(stage_name) if stage_options else None
|
||||||
yield Stage(stage_name, modulestr, mod_opts, r_env)
|
yield Stage(stage_name, modulestr, mod_opts, r_env)
|
||||||
|
|
||||||
def req_exists(r):
|
def req_exists(r):
|
||||||
""" Checks whether a dependency exists on a drive. """
|
""" Checks whether a dependency exists on a drive. """
|
||||||
|
|
||||||
if type(r) is str:
|
if type(r) is str:
|
||||||
if not os.path.isfile(r) and not os.path.islink(r) \
|
if not os.path.isfile(r) and not os.path.islink(r) \
|
||||||
and not os.path.isdir(r):
|
and not os.path.isdir(r):
|
||||||
|
@ -121,21 +122,21 @@ def prepare_stage_input(stage: Stage, platform_name: str, values: dict,
|
||||||
paths = dep_paths.get(take.name)
|
paths = dep_paths.get(take.name)
|
||||||
if paths: # Some takes may be not required
|
if paths: # Some takes may be not required
|
||||||
takes[take.name] = paths
|
takes[take.name] = paths
|
||||||
|
|
||||||
produces = {}
|
produces = {}
|
||||||
for prod in stage.produces:
|
for prod in stage.produces:
|
||||||
if dep_paths.get(prod.name):
|
if dep_paths.get(prod.name):
|
||||||
produces[prod.name] = dep_paths[prod.name]
|
produces[prod.name] = dep_paths[prod.name]
|
||||||
elif config_paths.get(prod.name):
|
elif config_paths.get(prod.name):
|
||||||
produces[prod.name] = config_paths[prod.name]
|
produces[prod.name] = config_paths[prod.name]
|
||||||
|
|
||||||
stage_mod_cfg = {
|
stage_mod_cfg = {
|
||||||
'takes': takes,
|
'takes': takes,
|
||||||
'produces': produces,
|
'produces': produces,
|
||||||
'values': values,
|
'values': values,
|
||||||
'platform': platform_name,
|
'platform': platform_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
return stage_mod_cfg
|
return stage_mod_cfg
|
||||||
|
|
||||||
def update_dep_statuses(paths, consumer: str, symbicache: SymbiCache):
|
def update_dep_statuses(paths, consumer: str, symbicache: SymbiCache):
|
||||||
|
@ -154,7 +155,7 @@ def dep_differ(paths, consumer: str, symbicache: SymbiCache):
|
||||||
Check if a dependency differs from its last version, lack of dependency is
|
Check if a dependency differs from its last version, lack of dependency is
|
||||||
treated as "differs"
|
treated as "differs"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if type(paths) is str:
|
if type(paths) is str:
|
||||||
s = symbicache.get_status(paths, consumer)
|
s = symbicache.get_status(paths, consumer)
|
||||||
if s == 'untracked':
|
if s == 'untracked':
|
||||||
|
@ -198,7 +199,7 @@ class Flow:
|
||||||
|
|
||||||
# Dependendecy to build
|
# Dependendecy to build
|
||||||
target: str
|
target: str
|
||||||
# Values in global scope
|
# Values in global scope
|
||||||
cfg: FlowConfig
|
cfg: FlowConfig
|
||||||
# dependency-producer map
|
# dependency-producer map
|
||||||
os_map: 'dict[str, Stage]'
|
os_map: 'dict[str, Stage]'
|
||||||
|
@ -228,14 +229,14 @@ class Flow:
|
||||||
self.deps_rebuilds = {}
|
self.deps_rebuilds = {}
|
||||||
|
|
||||||
self._resolve_dependencies(self.target, set())
|
self._resolve_dependencies(self.target, set())
|
||||||
|
|
||||||
def _dep_will_differ(self, dep: str, paths, consumer: str):
|
def _dep_will_differ(self, dep: str, paths, consumer: str):
|
||||||
if not self.symbicache: # Handle --nocache mode
|
if not self.symbicache: # Handle --nocache mode
|
||||||
return True
|
return True
|
||||||
return dep_will_differ(dep, paths, consumer,
|
return dep_will_differ(dep, paths, consumer,
|
||||||
self.os_map, self.run_stages,
|
self.os_map, self.run_stages,
|
||||||
self.symbicache)
|
self.symbicache)
|
||||||
|
|
||||||
def _resolve_dependencies(self, dep: str, stages_checked: 'set[str]'):
|
def _resolve_dependencies(self, dep: str, stages_checked: 'set[str]'):
|
||||||
# Initialize the dependency status if necessary
|
# Initialize the dependency status if necessary
|
||||||
if self.deps_rebuilds.get(dep) is None:
|
if self.deps_rebuilds.get(dep) is None:
|
||||||
|
@ -251,7 +252,7 @@ class Flow:
|
||||||
|
|
||||||
# TODO: Check if the dependency is "on-demand" and force it in provider's
|
# TODO: Check if the dependency is "on-demand" and force it in provider's
|
||||||
# config if it is.
|
# config if it is.
|
||||||
|
|
||||||
for take in provider.takes:
|
for take in provider.takes:
|
||||||
self._resolve_dependencies(take.name, stages_checked)
|
self._resolve_dependencies(take.name, stages_checked)
|
||||||
# If any of the required dependencies is unavailable, then the
|
# If any of the required dependencies is unavailable, then the
|
||||||
|
@ -263,17 +264,17 @@ class Flow:
|
||||||
if not take_paths and take.spec == 'req':
|
if not take_paths and take.spec == 'req':
|
||||||
_print_unreachable_stage_message(provider, take)
|
_print_unreachable_stage_message(provider, take)
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._dep_will_differ(take.name, take_paths, provider.name):
|
if self._dep_will_differ(take.name, take_paths, provider.name):
|
||||||
sfprint(2, f'{take.name} is causing rebuild for {provider.name}')
|
sfprint(2, f'{take.name} is causing rebuild for {provider.name}')
|
||||||
self.run_stages.add(provider.name)
|
self.run_stages.add(provider.name)
|
||||||
self.deps_rebuilds[take.name] += 1
|
self.deps_rebuilds[take.name] += 1
|
||||||
|
|
||||||
stage_values = self.cfg.get_r_env(provider.name).values
|
stage_values = self.cfg.get_r_env(provider.name).values
|
||||||
modrunctx = config_mod_runctx(provider, self.cfg.platform,
|
modrunctx = config_mod_runctx(provider, self.cfg.platform,
|
||||||
stage_values, self.dep_paths,
|
stage_values, self.dep_paths,
|
||||||
self.cfg.get_dependency_overrides())
|
self.cfg.get_dependency_overrides())
|
||||||
|
|
||||||
outputs = module_map(provider.module, modrunctx)
|
outputs = module_map(provider.module, modrunctx)
|
||||||
|
|
||||||
stages_checked.add(provider.name)
|
stages_checked.add(provider.name)
|
||||||
|
@ -282,7 +283,7 @@ class Flow:
|
||||||
for _, out_paths in outputs.items():
|
for _, out_paths in outputs.items():
|
||||||
if (out_paths is not None) and not (req_exists(out_paths)):
|
if (out_paths is not None) and not (req_exists(out_paths)):
|
||||||
self.run_stages.add(provider.name)
|
self.run_stages.add(provider.name)
|
||||||
|
|
||||||
# Verify module's outputs and add paths as values.
|
# Verify module's outputs and add paths as values.
|
||||||
outs = outputs.keys()
|
outs = outputs.keys()
|
||||||
# print(outs)
|
# print(outs)
|
||||||
|
@ -303,7 +304,7 @@ class Flow:
|
||||||
provider.value_overrides[dep_value_str(o.name)] = \
|
provider.value_overrides[dep_value_str(o.name)] = \
|
||||||
outputs.get(o.name)
|
outputs.get(o.name)
|
||||||
|
|
||||||
|
|
||||||
def print_resolved_dependencies(self, verbosity: int):
|
def print_resolved_dependencies(self, verbosity: int):
|
||||||
deps = list(self.deps_rebuilds.keys())
|
deps = list(self.deps_rebuilds.keys())
|
||||||
deps.sort()
|
deps.sort()
|
||||||
|
@ -333,7 +334,7 @@ class Flow:
|
||||||
status = Fore.RED + '[U]' + Fore.RESET
|
status = Fore.RED + '[U]' + Fore.RESET
|
||||||
source = \
|
source = \
|
||||||
f'{Fore.BLUE + self.os_map[dep].name + Fore.RESET} -> ???'
|
f'{Fore.BLUE + self.os_map[dep].name + Fore.RESET} -> ???'
|
||||||
|
|
||||||
sfprint(verbosity, f' {Style.BRIGHT + status} '
|
sfprint(verbosity, f' {Style.BRIGHT + status} '
|
||||||
f'{dep + Style.RESET_ALL}: {source}')
|
f'{dep + Style.RESET_ALL}: {source}')
|
||||||
|
|
||||||
|
@ -344,12 +345,12 @@ class Flow:
|
||||||
if not paths:
|
if not paths:
|
||||||
sfprint(2, f'Dependency {dep} is unresolved.')
|
sfprint(2, f'Dependency {dep} is unresolved.')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if req_exists(paths) and not run:
|
if req_exists(paths) and not run:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
assert(provider)
|
assert(provider)
|
||||||
|
|
||||||
any_dep_differ = False if self.symbicache else True
|
any_dep_differ = False if self.symbicache else True
|
||||||
for p_dep in provider.takes:
|
for p_dep in provider.takes:
|
||||||
if not self._build_dep(p_dep.name):
|
if not self._build_dep(p_dep.name):
|
||||||
|
@ -360,7 +361,7 @@ class Flow:
|
||||||
any_dep_differ |= \
|
any_dep_differ |= \
|
||||||
update_dep_statuses(self.dep_paths[p_dep.name],
|
update_dep_statuses(self.dep_paths[p_dep.name],
|
||||||
provider.name, self.symbicache)
|
provider.name, self.symbicache)
|
||||||
|
|
||||||
# If dependencies remained the same, consider the dep as up-to date
|
# If dependencies remained the same, consider the dep as up-to date
|
||||||
# For example, when changing a comment in Verilog source code,
|
# For example, when changing a comment in Verilog source code,
|
||||||
# the initial dependency resolution will report a need for complete
|
# the initial dependency resolution will report a need for complete
|
||||||
|
@ -372,7 +373,7 @@ class Flow:
|
||||||
f'{Style.BRIGHT + dep + Style.RESET_ALL}` because all '
|
f'{Style.BRIGHT + dep + Style.RESET_ALL}` because all '
|
||||||
f'of it\'s dependencies remained unchanged')
|
f'of it\'s dependencies remained unchanged')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
stage_values = self.cfg.get_r_env(provider.name).values
|
stage_values = self.cfg.get_r_env(provider.name).values
|
||||||
modrunctx = config_mod_runctx(provider, self.cfg.platform,
|
modrunctx = config_mod_runctx(provider, self.cfg.platform,
|
||||||
stage_values, self.dep_paths,
|
stage_values, self.dep_paths,
|
||||||
|
@ -380,12 +381,12 @@ class Flow:
|
||||||
module_exec(provider.module, modrunctx)
|
module_exec(provider.module, modrunctx)
|
||||||
|
|
||||||
self.run_stages.discard(provider.name)
|
self.run_stages.discard(provider.name)
|
||||||
|
|
||||||
if not req_exists(paths):
|
if not req_exists(paths):
|
||||||
raise DependencyNotProducedException(dep, provider.name)
|
raise DependencyNotProducedException(dep, provider.name)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self._build_dep(self.target)
|
self._build_dep(self.target)
|
||||||
if self.symbicache:
|
if self.symbicache:
|
||||||
|
@ -402,7 +403,7 @@ def display_dep_info(stages: 'Iterable[Stage]'):
|
||||||
l = len(out.name)
|
l = len(out.name)
|
||||||
if l > longest_out_name_len:
|
if l > longest_out_name_len:
|
||||||
longest_out_name_len = l
|
longest_out_name_len = l
|
||||||
|
|
||||||
desc_indent = longest_out_name_len + 7
|
desc_indent = longest_out_name_len + 7
|
||||||
nl_indentstr = '\n'
|
nl_indentstr = '\n'
|
||||||
for _ in range(0, desc_indent):
|
for _ in range(0, desc_indent):
|
||||||
|
@ -418,9 +419,9 @@ def display_dep_info(stages: 'Iterable[Stage]'):
|
||||||
if out.spec == 'req':
|
if out.spec == 'req':
|
||||||
specstr = f'{Fore.BLUE}guaranteed{Fore.RESET}'
|
specstr = f'{Fore.BLUE}guaranteed{Fore.RESET}'
|
||||||
elif out.spec == 'maybe':
|
elif out.spec == 'maybe':
|
||||||
specstr = f'{Fore.YELLOW}not guaranteed{Fore.RESET}'
|
specstr = f'{Fore.YELLOW}not guaranteed{Fore.RESET}'
|
||||||
elif out.spec == 'demand':
|
elif out.spec == 'demand':
|
||||||
specstr = f'{Fore.RED}on-demand{Fore.RESET}'
|
specstr = f'{Fore.RED}on-demand{Fore.RESET}'
|
||||||
pgen = f'{Style.DIM}stage: `{stage.name}`, '\
|
pgen = f'{Style.DIM}stage: `{stage.name}`, '\
|
||||||
f'spec: {specstr}{Style.RESET_ALL}'
|
f'spec: {specstr}{Style.RESET_ALL}'
|
||||||
pdesc = stage.meta[out.name].replace('\n', nl_indentstr)
|
pdesc = stage.meta[out.name].replace('\n', nl_indentstr)
|
||||||
|
@ -432,7 +433,7 @@ def display_stage_info(stage: Stage):
|
||||||
sfprint(0, f'Stage does not exist')
|
sfprint(0, f'Stage does not exist')
|
||||||
sfbuild_fail()
|
sfbuild_fail()
|
||||||
return
|
return
|
||||||
|
|
||||||
sfprint(0, f'Stage `{Style.BRIGHT}{stage.name}{Style.RESET_ALL}`:')
|
sfprint(0, f'Stage `{Style.BRIGHT}{stage.name}{Style.RESET_ALL}`:')
|
||||||
sfprint(0, f' Module: `{Style.BRIGHT}{stage.module.name}{Style.RESET_ALL}`')
|
sfprint(0, f' Module: `{Style.BRIGHT}{stage.module.name}{Style.RESET_ALL}`')
|
||||||
sfprint(0, f' Module info:')
|
sfprint(0, f' Module info:')
|
||||||
|
@ -481,13 +482,13 @@ def verify_platform_stage_params(flow_cfg: FlowConfig,
|
||||||
if args.platform not in flow_cfg.platforms():
|
if args.platform not in flow_cfg.platforms():
|
||||||
sfprint(0, f'Platform `{platform}`` is not in project.')
|
sfprint(0, f'Platform `{platform}`` is not in project.')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if stage:
|
if stage:
|
||||||
if not verify_stage(platform, stage, mypath):
|
if not verify_stage(platform, stage, mypath):
|
||||||
sfprint(0, f'Stage `{stage}` is invalid.')
|
sfprint(0, f'Stage `{stage}` is invalid.')
|
||||||
sfbuild_fail()
|
sfbuild_fail()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_platform_name_for_part(part_name: str):
|
def get_platform_name_for_part(part_name: str):
|
||||||
|
@ -506,7 +507,7 @@ def cmd_build(args: Namespace):
|
||||||
""" sfbuild's `build` command implementation """
|
""" sfbuild's `build` command implementation """
|
||||||
|
|
||||||
project_flow_cfg: ProjectFlowConfig = None
|
project_flow_cfg: ProjectFlowConfig = None
|
||||||
|
|
||||||
|
|
||||||
platform = args.platform
|
platform = args.platform
|
||||||
if platform is None:
|
if platform is None:
|
||||||
|
@ -596,7 +597,7 @@ def cmd_show_dependencies(args: Namespace):
|
||||||
if not verify_platform_stage_params(flow_cfg, args.platform):
|
if not verify_platform_stage_params(flow_cfg, args.platform):
|
||||||
sfbuild_fail()
|
sfbuild_fail()
|
||||||
return
|
return
|
||||||
|
|
||||||
platform_overrides: 'set | None' = None
|
platform_overrides: 'set | None' = None
|
||||||
if args.platform is not None:
|
if args.platform is not None:
|
||||||
platform_overrides = \
|
platform_overrides = \
|
||||||
|
@ -613,14 +614,14 @@ def cmd_show_dependencies(args: Namespace):
|
||||||
f'{Style.BRIGHT + dep_name + Style.RESET_ALL}: {dep_paths}'
|
f'{Style.BRIGHT + dep_name + Style.RESET_ALL}: {dep_paths}'
|
||||||
else:
|
else:
|
||||||
prstr = f'{Style.BRIGHT + dep_name + Style.RESET_ALL}: {dep_paths}'
|
prstr = f'{Style.BRIGHT + dep_name + Style.RESET_ALL}: {dep_paths}'
|
||||||
|
|
||||||
display_list.append((dep_name, prstr))
|
display_list.append((dep_name, prstr))
|
||||||
|
|
||||||
display_list.sort(key = lambda p: p[0])
|
display_list.sort(key = lambda p: p[0])
|
||||||
|
|
||||||
for _, prstr in display_list:
|
for _, prstr in display_list:
|
||||||
sfprint(0, prstr)
|
sfprint(0, prstr)
|
||||||
|
|
||||||
set_verbosity_level(-1)
|
set_verbosity_level(-1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in New Issue