# Released under the MIT License. See LICENSE for details.#"""Updates top level Makefile based on project elements present."""from__future__importannotationsimportosfromtypingimportTYPE_CHECKINGimportsubprocessifTYPE_CHECKING:pass
[docs]defgenerate_top_level_makefile(projroot:str,existing_data:str)->str:"""Main script entry point."""fromefrotools.projectimportgetprojectconfigfrompathlibimportPathpublic=getprojectconfig(Path(projroot))['public']assertisinstance(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.ifbool(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=originalreturnout
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]=[]forlineinlines:fname=os.path.split(line)[1]if(fname.startswith('python_class_')orfname.startswith('python_methods_'))and(fname.endswith('.cc')):assert' 'notinlineassertline.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 targetsout+=' \\\n'.join(f' {target}'fortargetintargets)assert' 'notindmstatedirout+=('\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}')returnout