Update Android SDK tools path lookup to be more strongly anchored to the provided root. (#21046)

### Description
<!-- Describe your changes. -->
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
<sdk_tools>/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
<sdk_tools>/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
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->
Make emulator run on arm64 macOS machines.
This commit is contained in:
Scott McKay 2024-06-17 09:24:43 +10:00 committed by GitHub
parent f25cf19375
commit d4470fe653
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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)
),
)