Now environment variable overrides no longer infect the build scripts.
_toolchain.overrides is dropped as probably misguided in the first place.
Fixes #251.
import shutil
-__all__ = ["ToolNotFound", "get_tool", "has_tool", "require_tool"]
+__all__ = ["ToolNotFound", "tool_env_var", "has_tool", "require_tool"]
class ToolNotFound(Exception):
pass
-def _tool_env_var(name):
+def tool_env_var(name):
return name.upper().replace("-", "_")
-def get_tool(name):
- return os.environ.get(_tool_env_var(name), overrides.get(name, name))
+def _get_tool(name):
+ return os.environ.get(tool_env_var(name), name)
def has_tool(name):
- return shutil.which(get_tool(name)) is not None
+ return shutil.which(_get_tool(name)) is not None
def require_tool(name):
- env_var = _tool_env_var(name)
- path = get_tool(name)
+ env_var = tool_env_var(name)
+ path = _get_tool(name)
if shutil.which(path) is None:
- if path == name:
+ if env_var in os.environ:
+ raise ToolNotFound("Could not find required tool {} in {} as "
+ "specified via the {} environment variable".
+ format(name, path, env_var))
+ else:
raise ToolNotFound("Could not find required tool {} in PATH. Place "
"it directly in PATH or specify path explicitly "
"via the {} environment variable".
format(name, env_var))
- else:
- if os.getenv(env_var):
- via = "the {} environment variable".format(env_var)
- else:
- via = "your packager's toolchain overrides. This is either an " \
- "nMigen bug or a packaging error"
- raise ToolNotFound("Could not find required tool {} in {} as "
- "specified via {}".format(name, path, via))
return path
-
-
-# Packages for systems like Nix can inject full paths to certain tools by adding them in
-# this dictionary, e.g. ``overrides = {"yosys": "/full/path/to/yosys"}``.
-overrides = {}
# {{autogenerated}}
set -e{{verbose("x")}}
[ -n "${{platform._toolchain_env_var}}" ] && . "${{platform._toolchain_env_var}}"
+ {{emit_prelude("sh")}}
{{emit_commands("sh")}}
""",
"build_{{name}}.bat": """
@rem {{autogenerated}}
{{quiet("@echo off")}}
if defined {{platform._toolchain_env_var}} call %{{platform._toolchain_env_var}}%
+ {{emit_prelude("bat")}}
{{emit_commands("bat")}}
""",
}
return verilog._convert_rtlil_text(rtlil_text,
strip_internal_attrs=False, write_verilog_opts=opts)
- def emit_commands(format):
+ def emit_prelude(syntax):
+ commands = []
+ for name in self.required_tools:
+ env_var = tool_env_var(name)
+ if syntax == "sh":
+ template = ": ${{{env_var}:={name}}}"
+ elif syntax == "bat":
+ template = \
+ "if [%{env_var}%] eq [\"\"] set {env_var}=\n" \
+ "if [%{env_var}%] eq [] set {env_var}={name}"
+ else:
+ assert False
+ commands.append(template.format(env_var=env_var, name=name))
+ return "\n".join(commands)
+
+ def emit_commands(syntax):
commands = []
for index, command_tpl in enumerate(self.command_templates):
- command = render(command_tpl, origin="<command#{}>".format(index + 1))
+ command = render(command_tpl, origin="<command#{}>".format(index + 1),
+ syntax=syntax)
command = re.sub(r"\s+", " ", command)
- if format == "sh":
+ if syntax == "sh":
commands.append(command)
- elif format == "bat":
+ elif syntax == "bat":
commands.append(command + " || exit /b")
else:
assert False
else:
return jinja2.Undefined(name=var)
+ @jinja2.contextfunction
+ def invoke_tool(context, name):
+ env_var = tool_env_var(name)
+ if context.parent["syntax"] == "sh":
+ return "\"${}\"".format(env_var)
+ elif context.parent["syntax"] == "bat":
+ return "%{}%".format(env_var)
+ else:
+ assert False
+
def options(opts):
if isinstance(opts, str):
return opts
else:
return arg
- def render(source, origin):
+ def render(source, origin, syntax=None):
try:
source = textwrap.dedent(source).strip()
compiled = jinja2.Template(source, trim_blocks=True, lstrip_blocks=True)
"emit_rtlil": emit_rtlil,
"emit_verilog": emit_verilog,
"emit_debug_verilog": emit_debug_verilog,
+ "emit_prelude": emit_prelude,
"emit_commands": emit_commands,
- "get_tool": get_tool,
+ "syntax": syntax,
+ "invoke_tool": invoke_tool,
"get_override": get_override,
"verbose": verbose,
"quiet": quiet,
}
command_templates = [
r"""
- {{get_tool("quartus_map")}}
+ {{invoke_tool("quartus_map")}}
{{get_override("quartus_map_opts")|options}}
--rev={{name}} {{name}}
""",
r"""
- {{get_tool("quartus_fit")}}
+ {{invoke_tool("quartus_fit")}}
{{get_override("quartus_fit_opts")|options}}
--rev={{name}} {{name}}
""",
r"""
- {{get_tool("quartus_asm")}}
+ {{invoke_tool("quartus_asm")}}
{{get_override("quartus_asm_opts")|options}}
--rev={{name}} {{name}}
""",
r"""
- {{get_tool("quartus_sta")}}
+ {{invoke_tool("quartus_sta")}}
{{get_override("quartus_sta_opts")|options}}
--rev={{name}} {{name}}
""",
}
_trellis_command_templates = [
r"""
- {{get_tool("yosys")}}
+ {{invoke_tool("yosys")}}
{{quiet("-q")}}
{{get_override("yosys_opts")|options}}
-l {{name}}.rpt
{{name}}.ys
""",
r"""
- {{get_tool("nextpnr-ecp5")}}
+ {{invoke_tool("nextpnr-ecp5")}}
{{quiet("--quiet")}}
{{get_override("nextpnr_opts")|options}}
--log {{name}}.tim
--textcfg {{name}}.config
""",
r"""
- {{get_tool("ecppack")}}
+ {{invoke_tool("ecppack")}}
{{verbose("--verbose")}}
{{get_override("ecppack_opts")|options}}
--input {{name}}.config
_diamond_command_templates = [
# These don't have any usable command-line option overrides.
r"""
- {{get_tool("pnmainc")}}
+ {{invoke_tool("pnmainc")}}
{{name}}.tcl
""",
r"""
- {{get_tool("ddtcmd")}}
+ {{invoke_tool("ddtcmd")}}
-oft -bit
-if {{name}}_impl/{{name}}_impl.bit -of {{name}}.bit
""",
r"""
- {{get_tool("ddtcmd")}}
+ {{invoke_tool("ddtcmd")}}
-oft -svfsingle -revd -op "Fast Program"
-if {{name}}_impl/{{name}}_impl.bit -of {{name}}.svf
""",
}
_icestorm_command_templates = [
r"""
- {{get_tool("yosys")}}
+ {{invoke_tool("yosys")}}
{{quiet("-q")}}
{{get_override("yosys_opts")|options}}
-l {{name}}.rpt
{{name}}.ys
""",
r"""
- {{get_tool("nextpnr-ice40")}}
+ {{invoke_tool("nextpnr-ice40")}}
{{quiet("--quiet")}}
{{get_override("nextpnr_opts")|options}}
--log {{name}}.tim
--asc {{name}}.asc
""",
r"""
- {{get_tool("icepack")}}
+ {{invoke_tool("icepack")}}
{{verbose("-v")}}
{{name}}.asc
{{name}}.bin
command_templates = [
# These don't have any usable command-line option overrides.
r"""
- {{get_tool("pnmainc")}}
+ {{invoke_tool("pnmainc")}}
{{name}}.tcl
""",
r"""
- {{get_tool("ddtcmd")}}
+ {{invoke_tool("ddtcmd")}}
-oft -jed
-dev {{platform.device}}-{{platform.speed}}{{platform.package}}{{platform.grade}}
-if {{name}}_impl/{{name}}_impl.jed -of {{name}}.jed
""",
r"""
- {{get_tool("ddtcmd")}}
+ {{invoke_tool("ddtcmd")}}
-oft -svfsingle -revd -op "FLASH Erase,Program,Verify"
-if {{name}}_impl/{{name}}_impl.jed -of {{name}}.svf
""",
}
command_templates = [
r"""
- {{get_tool("vivado")}}
+ {{invoke_tool("vivado")}}
{{verbose("-verbose")}}
{{get_override("vivado_opts")|options}}
-mode batch
}
command_templates = [
r"""
- {{get_tool("xst")}}
+ {{invoke_tool("xst")}}
{{get_override("xst_opts")|options}}
-ifn {{name}}.xst
""",
r"""
- {{get_tool("ngdbuild")}}
+ {{invoke_tool("ngdbuild")}}
{{quiet("-quiet")}}
{{verbose("-verbose")}}
{{get_override("ngdbuild_opts")|options}}
{{name}}.ngc
""",
r"""
- {{get_tool("map")}}
+ {{invoke_tool("map")}}
{{verbose("-detail")}}
{{get_override("map_opts")|default([])|options}}
-w
{{name}}.pcf
""",
r"""
- {{get_tool("par")}}
+ {{invoke_tool("par")}}
{{get_override("par_opts")|default([])|options}}
-w
{{name}}_map.ncd
{{name}}.pcf
""",
r"""
- {{get_tool("bitgen")}}
+ {{invoke_tool("bitgen")}}
{{get_override("bitgen_opts")|default(["-g Compress"])|options}}
-w
-g Binary:Yes
}
command_templates = [
r"""
- {{get_tool("vivado")}}
+ {{invoke_tool("vivado")}}
{{verbose("-verbose")}}
{{get_override("vivado_opts")|options}}
-mode batch