You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Bazel构建Android原生库时,如何动态获取目标架构命名Jar?

实现动态架构名的Jar打包方案

方案一:使用Genrule快速实现

直接通过genrule调用jar命令,结合Bazel内置的TARGET_CPU变量动态生成带架构名的Jar文件,同时对CPU名称做映射(比如将aarch64转为更直观的arm64):

genrule(
    name = "mylib_with_arch",
    srcs = ["//:my-native-lib.so"],
    outs = ["libmylib-$(ARCH).jar"],
    cmd = """
        # 映射TARGET_CPU到Android常用架构名
        ARCH=$(echo $(TARGET_CPU) | sed 's/aarch64/arm64/;s/armv7a/armeabi-v7a/;s/x86_64/x86_64/;s/x86/x86/')
        # 调用jar命令打包so文件到Jar
        jar cf "$@" $(location //:my-native-lib.so)
    """,
    # 引入JDK工具链确保jar命令可用
    toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"],
)

执行构建时,使用原命令即可:

bazel build --config android //:mylib_with_arch

生成的Jar文件会自动带上对应架构后缀,比如libmylib-arm64.jar。

方案二:自定义规则(更灵活可扩展)

如果需要复用逻辑或扩展更多架构映射,可自定义Bazel规则封装打包逻辑:

首先在BUILD文件所在目录创建java_with_arch.bzl文件,写入以下规则:

load("@bazel_tools//tools/jdk:jar.bzl", "jar")

def _java_library_with_arch_impl(ctx):
    # 定义CPU到Android架构名的映射表
    arch_mapping = {
        "aarch64": "arm64",
        "armv7a": "armeabi-v7a",
        "x86_64": "x86_64",
        "x86": "x86",
    }
    # 获取当前构建目标的CPU架构
    target_cpu = ctx.var.get("TARGET_CPU", "unknown")
    # 匹配对应的架构名,无匹配则保留原CPU名称
    arch = arch_mapping.get(target_cpu, target_cpu)
    
    # 声明带架构名的输出Jar文件
    jar_filename = "lib{}-{}.jar".format(ctx.attr.base_name, arch)
    output_jar = ctx.actions.declare_file(jar_filename)
    
    # 调用Bazel内置的jar工具打包资源
    jar(ctx,
        output = output_jar,
        files = ctx.files.resources,
    )
    
    return [DefaultInfo(files = depset([output_jar]))]

# 定义对外暴露的规则
java_library_with_arch = rule(
    implementation = _java_library_with_arch_impl,
    attrs = {
        "base_name": attr.string(mandatory = True, doc = "Jar文件的基础名称"),
        "resources": attr.label_list(allow_files = True, doc = "需要打包进Jar的资源文件(如so)"),
    },
    toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"],
)

然后在BUILD文件中引入并使用该规则:

load("//:java_with_arch.bzl", "java_library_with_arch")

java_library_with_arch(
    name = "mylib",
    base_name = "mylib",
    resources = ["//:my-native-lib.so"],
)

执行构建命令后,会自动生成带架构后缀的Jar文件,行为与原java_library一致,但文件名动态包含架构信息。

注意事项

  • 当前android_arm64_cgo平台对应的TARGET_CPU为aarch64,已在映射表中处理;若需支持更多架构,只需扩展arch_mapping或sed命令中的替换规则即可。

内容的提问来源于stack exchange,提问作者plamkata__

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 06:05:26