pw_build: Handle Windows artifacts in python_runner.py

Also add .dylib for Mach-O shared libraries.

Change-Id: I3f809603a929844c75ead897c2bcca537a2bf72d
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/38680
Commit-Queue: Wyatt Hepler <hepler@google.com>
Reviewed-by: Armando Montanez <amontanez@google.com>
diff --git a/pw_build/py/pw_build/python_runner.py b/pw_build/py/pw_build/python_runner.py
index 7210757..b719650 100755
--- a/pw_build/py/pw_build/python_runner.py
+++ b/pw_build/py/pw_build/python_runner.py
@@ -160,7 +160,8 @@
 # Matches a non-phony build statement.
 _GN_NINJA_BUILD_STATEMENT = re.compile(r'^build (.+):[ \n](?!phony\b)')
 
-_MAIN_ARTIFACTS = '', '.elf', '.a', '.so'
+# Extensions used for compilation artifacts.
+_MAIN_ARTIFACTS = '', '.elf', '.a', '.so', '.dylib', '.exe', '.lib', '.dll'
 
 
 def _get_artifact(build_dir: Path, entries: List[str]) -> _Artifact:
@@ -171,14 +172,16 @@
     """
     assert entries, "There should be at least one entry here!"
 
-    if len(entries) != 1:
-        entries = [p for p in entries if Path(p).suffix in _MAIN_ARTIFACTS]
-
     if len(entries) == 1:
         return _Artifact(build_dir / entries[0], {})
 
+    filtered = [p for p in entries if Path(p).suffix in _MAIN_ARTIFACTS]
+
+    if len(filtered) == 1:
+        return _Artifact(build_dir / filtered[0], {})
+
     raise ExpressionError(
-        f'Expected 1, but found {len(entries)} artifacts, after filtering for '
+        f'Expected 1, but found {len(filtered)} artifacts, after filtering for '
         f'extensions {", ".join(repr(e) for e in _MAIN_ARTIFACTS)}: {entries}')