mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-20 13:59:34 +08:00
92 lines
3.2 KiB
Python
Executable File
92 lines
3.2 KiB
Python
Executable File
# Released under the MIT License. See LICENSE for details.
|
|
#
|
|
"""Fetch and cache xcode project build paths.
|
|
|
|
This saves the few seconds it normally would take to fire up xcodebuild
|
|
and filter its output.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from typing import Any, Optional
|
|
|
|
|
|
def project_build_path(projroot: str, project_path: str,
|
|
configuration: str) -> str:
|
|
"""Main script entry point."""
|
|
# pylint: disable=too-many-locals
|
|
|
|
config_path = os.path.join(projroot, '.cache', 'xcode_build_path')
|
|
out_path = None
|
|
config: dict[str, dict[str, Any]] = {}
|
|
|
|
build_dir: Optional[str] = None
|
|
|
|
try:
|
|
if os.path.exists(config_path):
|
|
with open(config_path, encoding='utf-8') as infile:
|
|
config = json.loads(infile.read())
|
|
if (project_path in config
|
|
and configuration in config[project_path]):
|
|
|
|
# Ok we've found a build-dir entry for this project; now if it
|
|
# exists on disk and all timestamps within it are decently
|
|
# close to the one we've got recorded, lets use it.
|
|
# (Anything using this script should also be building
|
|
# stuff there so mod times should be pretty recent; if not
|
|
# then its worth re-caching to be sure.)
|
|
build_dir = config[project_path][configuration]['build_dir']
|
|
timestamp = config[project_path][configuration]['timestamp']
|
|
assert build_dir is not None
|
|
if os.path.isdir(build_dir):
|
|
use_cached = True
|
|
|
|
# if its been over a day since we cached this, renew it
|
|
now = time.time()
|
|
if abs(now - timestamp) > 60 * 60 * 24:
|
|
use_cached = False
|
|
|
|
if use_cached:
|
|
out_path = build_dir
|
|
except Exception:
|
|
import traceback
|
|
print('EXCEPTION checking cached build path', file=sys.stderr)
|
|
traceback.print_exc()
|
|
out_path = None
|
|
|
|
# If we don't have a path at this point we look it up and cache it.
|
|
if out_path is None:
|
|
print('Caching xcode build path...', file=sys.stderr)
|
|
output = subprocess.check_output([
|
|
'xcodebuild', '-project', project_path, '-showBuildSettings',
|
|
'-configuration', configuration
|
|
]).decode('utf-8')
|
|
prefix = 'TARGET_BUILD_DIR = '
|
|
lines = [
|
|
l for l in output.splitlines() if l.strip().startswith(prefix)
|
|
]
|
|
if len(lines) != 1:
|
|
raise Exception(
|
|
'TARGET_BUILD_DIR not found in xcodebuild settings output')
|
|
build_dir = lines[0].replace(prefix, '').strip()
|
|
if project_path not in config:
|
|
config[project_path] = {}
|
|
config[project_path][configuration] = {
|
|
'build_dir': build_dir,
|
|
'timestamp': time.time()
|
|
}
|
|
os.makedirs(os.path.dirname(config_path), exist_ok=True)
|
|
with open(config_path, 'w', encoding='utf-8') as outfile:
|
|
outfile.write(json.dumps(config))
|
|
|
|
assert build_dir is not None
|
|
return build_dir
|