mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 13:25:31 +08:00
106 lines
3.2 KiB
Python
Executable File
106 lines
3.2 KiB
Python
Executable File
# Released under the MIT License. See LICENSE for details.
|
|
#
|
|
"""Updates top level Makefile based on project elements present."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from typing import TYPE_CHECKING
|
|
import subprocess
|
|
|
|
if TYPE_CHECKING:
|
|
pass
|
|
|
|
|
|
def generate_top_level_makefile(projroot: str, existing_data: str) -> str:
|
|
"""Main script entry point."""
|
|
from efrotools.project import getprojectconfig
|
|
from pathlib import Path
|
|
|
|
public = getprojectconfig(Path(projroot))['public']
|
|
assert isinstance(public, bool)
|
|
|
|
original = existing_data
|
|
|
|
# NOTE: no longer doing this; our dummy module generation stuff is
|
|
# now a nice static lazybuild target. Can remove this whole file
|
|
# soon if no other uses for it come up.
|
|
if bool(False):
|
|
lines = original.splitlines()
|
|
|
|
auto_start = lines.index('# __AUTOGENERATED_DUMMY_MODULES_BEGIN__')
|
|
auto_end = lines.index('# __AUTOGENERATED_DUMMY_MODULES_END__')
|
|
|
|
our_lines = [
|
|
_get_dummy_module_target(projroot),
|
|
]
|
|
|
|
filtered = lines[: auto_start + 1] + our_lines + lines[auto_end:]
|
|
out = '\n'.join(filtered) + '\n'
|
|
else:
|
|
out = original
|
|
|
|
return out
|
|
|
|
|
|
def _get_dummy_module_target(projroot: str) -> str:
|
|
lines = (
|
|
subprocess.run(
|
|
[
|
|
'find',
|
|
os.path.join(projroot, 'src/ballistica'),
|
|
'-name',
|
|
'python_*',
|
|
],
|
|
check=True,
|
|
capture_output=True,
|
|
)
|
|
.stdout.decode()
|
|
.splitlines()
|
|
)
|
|
targets: list[str] = []
|
|
for line in lines:
|
|
fname = os.path.split(line)[1]
|
|
if (
|
|
fname.startswith('python_class_')
|
|
or fname.startswith('python_methods_')
|
|
) and (fname.endswith('.cc')):
|
|
assert ' ' not in line
|
|
assert line.startswith(projroot + '/')
|
|
targets.append(line.removeprefix(projroot + '/'))
|
|
|
|
# Keep our results deterministic.
|
|
targets.sort()
|
|
|
|
# Also require a built binary and compiled scripts for it to use.
|
|
# UPDATE - scratch that. Now just trying to make it clear that
|
|
# dummy-modules should not be generated as part of regular dependency
|
|
# setups but rather in a dedicated pass.
|
|
# targets.append('assets-cmake-scripts')
|
|
# targets.append('cmake-binary')
|
|
|
|
# Let's just use a single file for dependency tracking and regenerate
|
|
# all dummy modules when it is dirty. There's basically no speed difference
|
|
# regenerating all dummy-modules vs a single one so this keeps things
|
|
# simple. It also lets us blow away any orphaned modules.
|
|
dmstatepath = 'build/dummymodules/.dummy_modules_state'
|
|
dmstatedir = os.path.dirname(dmstatepath)
|
|
out = (
|
|
'\n# Update dummy Python modules when source files contributing to'
|
|
' them change.\n'
|
|
f'{dmstatepath}: \\\n'
|
|
)
|
|
# assert targets
|
|
out += ' \\\n'.join(f' {target}' for target in targets)
|
|
|
|
assert ' ' not in dmstatedir
|
|
out += (
|
|
'\n'
|
|
f'\t@tools/pcommand with_build_lock gen_dummy_modules_lock \\\n'
|
|
f' rm -rf {dmstatedir} \\&\\& mkdir -p {dmstatedir} \\\n'
|
|
' \\&\\& ./tools/pcommand gen_dummy_modules \\\n'
|
|
f' \\&\\& touch {dmstatepath}'
|
|
)
|
|
|
|
return out
|