build.run: add env= argument to BuildPlan.execute_local().

Build scripts are explicitly intended to have overrides that are
done through the use of environment variables, and right now this
would require a very awkward `run_script=False` invocation followed
by copying a bit of code out of the Amaranth codebase, which is
clearly suboptimal.
This commit is contained in:
Catherine 2023-07-23 03:42:03 +00:00
parent a6d67f7477
commit a921261215
2 changed files with 11 additions and 4 deletions

View file

@ -61,12 +61,13 @@ class BuildPlan:
for filename in sorted(self.files): for filename in sorted(self.files):
archive.writestr(zipfile.ZipInfo(filename), self.files[filename]) archive.writestr(zipfile.ZipInfo(filename), self.files[filename])
def execute_local(self, root="build", *, run_script=True): def execute_local(self, root="build", *, run_script=True, env=None):
""" """
Execute build plan using the local strategy. Files from the build plan are placed in Execute build plan using the local strategy. Files from the build plan are placed in
the build root directory ``root``, and, if ``run_script`` is ``True``, the script the build root directory ``root``, and, if ``run_script`` is ``True``, the script
appropriate for the platform (``{script}.bat`` on Windows, ``{script}.sh`` elsewhere) is appropriate for the platform (``{script}.bat`` on Windows, ``{script}.sh`` elsewhere) is
executed in the build root. executed in the build root. If ``env`` is not ``None``, the environment is extended
(not replaced) with ``env``.
Returns :class:`LocalBuildProducts`. Returns :class:`LocalBuildProducts`.
""" """
@ -90,13 +91,18 @@ class BuildPlan:
f.write(content) f.write(content)
if run_script: if run_script:
script_env = dict(os.environ)
if env is not None:
script_env.update(env)
if sys.platform.startswith("win32"): if sys.platform.startswith("win32"):
# Without "call", "cmd /c {}.bat" will return 0. # Without "call", "cmd /c {}.bat" will return 0.
# See https://stackoverflow.com/a/30736987 for a detailed explanation of why. # See https://stackoverflow.com/a/30736987 for a detailed explanation of why.
# Running the script manually from a command prompt is unaffected. # Running the script manually from a command prompt is unaffected.
subprocess.check_call(["cmd", "/c", "call {}.bat".format(self.script)]) subprocess.check_call(["cmd", "/c", "call {}.bat".format(self.script)],
env=script_env)
else: else:
subprocess.check_call(["sh", "{}.sh".format(self.script)]) subprocess.check_call(["sh", "{}.sh".format(self.script)],
env=script_env)
return LocalBuildProducts(os.getcwd()) return LocalBuildProducts(os.getcwd())

View file

@ -95,6 +95,7 @@ Toolchain changes
* Changed: text files are written with LF line endings on Windows, like on other platforms. * Changed: text files are written with LF line endings on Windows, like on other platforms.
* Added: ``debug_verilog`` override in :class:`build.TemplatedPlatform`. * Added: ``debug_verilog`` override in :class:`build.TemplatedPlatform`.
* Added: ``env=`` argument to :meth:`build.run.BuildPlan.execute_local`.
* Deprecated: use of mixed-case toolchain environment variable names, such as ``NMIGEN_ENV_Diamond`` or ``AMARANTH_ENV_Diamond``; use upper-case environment variable names, such as ``AMARANTH_ENV_DIAMOND``. * Deprecated: use of mixed-case toolchain environment variable names, such as ``NMIGEN_ENV_Diamond`` or ``AMARANTH_ENV_Diamond``; use upper-case environment variable names, such as ``AMARANTH_ENV_DIAMOND``.
* Removed: (deprecated in 0.3) :meth:`sim.Simulator.step`. * Removed: (deprecated in 0.3) :meth:`sim.Simulator.step`.
* Removed: (deprecated in 0.3) :mod:`back.pysim`. * Removed: (deprecated in 0.3) :mod:`back.pysim`.