consolidating xcode-build-path functionality

This commit is contained in:
Eric Froemling 2021-06-12 17:15:47 -05:00
parent 78e5fc0486
commit 1ae25e469b
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
4 changed files with 110 additions and 3 deletions

View File

@ -880,3 +880,18 @@ def update_meta_makefile() -> None:
"""Update the meta Makefile if needed."""
from batools.metamakefile import update
update(projroot=str(PROJROOT), check='--check' in sys.argv)
def xcode_build_path() -> None:
"""Get the build path for an xcode project."""
import os
from batools.xcode import project_build_path
if len(sys.argv) != 4:
raise Exception(
'Expected 2 args: <xcode project path> <configuration name>')
project_path = os.path.abspath(sys.argv[2])
configuration = sys.argv[3]
path = project_build_path(projroot=str(PROJROOT),
project_path=project_path,
configuration=configuration)
print(path)

91
tools/batools/xcode.py Executable file
View File

@ -0,0 +1,91 @@
# 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 Dict, 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) 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') as outfile:
outfile.write(json.dumps(config))
assert build_dir is not None
return build_dir

View File

@ -67,10 +67,10 @@ def push_ipa(root: pathlib.Path, modename: str) -> None:
raise Exception('invalid mode: "' + str(modename) + '"')
mode = MODES[modename]
xc_build_path = pathlib.Path(root, 'tools/xc_build_path')
pcommand_path = pathlib.Path(root, 'tools/pcommand')
xcprojpath = pathlib.Path(root, cfg.projectpath)
app_dir = subprocess.run(
[xc_build_path, xcprojpath, mode['configuration']],
[pcommand_path, 'xcode_build_path', xcprojpath, mode['configuration']],
check=True,
capture_output=True).stdout.decode().strip()
built_app_path = pathlib.Path(app_dir, cfg.app_bundle_name)

View File

@ -40,7 +40,8 @@ from batools.pcommand import (
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,
android_sdk_utils, update_resources_makefile, update_meta_makefile)
android_sdk_utils, update_resources_makefile, update_meta_makefile,
xcode_build_path)
# pylint: enable=unused-import
if TYPE_CHECKING: