From d4470fe653356d9869be4507a7748c04f987654a Mon Sep 17 00:00:00 2001 From: Scott McKay Date: Mon, 17 Jun 2024 09:24:43 +1000 Subject: [PATCH] Update Android SDK tools path lookup to be more strongly anchored to the provided root. (#21046) ### Description The tools should really all come from the same Android NDK, so using `shutil.which` adds potential confusion when we do a lookup for the target program by name first due to adding `dirnames.insert(0, "")` as the first directory entry to lookup as it will match the filename anywhere in the current path. That's problematic as the emulator should come from /emulator/emulator (see [here](https://www.stkent.com/2017/08/10/update-your-path-for-the-new-android-emulator-location.html)), but the paths on the CI machines result in the old location of /tools/emulator being selected. This leads to the emulator failing to run on arm64 macOS CIs as the old emulator does not look for the arm64 binary. At the most you may have multiple cmdline-tools versions installed, but if we need to support explicitly specifying a version for that path that can be added. ### Motivation and Context Make emulator run on arm64 macOS machines. --- tools/python/util/android/android.py | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/tools/python/util/android/android.py b/tools/python/util/android/android.py index 47e251d11a..fd25d8bc14 100644 --- a/tools/python/util/android/android.py +++ b/tools/python/util/android/android.py @@ -4,12 +4,11 @@ import collections import contextlib import datetime -import os -import shutil import signal import subprocess import time import typing +from pathlib import Path from ..logger import get_logger from ..platform_helpers import is_linux, is_windows @@ -28,26 +27,17 @@ def get_sdk_tool_paths(sdk_root: str): else: return name - def resolve_path(dirnames, basename): - dirnames.insert(0, "") - for dirname in dirnames: - path = shutil.which(os.path.join(os.path.expanduser(dirname), basename)) - if path is not None: - path = os.path.realpath(path) - _log.debug(f"Found {basename} at {path}") - return path - raise FileNotFoundError(f"Failed to resolve path for {basename}") + sdk_root = Path(sdk_root).resolve(strict=True) return SdkToolPaths( - emulator=resolve_path([os.path.join(sdk_root, "emulator")], filename("emulator", "exe")), - adb=resolve_path([os.path.join(sdk_root, "platform-tools")], filename("adb", "exe")), - sdkmanager=resolve_path( - [os.path.join(sdk_root, "cmdline-tools", "latest", "bin")], - filename("sdkmanager", "bat"), + # do not use sdk_root/tools/emulator as that is superceeded by sdk_root/emulator/emulator + emulator=str((sdk_root / "emulator" / filename("emulator", "exe")).resolve(strict=True)), + adb=str((sdk_root / "platform-tools" / filename("adb", "exe")).resolve(strict=True)), + sdkmanager=str( + (sdk_root / "cmdline-tools" / "latest" / "bin" / filename("sdkmanager", "bat")).resolve(strict=True) ), - avdmanager=resolve_path( - [os.path.join(sdk_root, "cmdline-tools", "latest", "bin")], - filename("avdmanager", "bat"), + avdmanager=str( + (sdk_root / "cmdline-tools" / "latest" / "bin" / filename("avdmanager", "bat")).resolve(strict=True) ), )