From e296187fa1fc597a7ac904f2ef77163132c61a1e Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Sat, 12 Jun 2021 12:10:50 -0500 Subject: [PATCH] more tools consolidation --- .efrocachemap | 36 +++---- src/ballistica/ballistica.cc | 2 +- tools/batools/android.py | 7 +- tools/batools/androidsdkutils.py | 164 +++++++++++++++++++++++++++++++ tools/batools/pcommand.py | 6 ++ tools/efrotools/pybuild.py | 2 +- tools/pcommand | 3 +- 7 files changed, 195 insertions(+), 25 deletions(-) create mode 100755 tools/batools/androidsdkutils.py diff --git a/.efrocachemap b/.efrocachemap index d03e3b1c..bc92d8a8 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -3933,26 +3933,26 @@ "assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e", "assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f", "ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a", - "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/16/1e/da5d1a1c78606accf3c4439338ad", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/3c/8c/082b6542e5e364534b7d941c9382", "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/74/1d/fc9e33e565475daaac80da5252f0", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/14/e7/3bdf7ab648128852e274b7bea0c6", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f3/a9/653c04b445c010dab03ab20cbb66", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d2/7b/5483d27ccb29d9e0c96652242c40", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/68/3e/0161f1e73c492f8189d87ca81f25", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c8/46/b7a92dafc732fefdefe65291db51", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a5/28/b88ab33d7b3a785057366b70a83f", "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/7b/ac1a200be0f37078af0991faca3b", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a3/06/627d11dcc80f829ea784f20967ba", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a5/22/469309e4c387e0e03e3c22a23bca", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/14/74/db5af0a68b77d99668dd19a0dbf0", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e4/1c/fbfd48da2029a8fbbf9089a7602c", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ab/68/0c3ddedc76ac4b22c5ef8a120fb9", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a9/8f/87f6795a951c3d659fbeb7e3894b", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/1e/84/dde3f07fc30f810b304dc1326dc7", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/89/d9/81113dc9a0989e06e7d11ee83e84", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ac/47/05be30983f510cdbe078b594be38", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f9/ea/8a9378ce519e466e9c478b07c116", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/62/5d/2e758624968b13f53c006fcaab5a", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/58/00/038c9a4d0cf2de4ee5358e0dad24", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/83/52/9e8381520466236ea823faf5e1ec", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/1e/48/3c42aa5f72286b00c8dc42f801a9", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e1/d8/e770a482c7ff49b8393a4c9b861c", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/14/58/911b39895f68f3f68718f15e4139", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a4/3b/ee0681829ed307717733bae23fc4", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/cb/95/512b448ec0448d911033f42ebec2", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/55/23/5cd0b9053565ff443054851290b2", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d5/72/31eb80eabf7f35bd8805fb37fcd4", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/45/06/9c55ae67557837c5dbfb775d547c", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/22/e8/8e560c68834433a53a3d1217755b", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a2/00/9cda774f393b0e6115adb3f70698", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c5/85/a4ea385bf200f61e2eaf1426fb09", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/77/ee/8aa64af1334e71b033f9f61a6e54", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/20/7f/2609ccbfcd3e461107b161d1010b", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/14/66/99d5e27941acb69f1400bd71f78f", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/7f/0c/d55e96dec8be029a21eabaf5880c", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/17/8a/3e4eec6be82a7d51ec68c2cd9134", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/18/27/4063e018845b61a43d3fb975dda9", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/94/8e/b57d1b16f9a97ae6b75f6aa64d24", diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index c9b23b50..1ff47f62 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -21,7 +21,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20378; +const int kAppBuildNumber = 20379; const char* kAppVersion = "1.6.4"; // Our standalone globals. diff --git a/tools/batools/android.py b/tools/batools/android.py index d286456b..e7d640fa 100644 --- a/tools/batools/android.py +++ b/tools/batools/android.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3.8 # Released under the MIT License. See LICENSE for details. # """Functionality related to android builds.""" @@ -45,10 +44,10 @@ def androidaddr(archive_dir: str, arch: str, addr: str) -> None: print('ERROR: invalid arch "' + arch + '"; (choices are ' + ', '.join(archs.keys()) + ')') sys.exit(255) - sdkutils = 'tools/android_sdk_utils' rootdir = '.' - ndkpath = subprocess.check_output([sdkutils, - 'get-ndk-path']).decode().strip() + ndkpath = subprocess.check_output( + ['tools/pcommand', 'android_sdk_utils', + 'get-ndk-path']).decode().strip() if not os.path.isdir(ndkpath): print("ERROR: ndk-path '" + ndkpath + '" does not exist') sys.exit(255) diff --git a/tools/batools/androidsdkutils.py b/tools/batools/androidsdkutils.py new file mode 100755 index 00000000..9072103c --- /dev/null +++ b/tools/batools/androidsdkutils.py @@ -0,0 +1,164 @@ +# Released under the MIT License. See LICENSE for details. +# +"""Utilities for wrangling Android SDK bits.""" +from __future__ import annotations + +import os +import sys +from pathlib import Path +from typing import TYPE_CHECKING + +from efro.error import CleanError + +if TYPE_CHECKING: + from typing import List + +PROJROOT = Path(__file__).resolve().parents[1] + + +def _parse_lprop_file(local_properties_path: str) -> str: + with open(local_properties_path) as infile: + lines = infile.read().splitlines() + sdk_dir_lines = [l for l in lines if 'sdk.dir=' in l] + if len(sdk_dir_lines) != 1: + raise Exception("Couldn't find sdk dir in local.properties") + sdk_dir = sdk_dir_lines[0].split('=')[1].strip() + if not os.path.isdir(sdk_dir): + raise Exception(f'Sdk dir from local.properties not found: {sdk_dir}.') + return sdk_dir + + +def _gen_lprop_file(local_properties_path: str) -> str: + + os.makedirs(os.path.dirname(local_properties_path), exist_ok=True) + + # Ok, we've got no local.properties file; attempt to find + # android sdk in standard locations and create a default + # one if we can. + found = False + sdk_dir = None + + # First off, if they have ANDROID_SDK_ROOT set, use that. + envvar = os.environ.get('ANDROID_SDK_ROOT') + if envvar is not None: + if os.path.isdir(envvar): + sdk_dir = envvar + found = True + + # Otherwise try some standard locations. + if not found: + home = os.getenv('HOME') + assert home is not None + test_paths = [home + '/Library/Android/sdk'] + for sdk_dir in test_paths: + if os.path.exists(sdk_dir): + found = True + break + if not found: + print('WOULD CHECK', os.environ.get('ANDROID_SDK_ROOT')) + assert sdk_dir is not None + if not found: + if not os.path.exists(sdk_dir): + print( + 'ERROR: Android sdk not found; install ' + 'the android sdk and try again', + file=sys.stderr) + sys.exit(255) + config = ('\n# This file was automatically generated by ' + + os.path.abspath(sys.argv[0]) + '\n' + '# Feel free to override these paths if you have your android' + ' sdk elsewhere\n' + '\n' + 'sdk.dir=' + sdk_dir + '\n') + with open(local_properties_path, 'w') as outfile: + outfile.write(config) + print('Generating local.properties file (found Android SDK at "' + + sdk_dir + '")', + file=sys.stderr) + return sdk_dir + + +def run(projroot: str, args: List[str]) -> None: + """Main script entry point.""" + # pylint: disable=too-many-branches + # pylint: disable=too-many-locals + + if len(args) != 1: + raise CleanError('Expected 1 arg') + + command = args[0] + + valid_args = ['check', 'get-sdk-path', 'get-ndk-path', 'get-adb-path'] + if command not in valid_args: + print('INVALID ARG; expected one of', valid_args, file=sys.stderr) + sys.exit(255) + + # In all cases we make sure there's a local.properties in our android + # dir that contains valid sdk path. If not, we attempt to create it. + local_properties_path = os.path.join(projroot, 'ballisticacore-android', + 'local.properties') + if os.path.isfile(local_properties_path): + sdk_dir = _parse_lprop_file(local_properties_path) + else: + sdk_dir = _gen_lprop_file(local_properties_path) + + # Sanity check; look for a few things in the sdk that we expect to + # be there. + if not os.path.isfile(sdk_dir + '/platform-tools/adb'): + raise Exception('ERROR: android sdk at "' + sdk_dir + + '" does not seem valid') + + # Sanity check: if they've got ANDROID_HOME set, make sure it lines up with + # what we're pointing at. + android_home = os.getenv('ANDROID_HOME') + if android_home is not None: + if android_home != sdk_dir: + print('ERROR: sdk dir mismatch; ANDROID_HOME is "' + android_home + + '" but local.properties set to "' + sdk_dir + '"', + file=sys.stderr) + sys.exit(255) + + if command == 'get-sdk-path': + print(sdk_dir) + + # We no longer add the ndk path to local.properties (doing so is obsolete) + # but we still want to support returning the ndk path, as some things such + # as external python builds still ask for this. So now we just pull it from + # the project gradle file where we set it explicitly. + if command == 'get-ndk-path': + gradlepath = Path(PROJROOT, 'ballisticacore-android/build.gradle') + with gradlepath.open() as infile: + lines = [ + l for l in infile.readlines() + if l.strip().startswith('ext.ndk_version = ') + ] + if len(lines) != 1: + raise RuntimeError( + f'Expected exactly one ndk_version line in build.gradle;' + f' found {len(lines)}') + ver = lines[0].strip().replace("'", '').replace('"', '').split()[-1] + path = os.path.join(sdk_dir, 'ndk', ver) + if not os.path.isdir(path): + raise Exception(f'NDK listed in gradle not found: {path}') + print(path) + + if command == 'get-adb-path': + import subprocess + adbpath = Path(sdk_dir, 'platform-tools/adb') + if not os.path.exists(adbpath): + raise Exception(f'ADB not found at expected path {adbpath}') + + # Ok, we've got a valid adb path. + # Now, for extra credit, let's see if 'which adb' points to the + # same one and simply return 'adb' if so. This makes our make + # output nice and readable (and hopefully won't cause problems) + result = subprocess.run('which adb', + shell=True, + capture_output=True, + check=False) + if result.returncode == 0: + wpath = result.stdout.decode().strip() + if wpath == str(adbpath): + print('adb') + return + print(adbpath) diff --git a/tools/batools/pcommand.py b/tools/batools/pcommand.py index b9a2eb01..d5a025ab 100644 --- a/tools/batools/pcommand.py +++ b/tools/batools/pcommand.py @@ -857,3 +857,9 @@ def genchangelog() -> None: """Gen a pretty html changelog.""" from batools.genchangelog import generate generate(projroot=str(PROJROOT)) + + +def android_sdk_utils() -> None: + """Wrangle android sdk stuff.""" + from batools.androidsdkutils import run + run(projroot=str(PROJROOT), args=sys.argv[2:]) diff --git a/tools/efrotools/pybuild.py b/tools/efrotools/pybuild.py index d503c3e8..f87caeeb 100644 --- a/tools/efrotools/pybuild.py +++ b/tools/efrotools/pybuild.py @@ -351,7 +351,7 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None: # These builds require ANDROID_NDK to be set, so make sure that's # the case. os.environ['ANDROID_NDK'] = subprocess.check_output( - [rootdir + '/tools/android_sdk_utils', + [f'{rootdir}/tools/pcommand', 'android_sdk_utils', 'get-ndk-path']).decode().strip() # Ok, let 'er rip diff --git a/tools/pcommand b/tools/pcommand index 0b002201..e7c52fef 100755 --- a/tools/pcommand +++ b/tools/pcommand @@ -39,7 +39,8 @@ from batools.pcommand import ( android_archive_unstripped_libs, efro_gradle, stage_assets, update_assets_makefile, update_project, update_cmake_prefab_lib, cmake_prep_dir, gen_binding_code, gen_flat_data_code, wsl_path_to_win, - wsl_build_check_win_drive, win_ci_binary_build, genchangelog) + wsl_build_check_win_drive, win_ci_binary_build, genchangelog, + android_sdk_utils) # pylint: enable=unused-import if TYPE_CHECKING: