import json def configure(conf): pass def generate_apps_table(task): in_node = task.inputs[0] registry = task.outputs[0] app_enum = task.outputs[1] # apps that are assumed to exist by source and must always have a define default_app_enums = [ 'ALARMS', 'GOLF', 'MUSIC', 'SETTINGS', 'SPORTS', ] system_apps = [] resource_apps = [] definition = {} with open(in_node.abspath(), 'r') as f_in: definition.update(json.load(f_in)) system_apps.extend(definition['system_apps']) resource_apps.extend(definition['resource_apps']) def uuid_to_byte_hex_str(uuid): uuid = uuid.replace("-", "") # split string into groups of twos n = 2 pieces = [uuid[i:i+n] for i in range(0, len(uuid), n)] # prefix every group of two with 0x and add commas hex_str = "0x" + ", 0x".join(pieces) return hex_str def generate_registry(f_out): # write generated header f_out.write('// @'+'generated -- DO NOT EDIT\n\n') # write out includes f_out.write('#include "system_app_ids.auto.h"\n') f_out.write('#include "process_management/pebble_process_md.h"\n') f_out.write('#include "resource/resource_ids.auto.h"\n\n') # zeroed app id's indicate disabled apps enabled_system_apps = filter(lambda e: e['id'] != 0, system_apps) # write out function declarations for system apps for entry in enabled_system_apps: f_out.write('extern const PebbleProcessMd *' "{cb_str}(void);\n".format( cb_str=entry['md_fn'])) # write variable name f_out.write('\n\nstatic const AppRegistryEntry ' 'APP_RECORDS[] = {\n') # comment for system apps f_out.write('\n // System Apps\n') # write all entries for system apps for entry in enabled_system_apps: f_out.write( ' {{\n' ' .id = APP_ID_{enum},\n' ' .type = AppInstallStorageFw,\n' ' .md_fn = &{cb_str},\n' ' .color.argb = {color_argb8},\n' ' }},\n'.format( enum=entry['enum'], cb_str=entry['md_fn'], color_argb8=entry.get('color_argb8', 'GColorClearARGB8'))) # comment for resource apps f_out.write('\n // Resource (stored) Apps\n') # write all entries for resource apps for entry in resource_apps: f_out.write( ' {{\n' ' .id = APP_ID_{enum},\n' ' .type = AppInstallStorageResources,\n' ' .name = "{name}",\n' ' .uuid = {{ {uuid} }},\n' ' .bin_resource_id = {bin_id},\n' ' .icon_resource_id = {icon_id},\n' ' .color.argb = {color_argb8},\n' ' }},\n'.format( enum=entry['enum'], name=entry['name'], uuid=uuid_to_byte_hex_str(entry['uuid']), bin_id=entry['bin_resource_id'], icon_id=entry['icon_resource_id'], color_argb8=entry.get('color_argb8', 'GColorClearARGB8'))) f_out.write('};\n') def generate_app_enum(f_out): # write generated header f_out.write('// @'+'generated -- DO NOT EDIT\n\n') # write out includes f_out.write('#include "process_management/app_install_types.h"\n\n') # write all entries for resource apps built_app_enums = [] def write_app_enum(enum, id): f_out.write('#define APP_ID_{enum} ((AppInstallId) {id})\n'.format(enum=enum, id=id)) for entry in (system_apps + resource_apps): built_app_enums.append(entry['enum']) write_app_enum(enum=entry['enum'], id=entry['id']) # write remaining default apps that are not being built for enum in [x for x in default_app_enums if x not in built_app_enums]: write_app_enum(enum=enum, id=0) def _entry_in_test_apps_list(entry): return str(entry['id']) in task.env.test_apps_list # If the current build config allows the app with the given list of defines to be added. # Disabled entries have no entry in the app registry. def entry_enabled(entry): defines = entry.get("ifdefs") or [] platforms = entry.get("target_platforms") or [] # Disabled overrides any define if "DISABLED" in defines: return False if (platforms) and (task.generator.bld.get_platform_name() not in platforms): # If we have a platform list and the current platform isn't listed, return false return False # keep around for legacy purposes if "DEFAULT" in defines: return True if defines: # If we have a defines list, run through all of them and see if we should be including # this application # if test apps are enabled and we have a list test_apps_enabled = "ENABLE_TEST_APPS" in task.env.DEFINES entry_is_test_app = "ENABLE_TEST_APPS" in defines has_test_app_list = len(task.env.test_apps_list) > 0 if test_apps_enabled and has_test_app_list: # check if app is allowed. If not, return False desired_test_app = _entry_in_test_apps_list(entry) if entry_is_test_app and not desired_test_app: return False else: if entry_is_test_app and not test_apps_enabled: return False if all(define in task.env.DEFINES for define in defines): return True else: # if there are no defines, it means we should include it by default return True return False def _set_disabled_app_ids_to_zero(): for entry in system_apps: if not entry_enabled(entry): entry['id'] = 0 def _move_desired_test_apps_to_top(): for app_list in [system_apps, resource_apps]: temp_list = [] for entry in app_list: if _entry_in_test_apps_list(entry): temp_list.insert(0, entry) else: temp_list.append(entry) app_list[:] = temp_list _set_disabled_app_ids_to_zero() _move_desired_test_apps_to_top() with open(registry.abspath(), 'w') as f_registry: generate_registry(f_registry) with open(app_enum.abspath(), 'w') as f_app_enum: generate_app_enum(f_app_enum) def build(bld): if bld.variant == 'prf': shell_name = 'prf' else: shell_name = bld.env.NORMAL_SHELL in_node = bld.path.find_node('%s/system_app_registry_list.json' % shell_name) registry = bld.path.get_bld().make_node('system_app_registry_list.auto.h') app_enum = bld.path.get_bld().make_node('system_app_ids.auto.h') bld(rule=generate_apps_table, source=[in_node], target=[registry, app_enum], vars=['DEFINES', 'test_apps_list']) # vim:filetype=python