scripts: runners: error on missing non-elf outputs

The RunnerConfig class stores the locations of the Zephyr output files
in various formats (elf, hex, bin). A longstanding issue with the
representation is that these might not exist if the corresponding
Kconfig options are not set. For example, if
CONFIG_BUILD_OUTPUT_BIN=n, there is no .bin file.

Change this so the type system knows these are Optional[str], not str.

Fix the runners that use non-ELF outputs so they check for the
existence of the relevant file before using it, mostly using a new
ZephyrBinaryRunner.ensure_output helper.

I'm not going to bother with checking for the ELF file itself; that's
always there as far as I can tell.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
diff --git a/scripts/west_commands/run_common.py b/scripts/west_commands/run_common.py
index 3025b16..d614c1c 100644
--- a/scripts/west_commands/run_common.py
+++ b/scripts/west_commands/run_common.py
@@ -346,9 +346,7 @@
             # directory containing the runners.yaml file.
             return fspath(yaml_dir / from_yaml)
 
-        # FIXME these RunnerConfig values really ought to be
-        # Optional[str], but some runners rely on them being str.
-        return ''
+        return None
 
     def config(attr):
         return getattr(args, attr, None) or yaml_config.get(attr)