| <html devsite><head> |
| <title>生成 VNDK 快照</title> |
| <meta name="project_path" value="/_project.yaml"/> |
| <meta name="book_path" value="/_book.yaml"/> |
| </head> |
| |
| <body> |
| <!-- |
| Copyright 2018 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <p> |
| VNDK 快照是一组适用于 Android 版本的 VNDK-core 和 VNDK-SP 库。如果 system.img 包含 vendor.img 所需的相应 VNDK 快照,那么,您只能升级系统分区。 |
| </p> |
| |
| <aside class="note"><strong>注意</strong>:本页提供了关于编译和更新 VNDK 快照的设计细节。要详细了解 VNDK 快照的背景、定义和用例,请参阅 <a href="/devices/architecture/vndk/snapshot-design">VNDK 快照设计</a>。 |
| </aside> |
| |
| <p> |
| 正式的 VNDK 快照是在 Android 编译服务器上自动编译而成,并签入 Android 源代码树的 <code>/prebuilts/vndk</code> 中。为了便于开发,您可以在本地编译 VNDK 快照。arm、arm64、x86 和 x86_64 TARGET_ARCH 架构支持 VNDK 快照。 |
| </p> |
| |
| <h2 id="snapshot-build-artifacts">快照编译工件</h2> |
| |
| <p> |
| Android 编译服务器使用以下编译参数和编译命令,生成适用于 VNDK 快照的编译工件。 |
| </p> |
| |
| <h3 id="build-parameters">编译参数</h3> |
| |
| <p> |
| 编译目标名称为 <code>vndk</code>,编译目标配置如下所示: |
| </p> |
| |
| <ul> |
| <li>TARGET_PRODUCT=aosp_{TARGET_ARCH}_ab</li> |
| <li>TARGET_BUILD_VARIANT=user</li> |
| <li>TARGET_ARCH。与常规系统映像 (GSI) 目标架构(arm、arm64、x86、x86_64)相同。</li> |
| <li>TARGET_ARCH_VARIANT。对于快照 v27 (Android 8.1),变体包含热门配置(如下所示);未来版本可能会包含其他 arch/cpu 变体。</li> |
| </ul> |
| |
| <table> |
| <thead> |
| <tr> |
| <th>TARGET_PRODUCT</th> |
| <th>TARGET_ARCH</th> |
| <th>TARGET_ARCH_VARIANT</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>aosp_arm_ab</td> |
| <td>arm</td> |
| <td>armv7-a-neon</td> |
| </tr> |
| <tr> |
| <td>aosp_arm64_ab</td> |
| <td>arm64</td> |
| <td>armv8-a</td> |
| </tr> |
| <tr> |
| <td>aosp_x86_ab</td> |
| <td>x86</td> |
| <td>x86</td> |
| </tr> |
| <tr> |
| <td>aosp_x86_64_ab</td> |
| <td>x86_64</td> |
| <td>x86_64</td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <h3 id="build-commands">编译命令</h3> |
| |
| <p> |
| 对于正式快照,Android 9 在 <a href="https://android.googlesource.com/platform/build/+/master/core/tasks/vndk.mk">vndk.mk</a> 中引入了新的虚拟目标 (<code>vndk</code>),该目标会编译 VNDK 快照并将其输出到 <code>$DIST_DIR</code> 中。快照的 ZIP 文件采用 <code>android-vndk-{TARGET_ARCH}.zip</code> 格式。例如: |
| </p> |
| |
| <pre class="prettyprint"> |
| $ lunch aosp_<ARCH>_ab-user |
| $ make -j vndk dist [BOARD_VNDK_VERSION=current] |
| </pre> |
| |
| <p> |
| Android 编译服务器通过以下命令使用 <a href="https://android.googlesource.com/platform/development/+/master/vndk/snapshot/build.sh">build.sh</a> 脚本来编译所有受支持的架构类型: |
| </p> |
| |
| <pre class="prettyprint"> |
| $ DIST_DIR=%dist_dir% development/vndk/snapshot/build.sh |
| </pre> |
| |
| <p> |
| Android 版本的 VNDK 快照由 <code><Android Version>-release</code> 分支生成。 |
| </p> |
| |
| <h3 id="build-locally">在本地编译</h3> |
| |
| <p> |
| 在开发过程中,您可以通过以下命令,从本地源代码树中编译 VNDK 快照:</p> |
| |
| <ul> |
| <li>要一次编译所有受支持的架构,请通过以下命令执行编译脚本 (<code>build.sh</code>):<pre class="prettyprint"> |
| $ cd $ANDROID_BUILD_TOP |
| $ development/vndk/snapshot/build.sh |
| </pre> |
| </li> |
| <li>要编译某个特定的 TARGET_ARCH,请执行以下命令: |
| |
| <pre class="prettyprint"> |
| $ lunch aosp_<ARCH>_ab-user |
| $ m -j vndk dist |
| </pre> |
| </li> |
| </ul> |
| |
| <p> |
| 相应的 <code>android-vndk-<ARCH>.zip</code> 文件会在 <code>$DIST_DIR</code> 下创建。 |
| </p> |
| |
| <h2 id="snapshot-files">快照文件</h2> |
| |
| <p> |
| VNDK 快照包含以下文件: |
| </p> |
| |
| <ul> |
| <li>VNDK-core 和 VNDK-SP 共享库的供应商变体。 |
| <ul> |
| <li>无需 LL-NDK 共享库,因为这类库是向后兼容的。</li> |
| <li>对于 64 位目标,TARGET_ARCH 和 TARGET_2ND_ARCH 库都将被编译并包含在内。</li> |
| </ul> |
| </li> |
| <li>VNDK-core、VNDK-SP、LL-NDK 和 VNDK-private 库的列表位于 <code>[vndkcore|vndksp|llndk|vndkprivate].libraries.txt</code>。</li> |
| <li>链接器配置文件为 <code>ld.config.txt</code>。</li> |
| <li>许可文件。</li> |
| <li><code>module_paths.txt</code>。记录所有 VNDK 库的模块路径;检查 GPL 项目是否已在指定 Android 源代码树中发布源代码时,需要用到这种文件。</li> |
| </ul> |
| |
| <p> |
| 对于指定 VNDK 快照 ZIP 文件 <code>android-vndk-{TARGET_ARCH}.zip</code>,系统会根据 ABI 位数将 VNDK 预编译库分组到名为 <code>arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}</code> 的单独目录中。例如,对于 <code>android-vndk-arm64.zip</code>,64 位库会位于 <code>arch-arm64-armv8-a</code> 下,而 32 位库则位于 <code>arch-arm-armv8-a</code> 下。 |
| </p> |
| |
| <h3 id="example-snapshot-dir-structure">示例:VNDK 快照目录结构</h3> |
| |
| <p> |
| 以下示例展示了 arm64 (<code>TARGET_ARCH=arm64</code>) VNDK 快照 ZIP 文件 (<code>android-vndk-arm64.zip</code>) 的目录结构。 |
| </p> |
| |
| <img src="/devices/architecture/images/vndk_snapshot_directory.png"/> |
| <figcaption><strong>图 1. </strong>VNDK 快照目录结构(示例)</figcaption> |
| |
| <h2 id="upload-vndk-snapshots">上传 VNDK 快照</h2> |
| |
| <p> |
| VNDK 快照将签入 <code>/prebuilts/vndk/v<VER></code> 下的源代码树,其中 <code><VER></code> 为 VNDK 快照的版本(遵循相应 Android 版本的 SDK 版本)。例如,O MR1 VNDK 快照的版本为 27。 |
| </p> |
| |
| <h3 id="using-update-py">使用 update.py 脚本</h3> |
| |
| <p> |
| <code>update.py</code> 脚本 (<code>/development/vndk/snapshot/update.py)</code> 可自动将预编译的 VNDK 快照添加到源代码树中。此脚本将执行以下任务:</p> |
| |
| <ol> |
| <li>在 <code>/prebuilts/vndk/v<VER></code> 中,使用 <code>repo start</code> 创建新的 git 分支。</li> |
| <li>获取 VNDK 快照编译软件工件并将其解压缩。</li> |
| <li>运行 <code>gen_buildfiles.py</code> 以自动生成编译文件(<code>Android.mk</code>、<code>Android.bp</code>)。</li> |
| <li>运行 <code>check_gpl_license.py</code> 以验证根据通用公共许可证 (GPL) 获得许可的预编译库是否在当前源代码树中发布了源代码。</li> |
| <li>使用 <code>git commit</code> 提交新的更改。</li> |
| </ol> |
| |
| <h3 id="using-local-snapshots">使用本地编译的 VNDK 快照</h3> |
| |
| <p> |
| 在开发过程中,您可以使用本地编译的 VNDK 快照进行测试。在指定 <code>--local</code> 选项的情况下,<code>update.py</code> 会从本地 <code>$DIST_DIR</code>(而非 Android 编译服务器中)提取 VNDK 快照编译工件。用法如下: |
| </p> |
| |
| <pre class="prettyprint"> |
| $ python update.py <VER> --local |
| </pre> |
| |
| <p> |
| 例如,要使用本地编译软件工件更新 O MR1 VNDK 快照,请运行以下命令: |
| </p> |
| |
| <pre class="prettyprint"> |
| $ python update.py 27 --local |
| </pre> |
| |
| <p> |
| 由于本地模式仅用于测试,因此该脚本将跳过 GPL 许可检查和 git commit 步骤。 |
| </p> |
| |
| <h3 id="dir-structure-prebuilts">prebuilts/vndk 的目录结构</h3> |
| |
| <img src="/devices/architecture/images/vndk_snapshot_prebuilt.png"/> |
| <figcaption><strong>图 2. </strong>Prebuilts/vndk 目录结构</figcaption> |
| |
| <h2 id="install-vndk-snapshot">安装 VNDK 快照</h2> |
| |
| <p> |
| 系统映像在编译时使用 <code>BOARD_VNDK_VERSION</code>、<code>PRODUCT_EXTRA_VNDK_VERSIONS</code> 和 <code>ro.vndk.version</code> 中的信息安装 VNDK 快照库。您可以使用以下选项之一控制从 <code>/prebuilts/vndk/v<VER></code> 中安装哪些 VNDK 快照: |
| </p> |
| |
| <ul> |
| <li><strong>选项 1</strong>:<code>BOARD_VNDK_VERSION</code>。使用快照模块编译当前供应商模块,并仅安装供应商模块所需的快照模块。</li> |
| <li><strong>选项 2</strong>:<code>PRODUCT_EXTRA_VNDK_VERSIONS</code>。无论当前供应商模块有哪些,都安装 VNDK 快照模块。这将安装 <code>PRODUCT_EXTRA_VNDK_VERSIONS</code> 中列出的预编译 VNDK 快照,而不会在编译时将其与任何其他模块相关联。</li> |
| </ul> |
| |
| <h3 id="set-board-vndk">设置 BOARD_VNDK_VERSION</h3> |
| |
| <p> |
| <code>BOARD_VNDK_VERSION</code> 显示的是当前供应商模块需要编译的 VNDK 版本。如果 <code>BOARD_VNDK_VERSION</code> 在 <code>/prebuilts/vndk</code> 目录中有可用的 VNDK 快照版本,则系统会安装 <code>BOARD_VNDK_VERSION</code> 中指明的 VNDK 快照。如果目录中的 VNDK 快照不可用,则会出现编译错误。 |
| </p> |
| |
| <p> |
| 定义 <code>BOARD_VNDK_VERSION</code> 也会启用要安装的 VNDK 模块。供应商模块会在编译时与 <code>BOARD_VNDK_VERSION</code> 中定义的 VNDK 快照版本相关联(此操作不会在系统源代码中编译当前的 VNDK 模块)。从代码库中下载完整的源代码树时,系统源代码和供应商源代码均基于相同的 Android 版本。 |
| </p> |
| |
| <aside class="note"><strong>注意</strong>:供应商模块使用的是系统源代码树的当前 VNDK 版本,因此,您必须将 <code>BOARD_VNDK_VERSION</code> 设置为 <code>current</code>。 |
| </aside> |
| |
| <h3 id="set-product-extra">设置 PRODUCT_EXTRA_VNDK_VERSIONS</h3> |
| |
| <p> |
| <code>PRODUCT_EXTRA_VNDK_VERSIONS</code> 列出了要安装的其他 VNDK 版本。正常情况下,当前的供应商分区只需一个 VNDK 快照就足够了。不过,在某些情况下,您可能需要在一个系统映像中提供多个快照。例如,常规系统映像 (GSI) 具有多个快照,以通过一个系统映像支持多个供应商版本。设置 <code>PRODUCT_EXTRA_VNDK_VERSIONS</code> 后,除了 <code>BOARD_VNDK_VERSION</code> 中的 VNDK 版本之外,您还可以安装 VNDK 快照模块。 |
| </p> |
| |
| <p> |
| 如果 <code>PRODUCT_EXTRA_VNDK_VERSIONS</code> 具有特定的版本列表,则编译系统会在 <code>prebuilts/vndk</code> 目录中查找版本列表的预编译快照。如果编译系统找到所有列出的快照,便会将这些快照文件安装到每个 <code>out/target/product/<board>/system/lib[64]/vndk[-sp]-${VER}</code> 中。缺少某些版本会导致出现编译错误。 |
| </p> |
| |
| <p> |
| VNDK 模块将不会在编译时与供应商模块相关联,但在运行时可能会使用该模块(如果供应商分区中的供应商模块需要某个已安装的 VNDK 版本)。<code>PRODUCT_EXTRA_VNDK_VERSIONS</code> 仅在指定了 <code>BOARD_VNDK_VERSION</code> 的情况下才有效。例如,要将 O MR1 VNDK 快照安装到 system.img 中,请运行以下命令: |
| </p> |
| |
| <pre class="prettyprint"> |
| $ m -j PRODUCT_EXTRA_VNDK_VERSIONS=27 |
| </pre> |
| |
| <h3 id="platform-vndk">PLATFORM_VNDK_VERSION</h3> |
| |
| <p> |
| <code>PLATFORM_VNDK_VERSION</code> 在系统源代码中指定了当前 VNDK 模块的 VNDK 版本。系统会通过以下方式自动设置该值: |
| </p> |
| |
| <ul> |
| <li>在版本发布之前,将 <code>PLATFORM_VNDK_VERSION</code> 设置为 <code>PLATFORM_VERSION_CODENAME</code>。</li> |
| <li>在发布时,将 <code>PLATFORM_SDK_VERSION</code> 复制到 <code>PLATFORM_VNDK_VERSION</code> 中。</li> |
| </ul> |
| |
| <p> |
| 发布 Android 版本后,当前的 VNDK 库会被安装到 <code>/system/lib[64]/vndk-$SDK_VER</code> 和 <code>/system/lib[64]/vndk-sp-$SDK_VER</code>,其中 <code>$SDK_VER</code> 是存储在 <code>PLATFORM_VNDK_VERSION</code> 中的版本。 |
| </p> |
| |
| <h3 id="namespace-config">命名空间配置</h3> |
| |
| <p> |
| 供应商模块使用 <code>/etc/ld.config.${VER}.txt</code>(其中 <code>${VER}</code> 是从 <code>ro.vndk.version</code> 属性中获得的)中的命名空间配置来搜索所需的共享库。命名空间配置中包含带有版本编号的 VNDK 目录,该目录使用以下语法: |
| </p> |
| |
| <ul> |
| <li><code>/system/${LIB}/vndk-%VNDK_VER%</code></li> |
| <li><code>/system/${LIB}/vndk-sp-%VNDK_VER%</code></li> |
| </ul> |
| |
| <p> |
| <code>%VNDK_VER%</code> 在编译时会被替换为 <code>PLATFORM_VNDK_VERSION</code>,这样一来,系统映像便能够为每个 VNDK 版本提供多个快照。 |
| </p> |
| |
| <p> |
| 如果将 <code>BOARD_VNDK_VERSION</code> 设置为 <code>current</code>,则 <code>PLATFORM_VNDK_VERSION</code> 将存储在 <code>ro.vndk.version</code> 中;否则,<code>BOARD_VNDK_VERSION </code> 将存储在 <code>ro.vndk.version</code> 中。<code>PLATFORM_VNDK_VERSION</code> 在 Android 版本发布时会被设置为 SDK 版本;在发布之前,由字母和数字组成的 Android 代码名称会用于 <code>PLATFORM_VNDK_VERSION</code>。</p> |
| |
| <h3 id="summary-vndk-version-settings">VNDK 版本设置摘要</h3> |
| |
| <p> |
| 下表总结了 VNDK 版本设置。 |
| </p> |
| |
| <table> |
| <thead> |
| <tr> |
| <th width="15%">供应商<br />版本</th> |
| <th>开发板<br />版本</th> |
| <th>SDK<br />版本</th> |
| <th>平台<br />版本</th> |
| <th>版本<br />属性</th> |
| <th>安装目录</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td rowspan="2">当前的 VNDK 模块</td> |
| <td rowspan="2"><code>current</code></td> |
| <td>之前</td> |
| <td><CODE_NAME></td> |
| <td><CODE_NAME></td> |
| <td>/system/lib[64]/vndk[-sp]-<CODE_NAME></td> |
| </tr> |
| <tr> |
| <td>之后</td> |
| <td><SDK_ver></td> |
| <td><SDK_ver></td> |
| <td>/system/lib[64]/vndk[-sp]-<SDK_ver></td> |
| </tr> |
| <tr> |
| <td>预编译的快照模块</td> |
| <td><VNDK_ver><br />(用于快照)</td> |
| <td>之前或之后</td> |
| <td><CODE_NAME><br />或 <SDK_ver></td> |
| <td><VNDK_ver></td> |
| <td>/system/lib[64]/vndk[-sp]-<VNDK_ver></td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <ul> |
| <li><strong>开发板版本</strong> (<code>BOARD_VNDK_VERSION</code>):供应商模块需要编译的 VNDK 版本。如果供应商模块可与当前系统模块相关联,则将其设置为 <code>current</code>。</li> |
| <li><strong>平台版本</strong> (<code>PLATFORM_VNDK_VERSION</code>):当前系统模块正在编译的 VNDK 版本(仅在 <code>BOARD_VNDK_VERSION</code> 为当前版本时编译)。</li> |
| <li><strong>版本属性</strong> (<code>ro.vndk.version</code>):一种属性,用于指定 vendor.img 中的二进制文件和库需要运行的 VNDK 版本。该属性存储在<code> /vendor/default.prop</code> 下的 vendor.img 中。</li> |
| </ul> |
| |
| </body></html> |