openharmony源码构建开发基础之编译指令-T指定详解
2026/6/3 22:40:03 网站建设 项目流程

build.ninja 目标查找与编译指南(以 camera_framework 为例)

本文面向OpenHarmony GN + Ninja构建体系,覆盖以下内容:

  • “camera_framework 同名导致 unknown target”的根因与解决办法
  • out/arm64/targets/build.ninja怎么产生的
  • build.ninja语法/规则怎么读(重点包含行末$$:转义)
  • camera_framework这种重名/多形态 target,如何区分“部件target”“库产物target”
  • 如何用grep / ninja -t targets / ninja -t query快速定位,并给出可直接复制的编译指令(build.sh -T

说明:文中的命令示例以当前环境路径为准:/root/633/out/arm64/targets/build.ninja


1. 问题背景:为什么最开始-T camera_framework编译失败(同名导致误解)

1.1 初始现象

初始尝试命令如下:

./build.sh --product-name 633_rk3588j_isdt-2 -T camera_framework

该命令无法编译成功(典型表现为 ninja 报unknown target)。

1.2 “同名”的起点:两处都叫 camera_framework(但含义完全不同)

误解的根源是:camera_framework这个字符串在两处被定义,但属于不同层面的“名字”:

  • bundle.json(部件/组件名)component.name = "camera_framework"
"component": { "name": "camera_framework", "subsystem": "multimedia", "syscap": ["SystemCapability.Multimedia.Camera.Core"], "features": [],
  • BUILD.gn(GN 目标名/模块名)ohos_shared_library("camera_framework")
ohos_shared_library("camera_framework") { branch_protector_ret = "pac_ret" install_enable = true sources = [

这两处“同名”本身不是错误,但非常容易误以为-T camera_framework可以直接编译

1.3 为什么-T camera_framework会失败(真正原因)

./build.sh -T传给的是ninja 的 target 名(不是 bundle.json 的component.name)。

因此当写-T camera_framework时,ninja 会去查找一个名为camera_framework的 target;但在当前build.ninja中,这个“短名字 target”并不存在,通常存在的是“带路径的 target”。

可用下面命令快速验证(返回空表示“没有这个 target”):

grep-n'^build camera_framework:'/root/633/out/arm64/targets/build.ninja

真正存在的是这类带路径的定义(举例):

grep-n'^build .*camera_framework'/root/633/out/arm64/targets/build.ninja|head

另外在bundle.json中也能看到:该部件并不是直接写“camera_framework”去编译,而是列出了它包含的GN label(带路径 + 冒号)

"fwk_group": [ "//foundation/multimedia/camera_framework/frameworks/native/camera:camera_framework", "//foundation/multimedia/camera_framework/frameworks/native/ndk:ohcamera", "//foundation/multimedia/camera_framework/interfaces/kits/js/camera_napi:camerapicker_napi", "//foundation/multimedia/camera_framework/interfaces/kits/js/camera_napi:camera_napi", "//foundation/multimedia/camera_framework/interfaces/kits/js/camera_napi:camera_js", "//foundation/multimedia/camera_framework/interfaces/kits/js/camera_napi:camerapicker_js" ],

注意:GN label 里常见的//是“源码根路径”语义;但build.ninja里的 ninja target不会带//,而是类似foundation/...这样的路径。

out/arm64/targets/build.ninja中可以看到对应的ninja target(phony 聚合目标,带路径):

build foundation/multimedia/camera_framework/common$:camera_utils: phony obj/foundation/multimedia/camera_framework/common/camera_utils.stamp build foundation/multimedia/camera_framework/frameworks/native/camera$:camera_framework: phony multimedia/camera_framework/libcamera_framework.z.so build foundation/multimedia/camera_framework/frameworks/native/camera$:camera_framework__check: phony obj/foundation/multimedia/camera_framework/frameworks/native/camera/camera_framework__check.stamp build foundation/multimedia/camera_framework/frameworks/native/camera$:camera_framework__collect: phony obj/foundation/multimedia/camera_framework/frameworks/native/camera/camera_framework__collect.stamp build foundation/multimedia/camera_framework/frameworks/native/camera$:camera_framework__notice: phony obj/foundation/multimedia/camera_framework/frameworks/native/camera/camera_framework__notice.stamp build foundation/multimedia/camera_framework/frameworks/native/camera$:camera_framework_info: phony obj/foundation/multimedia/camera_framework/frameworks/native/camera/camera_framework_info.stamp

因此正确做法是:使用带路径的目标名进行编译(见第 2 节)。

1.3.1 速查表:多个“camera_framework”的含义对照

  • bundle.json 的component.namecamera_framework(部件/组件名,不是 ninja target)
  • BUILD.gn 的 GN target 名camera_framework(需要配合路径才能唯一定位)
  • bundle.json 里用于构建的 GN label//foundation/.../camera:camera_framework(GN 语义)
  • build.ninja 里的目标写法foundation/.../camera$:camera_framework(Ninja 文件内部写法,$:表示字面量:
  • 命令行应使用的 ninja targetfoundation/.../camera:camera_framework(把$:还原成:
  • 库产物 targetmultimedia/camera_framework/libcamera_framework.z.so

1.3.2 为什么-T graphic_2d能“编译整个部件”(对比说明)

foundation/graphic/graphic_2d/bundle.json中可见(组件名 + 子系统):

"component": { "name": "graphic_2d", "subsystem": "graphic", "syscap": [

当一个部件被纳入产品配置后,构建系统通常会在build.ninja里为其生成一个同名的顶层聚合目标(phony)。当前 out 目录中存在:

build graphic_2d: phony obj/out/arm64/targets/build_configs/graphic/graphic_2d/graphic_2d.stamp build graphic_2d_info: phony obj/out/arm64/targets/build_configs/graphic/graphic_2d/graphic_2d_info.stamp build graphic_2d_inner_kits: phony obj/out/arm64/targets/build_configs/graphic/graphic_2d/graphic_2d_inner_kits.stamp build graphic_2d_innerkit_remove_check_so: phony obj/out/arm64/targets/build_configs/graphic/graphic_2d/graphic_2d_innerkit_remove_check_so.stamp build graphic_2d_sdk_info: phony obj/out/arm64/targets/build_configs/graphic/graphic_2d/graphic_2d_sdk_info.stamp build graphic_2d_test: phony obj/out/arm64/targets/build_configs/graphic/graphic_2d/graphic_2d_test.stamp

因此执行:

./build.sh --product-name 633_rk3588j_isdt-2 -T graphic_2d

等价于让 ninja 构建这个“部件级 phony target”。该 target 依赖并触发build_configs/.../graphic_2d.stamp,从而把bundle.json里配置的各个 group(base/fwk/service 等)相关目标一并拉起构建——表现上就是“编译整个部件”。

补充关键点:要严格证明“编译整个部件”,需要展开依赖链并确认其覆盖范围。

  • 第一步(聚合目标只依赖一个 stamp)graphic_2d的 phony 依赖graphic_2d.stamp(见上面build graphic_2d: phony ...graphic_2d.stamp)。
  • 第二步(看 stamp 的输入是什么)graphic_2d.stamp的输入里包含graphic_2d_install_modules.json/graphic_2d_dep_modules.json(可以用ninja -t query查看)。
  • 第三步(看 install_modules.json 里列了什么)graphic_2d_install_modules.json明确列出了该部件的模块清单,每条都带module_def(GN label)且part_namegraphic_2d,例如:
[ { "module_def": "//foundation/graphic/graphic_2d/frameworks/opengl_wrapper:EGL(//build/toolchain/ohos:ohos_clang_arm64)", "module_info_file": "obj/foundation/graphic/graphic_2d/frameworks/opengl_wrapper/EGL_module_info.json", "part_name": "graphic_2d", "subsystem_name": "graphic", "toolchain": "//build/toolchain/ohos:ohos_clang_arm64", "toolchain_out_dir": "." }, { "module_def": "//foundation/graphic/graphic_2d/frameworks/opengl_wrapper:GLESv3(//build/toolchain/ohos:ohos_clang_arm64)", "module_info_file": "obj/foundation/graphic/graphic_2d/frameworks/opengl_wrapper/GLESv3_module_info.json", "part_name": "graphic_2d", "subsystem_name": "graphic", "toolchain": "//build/toolchain/ohos:ohos_clang_arm64", "toolchain_out_dir": "." }, { "module_def": "//foundation/graphic/graphic_2d/utils/color_manager:color_manager(//build/toolchain/ohos:ohos_clang_arm64)", "module_info_file": "obj/foundation/graphic/graphic_2d/utils/color_manager/color_manager_module_info.json", "part_name": "graphic_2d", "subsystem_name": "graphic", "toolchain": "//build/toolchain/ohos:ohos_clang_arm64", "toolchain_out_dir": "." }, { "module_def": "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics:2d_graphics(//build/toolchain/ohos:ohos_clang_arm64)", "module_info_file": "obj/foundation/graphic/graphic_2d/rosen/modules/2d_graphics/2d_graphics_module_info.json", "part_name": "graphic_2d", "subsystem_name": "graphic", "toolchain": "//build/toolchain/ohos:ohos_clang_arm64", "toolchain_out_dir": "." }, { "module_def": "//foundation/graphic/graphic_2d/utils/socketpair:socketpair(//build/toolchain/ohos:ohos_clang_arm64)", "module_info_file": "obj/foundation/graphic/graphic_2d/utils/socketpair/socketpair_module_info.json", "part_name": "graphic_2d", "subsystem_name": "graphic", "toolchain": "//build/toolchain/ohos:ohos_clang_arm64", "toolchain_out_dir": "." }, // ... 后续还有大量 graphic_2d 部件内模块 ... ]

因此,“-T graphic_2d会编译整个部件”的更严格表述为:

  • -T graphic_2d会触发部件级 phony → 部件 stamp → 部件模块清单(install_modules.json)这条链路;
  • install_modules.json枚举了该部件内的模块(module_def),构建系统据此拉起这些模块的编译/安装信息生成;
  • 所以它的效果等价于“把 graphic_2d 部件配置覆盖的模块整体拉起来构建”,而不是只编单个.so

对比camera_framework:可用 grep 验证当前build.ninja没有build camera_framework: phony ...这种顶层部件目标:

grep-n'^build camera_framework:'/root/633/out/arm64/targets/build.ninja

因此-T camera_framework会失败,需要改用带路径的目标(如foundation/.../camera:camera_framework)或直接编库产物(如multimedia/camera_framework/libcamera_framework.z.so)。

1.3.3 归纳:何时可以“直接用名字 -T”构建(必要条件)

  • 按“部件名”构建整个部件(例如-T graphic_2d

    • 一般规律:若部件名在该部件的构建命名空间中不与部件内其它 GN 目标短名冲突,构建系统往往会生成同名的顶层聚合目标(build <part_name>: phony ...),从而支持-T <part_name>直接构建整个部件。
    • 必要条件(可验证):当前build.ninja中确实存在build <part_name>: phony ...这一类短名目标。
    • 冲突提示:当部件名与部件内某个 GN 目标短名同名(例如部件名camera_framework,部件内又存在ohos_shared_library("camera_framework")),为避免短名歧义,顶层短名聚合目标可能不会生成;此时通常会生成“带路径的部件聚合目标”,例如build out/.../build_configs/<subsystem>/<part>$:<part>: phony ...,需要用该目标来编整个部件。
  • 按“GN 目标短名”构建单个目标(例如-T <target_name>

    • 必要条件:当前build.ninja中存在名为<target_name>的可构建 target,且无歧义。
    • 更稳妥做法:直接使用“带路径的 target”(path:target形式)进行构建,避免短名不存在或重名导致unknown target/歧义。

结论:是否能用短名-T,最终以build.ninja中是否存在对应 target为准;可用grep '^build <name>:' build.ninjaninja -t targets验证。

1.4 常见误用:从 build.ninja 直接复制$:写法到命令行(“二级坑”:$:转义)

常见误用命令如下:

./build.sh --product-name 633_rk3588j_isdt-2\-T'foundation/multimedia/camera_framework/frameworks/native/camera$:camera_framework'

该写法会报错,因为build.ninja文件里为了表达字面量:,会写成$:;但命令行里 target 名应使用真实的冒号:。即:

  • .../camera$:camera_framework(build.ninja 内部写法)
  • .../camera:camera_framework(命令行应使用)

一句话总结:

  • 从 build.ninja 复制目标名时:把$:还原为:;把行末续行用的$去掉。

2. 解决方案:如何正确编译“部件 target”与“库 target”

编译部件聚合 target(phony)

✅ 编译整个camera_framework部件(部件级 build_configs 聚合 target):

./build.sh --product-name 633_rk3588j_isdt-2\-T'out/arm64/targets/build_configs/multimedia/camera_framework:camera_framework'

build.ninja中对应的目标定义为:

build out/arm64/targets/build_configs/multimedia/camera_framework$:camera_framework: phony obj/out/arm64/targets/build_configs/multimedia/camera_framework/camera_framework.stamp build out/arm64/targets/build_configs/multimedia/camera_framework: phony obj/out/arm64/targets/build_configs/multimedia/camera_framework/camera_framework.stamp

out/arm64/targets/build_configs/multimedia/camera_framework/BUILD.gn可以作为**辅助判断“部件构建名”**的依据:直接查看其中的ohos_part("<构建名>")(例如ohos_part("camera_framework"))即可确认该部件的聚合目标名称,并可顺带确认该部件聚合的模块清单(module_list)。

进一步推导:

  • 若对源码目录/子系统划分比较熟悉,可直接在out/arm64/targets/build_configs/<subsystem>/<part>/下通过“目录定位”快速确认部件的聚合构建名(以ohos_part("<构建名>")为准),再回到build.ninja验证其是否已生成对应的 Ninja target。
  • 推荐使用带路径的 target(例如out/.../build_configs/...:camera_framework);但在少数场景下build.ninja会额外提供短名别名(如graphic_2d),此时也可直接用短名进行-T构建。

但需要区分清楚:-T的参数必须是Ninja target 名,而不是某个BUILD.gn的文件路径。构建整个部件时使用的是build.ninja里已经生成出来的聚合目标out/arm64/targets/build_configs/multimedia/camera_framework:camera_frameworkphony -> *.stamp)。

该 target 名的来源:在633/out/arm64/targets/build.ninja中搜索build_configs/multimedia/camera_framework,可直接命中build out/arm64/targets/build_configs/multimedia/camera_framework$:camera_framework: phony ...;命令行使用时把$:还原为:,得到可用于-T的 target。

✅ 编译单个 GN 模块//foundation/multimedia/camera_framework/frameworks/native/camera:camera_framework(对应libcamera_framework.z.so):

./build.sh --product-name 633_rk3588j_isdt-2\-T'foundation/multimedia/camera_framework/frameworks/native/camera:camera_framework'

❌ 错误(把 build.ninja 内部转义写法$:原样拿去当 target):

./build.sh --product-name 633_rk3588j_isdt-2\-T'foundation/multimedia/camera_framework/frameworks/native/camera$:camera_framework'

编译库产物 target(.z.so)

./build.sh --product-name 633_rk3588j_isdt-2\-T multimedia/camera_framework/libcamera_framework.z.so

同时编“部件 + 库”(一次命令)

-T/--build-target支持指定多个(build 系统里明确支持),所以可以一次编两个目标。

./build.sh --product-name 633_rk3588j_isdt-2\-T'foundation/multimedia/camera_framework/frameworks/native/camera:camera_framework'\-T multimedia/camera_framework/libcamera_framework.z.so

3. build.ninja 是怎么产生的(生成链路)

OpenHarmony 的构建大体分为:

  • preloader / loader:解析产品配置、子系统/部件/模块信息
  • gn:执行gn gen生成 Ninja 构建文件(核心产物就是build.ninja
  • ninja:根据build.ninja的规则执行实际编译/链接

在仓内文档build/docs/how-to-add-a-build-parameter.md里明确写到:

“执行 gn gen 编译命令,产生的 build.ninja 文件可以类比与 makefile 文件。”

build/hb/services/gn.py中也可以看到gn gen的执行方式(hb 调用 gn)大体就是:

  • 组装gn gen ... <out_dir>命令
    • out 目录即self.config.out_path(对应out/arm64/targets这一类产物目录)

结论:

  • /root/633/out/arm64/targets/build.ninjaGN 阶段gn gen)生成的;
  • 后续ninja -C /root/633/out/arm64/targets ...读取它来执行编译。

4. build.ninja 的语法规则:建议掌握的核心要点

build行:定义一个“可构建目标”

最重要的一句:

build <输出target>: <rule> <输入依赖...>
  • <输出target>:这个字符串就是 Ninja 的target 名(可被构建/被依赖)。
  • <rule>:使用哪个规则来生成它。

rule:规则定义(编译/链接/拷贝等)

build.ninja里会有很多rule xxx,比如编译 C/C++ 的、链接 so 的等。

在“判断目标类型/行为”时,更关键的是build 行里使用的 rule 名字

  • phony聚合/别名 target,它本身不产生文件,只是把依赖串起来。
  • 其他(例如cxx/cc/alink/solink/stamp等):一般对应真实动作。
    • stamp常见于“收集/检查/notice”等阶段性标记文件(*.stamp)。

注意:不同产品/工具链生成的 rule 命名可能略有差异,但phony的语义是 Ninja 固定语法。

$在 Ninja 里的两种常见用法:行末续行 vs$:转义

在 Ninja 语法里,$最常见有两种用途,千万别混淆:

  • 行末$:续行符(line continuation),表示这一行还没写完,下一行继续。
  • $::转义后的冒号:。因为:build <out>: <rule>里有语法含义,如果目标名本身包含冒号(例如 GN label 形式path:target),Ninja 文件里会把这个冒号写成$:来避免歧义。

典型例子是all目标的依赖列表非常长,因此会写成:

build all: phony $ obj/.../xxx.stamp $ multimedia/camera_framework/libcamera_framework.z.so $ obj/.../yyy.stamp $ ...

这里的含义是:

  • build all: phony $:定义了一个all聚合目标
  • 后续每一行(缩进的)都是all的依赖
  • 每行末尾$表示依赖列表继续(不是 target 名的一部分)

因此可以看到(行末$):

multimedia/camera_framework/libcamera_framework.z.so $

应当理解为:

  • 真实 target 名multimedia/camera_framework/libcamera_framework.z.so
  • 行末$:仅表示“下一行还有依赖项”,不是 target 名的一部分

另外还有一种常见$用法:$:转义。build.ninja中会出现这种形式:

build foundation/multimedia/camera_framework/frameworks/native/camera$:camera_framework: phony multimedia/camera_framework/libcamera_framework.z.so

这行里camera$:camera_framework的含义是:

  • Ninja 文件内部写法camera$:camera_framework
  • 真实 target 名(命令行/日志里应使用)camera:camera_framework

结论:命令行里不要带$:,需要把$:还原成:。否则会触发unknown target报错。

unknown target '...camera$:camera_framework', did you mean '...camera:camera_framework'?


5. camera_framework 这种“多形态 target”怎么区分:部件 vs 库

核心问题在于:camera_framework在多个层面都有名字:

  • GN target 名(path:target形式)
  • 部件/模块聚合目标(通常是phony
  • 真实产物(.z.so/.so/ 可执行程序等)

部件/聚合 target(phony)

build.ninja中可以找到如下示例(注意这里的$:是 Ninja 文件里的转义写法):

build foundation/multimedia/camera_framework/frameworks/native/camera$:camera_framework: phony multimedia/camera_framework/libcamera_framework.z.so

解读:

  • build.ninja 内部写法foundation/multimedia/camera_framework/frameworks/native/camera$:camera_framework
  • 真实 target 名(命令行应使用)foundation/multimedia/camera_framework/frameworks/native/camera:camera_framework
  • 规则:phony(说明这就是“别名/聚合目标”)
  • 它依赖的真实产物:multimedia/camera_framework/libcamera_framework.z.so

库产物 target(真实 so 输出名)

all目标的依赖清单中也能看到库产物本身:

multimedia/camera_framework/libcamera_framework.z.so $

这类.so(或.z.so)通常才是期望的“真实编译结果/链接结果”。

常见疑问:为什么 grep^build multimedia/camera_framework/libcamera_framework.z.so:有时找不到?

  • 因为不同生成策略下,.so可能是最终输出,也可能还会经过 wrapper/重命名/打包步骤;
  • 更稳妥的方法是用ninja -t query来追溯它的生成规则(见下文第 7 节)。

6. 在 build.ninja 里“怎么搜”:推荐的定位套路

只看 target 定义:搜^build

找 camera_framework 相关定义(最快):

grep-n"^build .*camera_framework"/root/633/out/arm64/targets/build.ninja|head-n50

通常会看到两类信息:

  • ...$:camera_framework: phony ...(部件/聚合;$:是 build.ninja 内部转义,命令行要还原成:
  • ...camera_framework__check/__collect/__notice...(一般是 stamp 相关目标)

想知道某个库是否进入“全量编译”:看build all

all目标基本代表“全量构建入口”,做全量编译时会走到它依赖的所有项。

可按如下方式搜索all

grep-n"^build all:"/root/633/out/arm64/targets/build.ninja

然后在build all的依赖区域进一步 grep:

grep-n"multimedia/camera_framework/libcamera_framework.z.so"/root/633/out/arm64/targets/build.ninja

注意:build all的依赖非常长,直接打开文件会很难读;用 grep 定位行号再看局部上下文更高效。


7. 不要“盲 grep”:用 ninja 自带工具精确查 target(推荐)

Ninja 提供了非常实用的“自省”命令,比直接肉眼阅读build.ninja更稳定:

列出所有 target(然后 grep 关注项)

说明:当前环境里系统ninja可能不在 PATH,建议直接用预置 ninja:/root/633/prebuilts/build-tools/linux-x86/bin/ninja
另外,out 目录可能存在重复规则,-t targets建议加-w dupbuild=warn以避免直接报错中断。

/root/633/prebuilts/build-tools/linux-x86/bin/ninja -wdupbuild=warn\-C /root/633/out/arm64/targets -t targets all|grepcamera_framework|head-n50

该步骤最适合解决以下问题:

  • unknown target 'camera_framework'(说明传入的不是 Ninja 目标名)
  • “同名太多不知道选哪个”

查询某个 target 的生成关系(追溯它由谁生成)

/root/633/prebuilts/build-tools/linux-x86/bin/ninja -wdupbuild=warn\-C /root/633/out/arm64/targets -t query multimedia/camera_framework/libcamera_framework.z.so

该命令会输出:

  • 这个输出由哪个 rule 生成(例如链接/拷贝)
  • 它依赖了哪些输入(对象文件、其他库、stamp 等)

这一步是“找真实编译规则”的最可靠方式。


8. 用 build.sh 精准编译:部件名 vs 库名(camera_framework 示例)

先确认:-T/--build-target支持指定多个

仓内build/README_zh.md明确写了:

  • -T BUILD_TARGET, --build-target=BUILD_TARGET # 指定编译目标,可以指定多个

并且build/scripts/entry.py里参数解析也是:

  • parser.add_option('-T', '--build-target', action='append', default=[])

结论:-T支持重复传参,从而在一次构建中同时指定多个目标。

说明:本节与第 2 节避免重复

本节的“部件/库/同时编译”命令已在本文第 2 节给出(避免重复)。


9. 常见坑位速查

unknown target 'camera_framework'

原因:

  • 传入的是部件/模块在 bundle.json 里的名字,而不是 Ninja 的 target 名。

解决:

  • ninja -t targets all | grep camera_framework找到真实 target(通常是path:target或具体产物路径)。
  • 如果目标名来自build.ninja的复制:需要先把$:还原为:

修改out/.../build_configs/.../BUILD.gn后出现 “Regenerating ninja files / Unresolved dependencies”

原因:

  • out/arm64/targets/build_configs/<subsystem>/<part>/BUILD.gn属于 GN 构建图的输入(很多场景下还是生成物)。改动其中的ohos_part("<构建名>")/依赖列表,可能导致gn gen重建build.ninja时出现依赖无法解析,从而使构建直接失败。

建议:

  • 该类文件用于“辅助定位/确认部件聚合目标与模块清单”即可;需要改动部件构建配置时,应回溯并修改上游生成来源(例如产品配置、bundle/部件配置、loader 生成逻辑),再重新生成 out。

从 build.ninja 复制目标名:记得把$:还原为:

例如 build.ninja 里写:

  • foundation/.../camera$:camera_framework

命令行里应使用:

  • foundation/.../camera:camera_framework

“这行只有xxx.z.so $,找不到build xxx.z.so: ...

解释:

  • 这行很可能只是all的依赖项之一(依赖列表里出现),不代表它的build规则一定就在附近。

解决:

  • 优先使用ninja -t query xxx.z.so追溯生成链路;
  • 或者 grep 整个文件的build头:grep -n "^build .*xxx\.z\.so" ...(注意有时输出名会被包装/重命名)。

10. 建议的“实战操作流程”(最省时间)

  1. 列出所有相关 targets:
/root/633/prebuilts/build-tools/linux-x86/bin/ninja -wdupbuild=warn\-C /root/633/out/arm64/targets -t targets all|grepcamera_framework
  1. 对目标做 query,确认其类型(phony 还是产物):
/root/633/prebuilts/build-tools/linux-x86/bin/ninja -wdupbuild=warn\-C /root/633/out/arm64/targets -t query'foundation/multimedia/camera_framework/frameworks/native/camera:camera_framework'/root/633/prebuilts/build-tools/linux-x86/bin/ninja -wdupbuild=warn\-C /root/633/out/arm64/targets -t query multimedia/camera_framework/libcamera_framework.z.so
  1. build.sh -T精准编译(注意$转义):
./build.sh --product-name 633_rk3588j_isdt-2\-T'foundation/multimedia/camera_framework/frameworks/native/camera:camera_framework'

11. 附:快速理解 “部件 target” 为啥在 build.ninja 里长得像...$:camera_framework

这类...$:形式并不是“目标名里真的有$”,而是 Ninja 为了表达path:target这种包含冒号的 label,在build.ninja文件中使用的转义写法($:表示字面量:)。

因此在需要“按模块/部件维度构建”时,通常应使用完整路径 + 冒号 + target 名的形式,而不是只写短名字。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询