@@ -116,6 +116,14 @@ Arbitrary extra arguments that are passed directly to the FVP. For example:
FVP_EXTRA_ARGS = "--simlimit 60"
```
+### `FVP_ENV_PASSTHROUGH`
+
+The FVP is launched with an isolated set of environment variables. Add the name of a Bitbake variable to this list to pass it through to the FVP environment. For example:
+
+```
+FVP_ENV_PASSTHROUGH = "ARMLMD_LICENSE_FILE FM_TRACE_PLUGINS"
+```
+
[AEM]: https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models
[FVP]: https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms
@@ -23,6 +23,8 @@ FVP_CONSOLE ?= ""
FVP_CONSOLES[default] ?= "${FVP_CONSOLE}"
# Arbitrary extra arguments
FVP_EXTRA_ARGS ?= ""
+# Bitbake variables to pass to the FVP environment
+FVP_ENV_PASSTHROUGH ?= ""
EXTRA_IMAGEDEPENDS += "${FVP_PROVIDER}"
@@ -66,6 +68,10 @@ python do_write_fvpboot_conf() {
data["terminals"] = getFlags("FVP_TERMINALS")
data["args"] = shlex.split(d.getVar("FVP_EXTRA_ARGS") or "")
+ data["env"] = {}
+ for var in d.getVar("FVP_ENV_PASSTHROUGH").split():
+ data["env"][var] = d.getVar(var)
+
os.makedirs(os.path.dirname(conffile), exist_ok=True)
with open(conffile, "wt") as f:
json.dump(data, f)
@@ -51,6 +51,7 @@ def load(config_file):
sanitise("terminals", {})
sanitise("args", [])
sanitise("consoles", {})
+ sanitise("env", {})
if not config["exe"]:
raise ValueError("Required value FVP_EXE not set in machine configuration")
@@ -60,7 +60,10 @@ class FVPRunner:
cli = cli_from_config(config, terminal_choice)
cli += extra_args
self._logger.debug(f"Constructed FVP call: {cli}")
- self._fvp_process = await asyncio.create_subprocess_exec(*cli, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ self._fvp_process = await asyncio.create_subprocess_exec(
+ *cli,
+ stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+ env=config['env'])
def detect_terminals(line):
m = re.match(r"^(\S+): Listening for serial connection on port (\d+)$", line)
@@ -20,11 +20,10 @@ class RunFVPTests(OESelftestTestCase):
on exit code 0 or fail the test, otherwise return the CompletedProcess
instance.
"""
- # Put the test directory in PATH so that any mock FVPs are found first
- newenv = {"PATH": str(testdir) + ":" + os.environ["PATH"]}
cli = [runfvp,] + list(args)
print(f"Calling {cli}")
- ret = subprocess.run(cli, env=newenv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
+ # Set cwd to testdir so that any mock FVPs are found
+ ret = subprocess.run(cli, cwd=testdir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
if should_succeed:
self.assertEqual(ret.returncode, 0, f"runfvp exit {ret.returncode}, output: {ret.stdout}")
return ret.stdout
@@ -40,8 +39,6 @@ class RunFVPTests(OESelftestTestCase):
self.run_fvp("--this-is-an-invalid-option", should_succeed=False)
def test_run_auto_tests(self):
- newenv = {"PATH": str(testdir) + ":" + os.environ["PATH"]}
-
cases = list(testdir.glob("auto-*.json"))
if not cases:
self.fail("No tests found")
@@ -79,6 +76,7 @@ class ConfFileTests(OESelftestTestCase):
self.assertTrue("terminals" in conf)
self.assertTrue("args" in conf)
self.assertTrue("consoles" in conf)
+ self.assertTrue("env" in conf)
class RunnerTests(OESelftestTestCase):
@@ -97,6 +95,7 @@ class RunnerTests(OESelftestTestCase):
"applications": {'a1': 'file'},
"terminals": {},
"args": ['--extra-arg'],
+ "env": {"FOO": "BAR"}
}))
m.assert_called_once_with('/usr/bin/FVP_Binary',
@@ -106,4 +105,5 @@ class RunnerTests(OESelftestTestCase):
'--extra-arg',
stdin=unittest.mock.ANY,
stdout=unittest.mock.ANY,
- stderr=unittest.mock.ANY)
+ stderr=unittest.mock.ANY,
+ env={"FOO":"BAR"})
@@ -1,3 +1,4 @@
{
+ "fvp-bindir": ".",
"exe": "auto-basic.sh"
}
@@ -1,4 +1,5 @@
{
+ "fvp-bindir": ".",
"exe": "test-parameters.py",
"parameters": {
"board.cow": "moo",
@@ -1,4 +1,5 @@
{
+ "fvp-bindir": ".",
"exe": "test-parameters.py",
"parameters": {
"board.cow": "moo"