From 78e5fc0486cb6672217848298f2cb2e9323f38ae Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Sat, 12 Jun 2021 16:52:24 -0500 Subject: [PATCH] Consolidating meta makefile generation --- .idea/dictionaries/ericf.xml | 1 + .../.idea/dictionaries/ericf.xml | 1 + docs/ba_module.md | 2 +- src/meta/Makefile | 2 +- tools/batools/metamakefile.py | 143 ++++++++++++++++++ tools/batools/pcommand.py | 6 + tools/batools/resourcesmakefile.py | 3 +- tools/batools/updateproject.py | 14 +- tools/pcommand | 2 +- 9 files changed, 164 insertions(+), 10 deletions(-) create mode 100755 tools/batools/metamakefile.py diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index ab49ebe7..94289c2c 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -1556,6 +1556,7 @@ otherplayer otherspawn ourhash + ourname ourself outdata outdelay diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml index eed0a770..eb2adef3 100644 --- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml @@ -729,6 +729,7 @@ osis osssssssssss ostype + ourname ourself ourstanding outpath diff --git a/docs/ba_module.md b/docs/ba_module.md index 2ba1a5fa..f187e602 100644 --- a/docs/ba_module.md +++ b/docs/ba_module.md @@ -1,5 +1,5 @@ -

last updated on 2021-06-11 for Ballistica version 1.6.4 build 20378

+

last updated on 2021-06-12 for Ballistica version 1.6.4 build 20379

This page documents the Python classes and functions in the 'ba' module, which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please let me know. Happy modding!


diff --git a/src/meta/Makefile b/src/meta/Makefile index 4c30164a..83292723 100644 --- a/src/meta/Makefile +++ b/src/meta/Makefile @@ -1,6 +1,6 @@ # Released under the MIT License. See LICENSE for details. # -# This file was generated by tools/update_meta_makefile. +# This file was generated by batools.metamakefile. all: cpp_sources diff --git a/tools/batools/metamakefile.py b/tools/batools/metamakefile.py new file mode 100755 index 00000000..0e375467 --- /dev/null +++ b/tools/batools/metamakefile.py @@ -0,0 +1,143 @@ +# Released under the MIT License. See LICENSE for details. +# +"""Procedurally regenerates our code Makefile. + +This Makefiles builds our generated code such as encrypted python strings, +node types, etc). +""" +from __future__ import annotations + +import os +import sys +from typing import TYPE_CHECKING +from dataclasses import dataclass + +from efro.terminal import Clr + +if TYPE_CHECKING: + from typing import Optional, Set, List, Dict, Any, Tuple + +# These paths need to be relative to the dir we're writing the Makefile to. +TOOLS_DIR = '../../tools' +ROOT_DIR = '../..' +OUT_DIR_CPP = '../ballistica/generated' + + +@dataclass +class Target: + """A target to be added to the makefile.""" + src: List[str] + dst: str + cmd: str + public: bool + mkdir: bool = False + + +def update(projroot: str, check: bool) -> None: + """Main script entry point.""" + + from efrotools import get_public_license + + # Operate out of root dist dir for consistency. + os.chdir(projroot) + + targets = _generate_targets() + + # Write Makefile. + fname = 'src/meta/Makefile' + existing: Optional[str] + try: + with open(fname, 'r') as infile: + existing = infile.read() + except Exception: + existing = None + + out = (get_public_license('makefile') + + f'\n#\n# This file was generated by {__name__}.\n\n') + public_dsts: Set[str] = set() + private_dsts: Set[str] = set() + for target in targets: + (public_dsts if target.public else private_dsts).add(target.dst) + out += 'all: cpp_sources\n' + out += ('\n' + 'cpp_sources: ' + ' \\\n '.join( + dst.replace(' ', '\\ ') for dst in sorted(public_dsts)) + '\n') + out += ('\n' + '#__PUBSYNC_STRIP_BEGIN__\n' + 'cpp_sources: ' + ' \\\n '.join( + dst.replace(' ', '\\ ') for dst in sorted(private_dsts)) + + '\n' + '#__PUBSYNC_STRIP_END__\n') + + out += f'\nclean:\n\t@rm -rf {OUT_DIR_CPP}\n\n' + var_num = 1 + + for public in [True, False]: + if not public: + out += '#__PUBSYNC_STRIP_BEGIN__\n\n' + for target in targets: + if target.public != public: + continue + if bool(False) and ' ' in target.dst: + out += ('TARGET_' + str(var_num) + ' = ' + + target.dst.replace(' ', '\\ ') + '\n${TARGET_' + + str(var_num) + '}') + var_num += 1 + else: + out += target.dst.replace(' ', '\\ ') + out += ' : ' + ' '.join(s for s in target.src) + ( + ('\n\t@mkdir -p "' + os.path.dirname(target.dst) + + '"') if target.mkdir else '') + '\n\t@' + target.cmd + '\n\n' + if not public: + out += '#__PUBSYNC_STRIP_END__\n' + + if out == existing: + print('Meta Makefile is up to date.') + else: + if check: + print(Clr.SRED + 'ERROR: file out of date: ' + fname + Clr.RST) + sys.exit(255) + print(Clr.SBLU + 'Generating: ' + fname + Clr.RST) + with open(fname, 'w') as outfile: + outfile.write(out) + + +def _generate_targets() -> List[Target]: + targets: List[Target] = [] + # Manually define a few entries and automatically add one for each + # of our ba_embedded_*.py files. + for pkg, public in [('bameta', True), ('bametainternal', False)]: + entries: List[Tuple[str, str]] = [] + + for fname in os.listdir(f'src/meta/{pkg}/python_embedded'): + if (fname.endswith('.py') and fname != '__init__.py' + and 'flycheck' not in fname): + entries.append((os.path.splitext(fname)[0], + 'BINDING' if fname == 'binding.py' else + 'FLAT_DATA' if public else 'ENCRYPTED_DATA')) + # Generate targets from our entries. + for name, out_type in entries: + extra_sources: List[str] = [] + if out_type == 'FLAT_DATA': + cmd = os.path.join( + TOOLS_DIR, + f'pcommand gen_flat_data_code $< $@ {name}_code') + extra_sources.append(os.path.join(TOOLS_DIR, + 'batools/meta.py')) + elif out_type == 'BINDING': + cmd = os.path.join(TOOLS_DIR, + 'pcommand gen_binding_code $< $@') + extra_sources.append(os.path.join(TOOLS_DIR, + 'batools/meta.py')) + else: + cmd = os.path.join( + TOOLS_DIR, f'generate_code {out_type} {name}_code $< $@') + extra_sources.append(os.path.join(TOOLS_DIR, 'generate_code')) + + targets.append( + Target(src=[f'{pkg}/python_embedded/{name}.py'] + + extra_sources, + dst=os.path.join(OUT_DIR_CPP, 'python_embedded', + f'{name}.inc'), + cmd=cmd, + public=public)) + return targets diff --git a/tools/batools/pcommand.py b/tools/batools/pcommand.py index 3f3d3a74..b87aad70 100644 --- a/tools/batools/pcommand.py +++ b/tools/batools/pcommand.py @@ -874,3 +874,9 @@ def update_resources_makefile() -> None: """Update the resources Makefile if needed.""" from batools.resourcesmakefile import update update(projroot=str(PROJROOT), check='--check' in sys.argv) + + +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) diff --git a/tools/batools/resourcesmakefile.py b/tools/batools/resourcesmakefile.py index f267351f..ed56f477 100755 --- a/tools/batools/resourcesmakefile.py +++ b/tools/batools/resourcesmakefile.py @@ -278,9 +278,8 @@ def _write_makefile(fname: str, targets: List[Dict], check: bool) -> None: except Exception: existing = None - ourname = os.path.basename(__file__) out = (get_public_license('makefile') + - f'\n# Generated by {ourname}; do not hand-edit.\n\n') + f'\n# Generated by {__name__}; do not hand-edit.\n\n') all_dsts = set() for target in targets: all_dsts.add(target['dst']) diff --git a/tools/batools/updateproject.py b/tools/batools/updateproject.py index eb947013..3f0795e0 100755 --- a/tools/batools/updateproject.py +++ b/tools/batools/updateproject.py @@ -668,11 +668,15 @@ class Updater: sys.exit(255) def _update_meta_makefile(self) -> None: - if os.path.exists('tools/update_meta_makefile'): - if os.system('tools/update_meta_makefile' + self._checkarg) != 0: - print(f'{Clr.RED}Error checking/updating' - f' generated-code Makefile.{Clr.RED}') - sys.exit(255) + # FIXME: should support running this in public too. + if not self._public: + try: + subprocess.run(['tools/pcommand', 'update_meta_makefile'] + + self._checkarglist, + check=True) + except Exception as exc: + raise CleanError( + 'Error checking/updating meta Makefile.') from exc def _update_resources_makefile(self) -> None: # FIXME: should support running this in public too. diff --git a/tools/pcommand b/tools/pcommand index 80f35e26..f4d8b35e 100755 --- a/tools/pcommand +++ b/tools/pcommand @@ -40,7 +40,7 @@ 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) + android_sdk_utils, update_resources_makefile, update_meta_makefile) # pylint: enable=unused-import if TYPE_CHECKING: