Skip to main content
Glama
apk_genrule.bzl7.73 kB
# Copyright (c) Meta Platforms, Inc. and affiliates. # # This source code is licensed under both the MIT license found in the # LICENSE-MIT file in the root directory of this source tree and the Apache # License, Version 2.0 found in the LICENSE-APACHE file in the root directory # of this source tree. load("@prelude//:genrule.bzl", "process_genrule") load("@prelude//android:android_apk.bzl", "get_install_info") load("@prelude//android:android_providers.bzl", "AndroidAabInfo", "AndroidApkInfo", "AndroidApkUnderTestInfo") load("@prelude//android:android_toolchain.bzl", "AndroidToolchainInfo") load("@prelude//android:bundletool_util.bzl", "derive_universal_apk") load("@prelude//java:class_to_srcs.bzl", "JavaClassToSourceMapInfo") load("@prelude//java:java_providers.bzl", "KeystoreInfo") load("@prelude//utils:expect.bzl", "expect") def apk_genrule_impl(ctx: AnalysisContext) -> list[Provider]: expect((ctx.attrs.apk == None) != (ctx.attrs.aab == None), "Exactly one of 'apk' and 'aab' must be specified") input_android_apk_under_test_info = None input_unstripped_shared_libraries = None input_android_apk_subtargets = None input_android_aab_subtargets = None if ctx.attrs.apk != None: # TODO(T104150125) The underlying APK should not have exopackage enabled input_android_apk_info = ctx.attrs.apk[AndroidApkInfo] expect(input_android_apk_info != None, "'apk' attribute must be an Android APK!") input_apk = input_android_apk_info.apk input_manifest = input_android_apk_info.manifest input_materialized_artifacts = input_android_apk_info.materialized_artifacts input_unstripped_shared_libraries = input_android_apk_info.unstripped_shared_libraries input_android_apk_under_test_info = ctx.attrs.apk[AndroidApkUnderTestInfo] input_android_apk_subtargets = ctx.attrs.apk[DefaultInfo].sub_targets env_vars = { "APK": cmd_args(input_apk), } else: input_android_aab_info = ctx.attrs.aab[AndroidAabInfo] expect(input_android_aab_info != None, "'aab' attribute must be an Android Bundle!") # It's not an APK, but buck1 does this so we do it too for compatibility input_apk = input_android_aab_info.aab input_manifest = input_android_aab_info.manifest input_materialized_artifacts = input_android_aab_info.materialized_artifacts input_android_aab_subtargets = ctx.attrs.aab[DefaultInfo].sub_targets env_vars = { "AAB": cmd_args(input_apk), } genrule_providers = process_genrule( ctx, ctx.attrs.out, ctx.attrs.outs, env_vars, other_outputs = input_materialized_artifacts, genrule_error_handler = ctx.attrs._android_toolchain[AndroidToolchainInfo].android_error_handler, ) genrule_default_info = filter(lambda x: isinstance(x, DefaultInfo), genrule_providers) expect( len(genrule_default_info) == 1, "Expecting a single DefaultInfo, but got {}", genrule_default_info, ) genrule_default_output = genrule_default_info[0].default_outputs[0] genrule_default_output_is_aab = genrule_default_output.extension == ".aab" genrule_default_output_is_apk = genrule_default_output.extension == ".apk" expect( genrule_default_output_is_aab or genrule_default_output_is_apk, "apk_genrule must output a '.apk' or '.aab' file, but got {}", genrule_default_info, ) if ctx.attrs.aab: if genrule_default_output_is_aab: output_aab_info = AndroidAabInfo( aab = genrule_default_output, manifest = input_manifest, materialized_artifacts = input_materialized_artifacts, ) output_apk = None else: output_aab_info = None output_apk = genrule_default_output if ctx.attrs.use_derived_apk: expect(genrule_default_output_is_aab, "Default genrule output must end in '.aab' if use_derived_apk is True.") output_apk = derive_universal_apk( ctx = ctx, android_toolchain = ctx.attrs._android_toolchain[AndroidToolchainInfo], app_bundle = genrule_default_output, keystore = ctx.attrs.keystore[KeystoreInfo] if ctx.attrs.keystore else None, ) default_providers = [ DefaultInfo( default_output = output_apk, other_outputs = input_materialized_artifacts + genrule_default_info[0].other_outputs, sub_targets = { "aab": [DefaultInfo( default_outputs = [genrule_default_output], )], "native_libs": [input_android_aab_subtargets["native_libs"][DefaultInfo]], }, ), ] + filter(lambda x: not isinstance(x, DefaultInfo), genrule_providers) else: sub_targets = {k: [v[DefaultInfo]] for k, v in genrule_default_info[0].sub_targets.items()} sub_targets.update({ "native_libs": [input_android_aab_subtargets["native_libs"][DefaultInfo]], }) default_providers = [ DefaultInfo( default_output = genrule_default_output, other_outputs = genrule_default_info[0].other_outputs, sub_targets = sub_targets, ), ] + filter(lambda x: not isinstance(x, DefaultInfo), genrule_providers) else: sub_targets = {k: [v[DefaultInfo]] for k, v in genrule_default_info[0].sub_targets.items()} sub_targets.update({ "manifest": [input_android_apk_subtargets["manifest"][DefaultInfo]], "native_libs": [input_android_apk_subtargets["native_libs"][DefaultInfo]], "unstripped_native_libraries": [input_android_apk_subtargets["unstripped_native_libraries"][DefaultInfo]], "unstripped_native_libraries_files": [input_android_apk_subtargets["unstripped_native_libraries_files"][DefaultInfo]], "unstripped_native_libraries_json": [input_android_apk_subtargets["unstripped_native_libraries_json"][DefaultInfo]], }) expect(genrule_default_output_is_apk, "apk_genrule output must end in '.apk'") output_apk = genrule_default_output output_aab_info = None default_providers = [ DefaultInfo( default_output = output_apk, other_outputs = genrule_default_info[0].other_outputs, sub_targets = sub_targets, ), ] + filter(lambda x: not isinstance(x, DefaultInfo), genrule_providers) class_to_src_map = [ctx.attrs.apk[JavaClassToSourceMapInfo]] if (ctx.attrs.apk and JavaClassToSourceMapInfo in ctx.attrs.apk) else [] if output_apk: apk_providers = [ AndroidApkInfo( apk = output_apk, manifest = input_manifest, materialized_artifacts = input_materialized_artifacts, unstripped_shared_libraries = input_unstripped_shared_libraries, ), get_install_info( ctx, output_apk = output_apk, manifest = input_manifest, exopackage_info = None, ), ] else: apk_providers = [] aab_providers = filter(None, [output_aab_info]) apk_under_test_providers = filter(None, [input_android_apk_under_test_info]) return default_providers + apk_providers + aab_providers + apk_under_test_providers + class_to_src_map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server