HarmonyOS鸿蒙Next中打包hap/app能过滤so只保留特定abi吗?

HarmonyOS鸿蒙Next中打包hap/app能过滤so只保留特定abi吗? 就是像安卓那样简单指定debug保留arm64/x86_64, 指定release保留arm64, 不管具体用到什么库以及库产出了那些abi,不要的全部过滤掉,

abiFilters好像只在cmake编译阶段生效,打包没找到合适的配置,

9 回复

可以,但不是靠一个 abiFilters 一把梭

你这个场景在鸿蒙里要分成两层看:

结论

  1. externalNativeOptions.abiFilters 只控制 本模块 C/C++ 编译阶段 生成哪些 ABI 的 .so,官方 FAQ 也是这么描述的。工程级 build-profile 文档 / FAQ

  2. 真正要做“最终打包时把不要的 ABI 全过滤掉”,要用 buildOption.nativeLib.filter 这一层是官方文档里专门的 Native 库(.so)相关配置,属于打包/收集阶段,不是 CMake 编译阶段。工程级 build-profile 文档

所以答案是:

  • 能过滤
  • 但要用 nativeLib.filter 做打包过滤
  • abiFilters 只是辅助,不够

你要的对应关系

你想要的是这种效果:

  • debug 保留 arm64-v8a + x86_64
  • release 只保留 arm64-v8a
  • 不管 .so 来自你自己编的、三方库自带的、依赖模块带进来的,最后统一裁掉不要的 ABI

这个思路在鸿蒙里是:

  • 编译层abiFilters
  • 打包层nativeLib.filter.excludes

推荐配置

1. 模块级:控制你自己 native 编译产物

在模块级 build-profile.json5 里保留 abiFilters

{
  "buildOption": {
    "externalNativeOptions": {
      "abiFilters": ["arm64-v8a", "x86_64"]
    }
  }
}

如果 release 下你自己的 CMake 也只想编 arm64-v8a,那再配一份 release 专用覆盖。

但这一步只影响你自己编译出来的 so

2. 工程级或产品/构建模式级:控制最终打包收敛

真正关键是这个:

{
  "app": {
    "buildModeSet": [
      {
        "name": "debug",
        "buildOption": {
          "nativeLib": {
            "filter": {
              "excludes": [
                "**/armeabi/*.so",
                "**/armeabi-v7a/*.so",
                "**/x86/*.so"
              ]
            }
          }
        }
      },
      {
        "name": "release",
        "buildOption": {
          "nativeLib": {
            "filter": {
              "excludes": [
                "**/armeabi/*.so",
                "**/armeabi-v7a/*.so",
                "**/x86/*.so",
                "**/x86_64/*.so"
              ]
            }
          }
        }
      }
    ]
  }
}

按这个意思就是:

  • debug:排除 32 位和 x86,保留 arm64-v8ax86_64
  • release:再额外排掉 x86_64,最终只留 arm64-v8a

为什么建议放到 buildModeSet

因为你要的是 debug / release 差异化,而官方 buildModeSet 就是干这个的,且 buildOption 支持配置在这里。工程级 build-profile 文档

如果你还分 product

如果你不是按 debug/release 区分,而是按 phoneDebug / phoneRelease / simulator 这种产品区分,也可以把同样的配置放到 products[].buildOption 里。

这几个点要特别注意

1. 鸿蒙没有完全等价 Android 那种“一个 abiFilters 同时管编译+打包”的体验

鸿蒙这边更像:

  • abiFilters = 编译范围
  • nativeLib.filter = 打包范围

所以你现在觉得 abiFilters 只在 CMake 阶段生效,这个判断基本是对的。

2. 三方库自带的 so,abiFilters 管不到

比如某个 oh_modules/xxx/libs/x86_64/libxxx.so, 即便你自己模块只编了 arm64-v8a, 它还是可能被打包进去。

这时必须靠 nativeLib.filter.excludes 再裁一遍。

3. 旧字段别用了

文档里提到 napiLibFilterOption 已经是废弃状态,推荐用 nativeLib/filter工程级 build-profile 文档

4. 如果有同名 .so 冲突

官方还提供了 pickFirstspickLastsselect 这类能力,用来做更精细的 .so 选择;FAQ 里也提到 select 的优先级比 excludes 更高。编译构建 FAQ 搜索结果

你这个“按 ABI 裁剪”场景,一般先用 excludes 就够了。

实战建议

最稳的做法是两层都配:

debug

  • abiFilters: ["arm64-v8a", "x86_64"]
  • nativeLib.filter.excludes: 排除 armeabi*x86

release

  • abiFilters: ["arm64-v8a"]
  • nativeLib.filter.excludes: 额外排除 x86_64

这样:

  • 你自己的 native 编译更快
  • 最终包里也不会混进三方 ABI 残留

一句话版

可以做,但不要只配 abiFilters 你要的“最终 hap/app 只保留指定 ABI”,用:

  • externalNativeOptions.abiFilters 控制编译
  • buildOption.nativeLib.filter.excludes 控制打包

更多关于HarmonyOS鸿蒙Next中打包hap/app能过滤so只保留特定abi吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


鸿蒙也可以。

一. 配置模块级build-profile.json5。

  1. 配置excludes
{
  "buildOption": {
    "nativeLib": {
      "filter": {
        "excludes": [
          "**/1.so",
          "**/x86_64/*.so"
        ]
      }
    }
  }
}
  1. 配置select的excludePattern,指定排除
{
  "apiType": "stageMode",
  "buildOption": {
    "nativeLib": {
      "filter": {
        "select": [
          "package": "xxx",
          "version": "xxx",
          "excludePattern": ["/arm64-v8a/"]
        ]
      }
    }
  }
}

二. 工程级的build-profile.json5,products和buildModeSet里,排除工程的,用于多个模块依赖,留一个。

{
  "buildOption": {
    "nativeLib": {
      "filter": {
        "excludes": ["**/libfz.so"]
      }
    }
  }
}

总之结论就是无法仅保留特定abi,只能是仅排除特定abi,得结合最终拆包hap看实际有哪些abi打包进来了, 不要的排除掉,

顺便cmake模块默认只打包armv8一个abi,得手动指定所有需要的abi,

背景知识:

可以在 entry 下面的 build-profile.json5 文件中配置nativelib的filter选项来过滤so文件,只保留特定的ABI架构。

问题解决:

配置参数:

{
  "apiType": "stageModel",
  "buildOption": {
    "externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt",
      "arguments": "",
      "cppFlags": "",
      "abiFilters": ["arm64-v8a", "x86_64"]  // debug模式包含两种架构
    },
    "nativelib": {
      "filter": {
        "excludes": ["**/armeabi-v7a/*.so"]
      }
    }
  },
  "buildOptionSet": [
    {
      "name": "release",
      "buildOption": {
        "externalNativeOptions": {
          "abiFilters": ["arm64-v8a"]  // release模式只保留arm64-v8a
        },
        "nativelib": {
          "filter": {
            "excludes": ["**/x86_64/*.so", "**/armeabi-v7a/*.so"]
          }
        }
      }
    }
  ]
}

使用 nativeLib.filter 打包级过滤

这是官方推荐的 “打包时” 过滤方案,位于模块的 build-profile.json5 文件中。它能对所有最终打入 HAP 的 .so 文件进行二次过滤。

cke_131.png

// 在 build-profile.json5 中,找到 buildOptionSet 下的 nativeLib 部分
{
  "buildOption": {
    "nativeLib": {
      "filter": {
        // 方式一:按目录排除(最常用)
        "excludes": [
          "**/armeabi-v7a/*.so",
          "**/x86_64/*.so"
        ],
        // 方式二:精准选择(优先级最高,推荐)
        "select": [
          {
            "include": ["**/*.so"],
            "exclude": ["**/x86_64/*.so", "**/armeabi-v7a/*.so"]
          }
        ]
      }
    }
  }
}

可以,但要分清两个配置:externalNativeOptions.abiFilters 只影响本模块 CMake 编译哪些 ABI;最终打包已有 .so 要用 buildOption.nativeLib.filter。你这种“无论库从哪里来,最终只保留指定 ABI”的场景,建议在不同 buildOptionSet 里配置 nativeLib.filter.excludes,例如 release 排除 **/x86_64/*.so,只保留 arm64-v8a。三方 HAR/HSP/ohpm 包自带的 so 不一定受 abiFilters 影响,打包后最好解压 HAP 看 libs 目录确认。

在 entry/build-profile.json5 里面配置
这是官网样例

"buildOption": {
    "nativeLib": {
      "filter": {
        "excludes": [
          "**/armeabi-v7a/*.so", //排除所有armeabi-v7a架构的so文件
          "**/x86_64/*.so"//排除所有x86_64架构的so文件
        ]
      }
    }
  },

可以。在HarmonyOS NEXT中,通过配置模块的 build-profile.json5 中的 abiFilters 字段(如 ["arm64-v8a"])即可打包时仅保留指定ABI的so文件。需确保HAP/APP包体积符合要求。该设置仅作用于native库,不影响其他资源。

在 HarmonyOS Next 中,可以通过以下两种方式过滤 SO,仅保留特定 ABI:

1. 编译期 + 打包期过滤(推荐)
在模块的 build-profile.json5 中直接设置 buildOption.externalNativeOptions.abiFilters,该配置会同时限制编译和最终 HAP 中携带的 ABI:

{
  "buildOption": {
    "externalNativeOptions": {
      "abiFilters": ["arm64-v8a", "x86-64"] // debug
    }
  }
}

对应 release 只需改为 ["arm64-v8a"]。可通过不同的 buildMode 或自定义 build-profile 分别配置。

2. 仅打包期过滤
若 SO 已经编译出多个 ABI,仅需在打包时剔除,则使用 packOptions.exclude 排除目录:

{
  "packOptions": {
    "exclude": ["**/armeabi-v7a/**", "**/x86/**"]
  }
}

此配置会将 lib/ 下所有不想要的 ABI 目录排除,最终 hap 中只保留指定架构。
两种方式可组合使用,灵活满足 debug/release 不同需求。

回到顶部