在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、前置思考

1.1 为什么要定制源码?

标准 OpenHarmony 系统 ≈ 全套餐
  → IoT 传感器: 只要 1/10 的能力
  → 智能电视: 不需要电话/短信
  → 行业设备: 需要裁剪到最小、最快、最省电

定制 = 按需裁剪 + 按需定制

1.2 源码编译的两种路径

本地构建: 自己搭编译环境 (Linux) → 适合深度定制
云构建: DevEco Studio 远程构建 → 适合常规开发

定制核心链路:
  源码 → 配置裁剪 → gn/ninja 编译 → 系统镜像 → 烧录设备

1.3 关键概念

组件 (component): 一个可独立编译的功能单元
  → 如: 蓝牙组件、媒体组件、权限组件

部件裁剪: 按产品需求选组件,未选的不编译
   → 直接决定系统大小、内存占用、启动速度

镜像 (image): 编译产物打包
  → system.img / vendor.img / userdata.img
  → 分区概念: 系统区 / 厂商区 / 数据区

二、核心原理

2.1 OpenHarmony 源码结构

OpenHarmony 根目录:
  ├── build/               # 构建系统 (gn/ninja 封装)
  ├── foundation/          # 系统基础能力 (分布式/软总线)
  ├── interfaces/          # 接口定义 (API)
  ├── kernel/              # 内核 (LiteOS / Linux)
  ├── device/              # 设备相关 (驱动/SoC)
  ├── vendor/              # 厂商定制 (产品配置)
  ├── applications/        # 系统应用
  └── productdefine/       # 产品定义 (产品→组件映射)

2.2 gn + ninja 编译框架

gn (Generate Ninja): 生成构建文件
  → BUILD.gn 描述"构建什么、依赖什么"
  → 产物: ninja 文件 (构建图)

ninja: 真正的编译器调度器
  → 按依赖图并行编译
  → 只编译变更部分 (增量构建)

流程:
  gn gen → 生成 ninja → ninja 编译 → 打包镜像
  (build.sh 一键封装)

2.3 产品级裁剪原理

产品定义文件 (productdefine/xxx.json):
  → 声明: 产品名、厂商、版本
  → 声明: 包含哪些组件列表

裁剪原理:
  构建系统读产品定义 → 展开依赖图
  → 只编译依赖图中的组件
  → 未声明的组件直接跳过 (不编不进镜像)

镜像裁剪:
  → 系统服务裁剪: 不启动不需要的服务
  → 资源裁剪: 删除无用资源/字体/图片
  → 分区规划: 镜像大小与分区匹配

三、源码/API 深度解析

3.1 产品定义与组件配置

// productdefine/xxx.json 产品定义示例
{
  "product_name": "my_iot_device",
  "version": "1.0.0",
  "type": "mini",                      // 产品类型
  "parts": {
    // 组件列表: 按需声明
    "common": {
      "subsystem": "common",           // 子系统
      "component": "common_utils"      // 组件
    },
    "distributed_schedule": {
      "subsystem": "distributedschedule",
      "component": "samgr_lite"        // 服务管理
    },
    "security": {
      "subsystem": "security",
      "component": "permission_lite"   // 权限
    }
    // 未声明的媒体/电话等组件 → 不编译
  }
}

3.2 组件 BUILD.gn

# foundation/my_feature/BUILD.gn
# 声明一个可编译组件
import("//build/ohos.gni")

ohos_component("my_feature") {
  # 组件信息
  part_name = "my_feature"           # 组件名
  subsystem_name = "my_subsystem"    # 所属子系统
  # 编译源
  sources = [
    "src/my_feature.c",
    "src/my_impl.c",
  ]
  # 头文件
  include_dirs = [ "include" ]
  # 依赖 (组件间依赖图)
  deps = [
    "//foundation/common:common_utils",
  ]
  # 产物 (生成动态库)
  output_extension = "so"
}

3.3 编译与裁剪命令

# 1. 环境准备
#    安装编译依赖: python3, node, gn, ninja, clang...

# 2. 配置产品 (选择产品定义 → 决定裁剪范围)
./build.sh --product-name my_iot_device \
           --ccache              # 启用编译缓存

# 3. 只编译目标组件 (开发时提速)
./build.sh --product-name my_iot_device \
           --build-target my_feature

# 4. 产物
#    out/my_iot_device/packages/phone/
#      ├── system.img   # 系统镜像
#      ├── vendor.img   # 厂商镜像
#      └── userdata.img # 数据分区

# 5. 烧录
hdc flash system.img

3.4 系统服务增减(组件化定制)

// 服务配置: 决定系统启动哪些服务
// 裁剪服务示例: 移除不需要的媒体服务
{
  "services": {
    "init": { "start": true },            // 系统初始化
    "samgr": { "start": true },           // 服务管理
    "media_service": { "start": false },  // 媒体服务(裁剪)
    "telephony_service": { "start": false }, // 电话服务(裁剪)
    "appspawn": { "start": true }         // 应用孵化
  }
}

四、企业级实战落地

4.1 镜像裁剪分级

裁剪级别 手段 效果 风险
L1 组件级 产品定义去组件 体积减 30-50%
L2 服务级 关闭系统服务 内存减、启动快
L3 资源级 删字体/图片/语言 体积再减 10%
L4 内核级 内核 config 裁剪 体积最小

4.2 完整示例:裁剪配置演示

@Entry
@ComponentV2
struct SourceBuildDemo {
  @Local logs: string[] = [];
  @Local state: string = '未开始';

  private runBuildDemo(): void {
    this.logs = [];
    this.state = '编译流程';
    this.log('🔨 OpenHarmony 源码编译流程演示');
    this.log('① 环境准备: python3/node/gn/ninja/clang');
    this.log('② 产品配置: my_iot_device (mini 类型)');
    this.log('   → 组件清单: common + samgr + permission');
    this.log('   → 裁剪: 媒体/电话组件不编译');
    this.log('③ gn gen: 生成构建图 (5000+ 目标)');
    this.log('④ ninja: 并行编译 (64核, 增量)');
    this.log('   → 编译 128 个组件 ✅');
    this.log('⑤ 打包: system.img + vendor.img');
    this.log('   → 镜像体积: 480MB → 156MB (-67%)');
    this.log('⑥ 烧录设备 → 启动验证 ✅');
  }

  private runServiceDemo(): void {
    this.logs = [];
    this.state = '服务裁剪';
    this.log('⚙️ 系统服务增减演示 (IoT 场景)');
    this.log('保留服务:');
    this.log('  init / samgr / appspawn / softbus');
    this.log('  权限服务 / 日志服务 ✅');
    this.log('裁剪服务:');
    this.log('  media_service (无媒体需求)');
    this.log('  telephony_service (无通话需求)');
    this.log('  bluetooth_service (无蓝牙外设)');
    this.log('效果: 常驻内存 320MB → 118MB');
    this.log('  启动耗时 8.5s → 2.1s ✅');
    this.log('注意: 服务间依赖需完整分析,防缺依赖');
  }

  build() {
    Column({ space: 12 }) {
      Text('📦 源码编译与定制').fontSize(20).fontWeight(FontWeight.Bold)
      Text('状态: ' + this.state).fontSize(13).fontColor('#4FC3F7')

      Row({ space: 8 }) {
        Button('编译流程').layoutWeight(1).height(40).fontSize(12)
          .onClick(() => this.runBuildDemo())
        Button('服务裁剪').layoutWeight(1).height(40).fontSize(12)
          .onClick(() => this.runServiceDemo())
      }
      .width('100%')

      Scroll() {
        Column() {
          ForEach(this.logs, (l: string) => {
            Text(l).fontSize(11).lineHeight(18).fontColor('rgba(255,255,255,0.8)').width('100%')
          }, (l: string, i: number) => l + i)
        }.width('100%')
      }
      .layoutWeight(1).width('100%').scrollBar(BarState.Off)
    }
    .width('100%').height('100%').padding(16)
    .backgroundColor('#0D1B2A')
  }
}

4.3 定制流程规范

1. 需求分析: 设备定位 → 需要哪些能力
2. 最小集构建: 先裁剪到能启动,再逐步加回
3. 依赖分析: 组件裁剪前检查依赖图
4. 镜像验证: 体积/内存/启动时间三指标
5. 回归测试: 裁剪后核心功能全量回归

五、问题排查与性能优化

问题 原因 解决
编译失败缺头文件 组件依赖缺失 检查 deps 依赖图
裁剪后功能失效 组件有隐式依赖 用 dep 分析工具
镜像超出分区 裁剪不彻底 资源级裁剪
启动慢 服务依赖链长 精简启动服务
增量构建不生效 编译缓存被清理 配置 ccache
编译环境报错 版本不匹配 按官方版本锁定

5.1 裁剪优化清单

1. 最小可运行集: 核心 = init + 启动 + 基础框架
2. 依赖图工具: 用 build 分析确认无隐式依赖
3. 按需编译: 开发期 --build-target 单组件提速
4. 镜像压缩: 资源去重、字体子集化、语言精简
5. 内核裁剪: 关无用子系统 (netfilter/文件系统等)
6. CI 集成: 构建产物自动验证镜像可启动

六、高阶总结与最佳实践

  1. 产品定义是裁剪的入口:组件清单决定系统范围,先砍组件再砍服务再砍资源。
  2. 依赖图是安全的保证:裁剪前必须分析组件依赖,隐式依赖是裁坏系统的头号原因。
  3. 增量编译提效:开发期单组件编译 + ccache,把 30 分钟构建降到 1 分钟。
  4. 验证闭环:每次裁剪都要验证"能启动 + 功能完整 + 指标达标"三件事。
  5. 分层定制:产品级(组件)→ 系统级(服务)→ 资源级(镜像)→ 内核级(config),风险递增。

一句话记住:源码定制的核心是"按需裁剪"——产品定义选组件(gn/ninja 只编依赖图内目标)、系统服务按场景增减、镜像资源逐层压缩、内核 config 最后兜底,每次裁剪后都要验证"能启动、功能全、指标达标"。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐