blob: f230e23a9c62a92fb4b5efdbfa02674bfd9df616 [file] [log] [blame]
<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_&lt;ARCH&gt;_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>&lt;Android Version&gt;-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_&lt;ARCH&gt;_ab-user
$ m -j vndk dist
</pre>
</li>
</ul>
<p>
相应的 <code>android-vndk-&lt;ARCH&gt;.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&lt;VER&gt;</code> 下的源代码树,其中 <code>&lt;VER&gt;</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&lt;VER&gt;</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 &lt;VER&gt; --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&lt;VER&gt;</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/&lt;board&gt;/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>&lt;CODE_NAME&gt;</td>
<td>&lt;CODE_NAME&gt;</td>
<td>/system/lib[64]/vndk[-sp]-&lt;CODE_NAME&gt;</td>
</tr>
<tr>
<td>之后</td>
<td>&lt;SDK_ver&gt;</td>
<td>&lt;SDK_ver&gt;</td>
<td>/system/lib[64]/vndk[-sp]-&lt;SDK_ver&gt;</td>
</tr>
<tr>
<td>预编译的快照模块</td>
<td>&lt;VNDK_ver&gt;<br />(用于快照)</td>
<td>之前或之后</td>
<td>&lt;CODE_NAME&gt;<br />或 &lt;SDK_ver&gt;</td>
<td>&lt;VNDK_ver&gt;</td>
<td>/system/lib[64]/vndk[-sp]-&lt;VNDK_ver&gt;</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>