blob: afab4d68d0be28a41de1c2351700f4996386edd4 [file] [log] [blame]
<html devsite><head>
<title>原生库的命名空间</title>
<meta name="project_path" value="/_project.yaml"/>
<meta name="book_path" value="/_book.yaml"/>
</head>
<body>
<!--
Copyright 2017 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>
Android 7.0 推出了针对原生库的命名空间,旨在限制内部 API 可见性,并解决应用在使用平台库(而非它们自己的库)时意外终止的问题。请参阅<a href="http://android-developers.blogspot.com/2016/06/improving-stability-with-private-cc.html">通过 Android 7.0 中的私有 C/C++ 符号限制提升稳定性</a>这篇 Android 开发者博文,了解针对应用的更改。</p>
<h2 id="architecture">架构</h2>
<p>
这项更改会将系统库与应用库分离开来,从而很大程度上避免意外使用内部系统库(反之亦然)。
</p>
<img src="images/namespace-libraries.png" alt="原生库的命名空间" id="namespace-libraries"/>
<p class="img-caption">
<strong>图 1.</strong> 原生库的命名空间
</p>
<p>
原生库的命名空间可防止应用使用私有平台的原生 API(例如使用 OpenSSL)。它还可以避免应用在使用平台库(而非它们自己的库)时出现意外终止的情况(如使用 <code>libpng</code> 时)。
</p>
<h2 id="adding-additional-native-libraries">添加其他原生库</h2>
<p>
除了标准的公共原生库之外,芯片供应商(从 Android 7.0 起)和设备制造商(从 Android 9 起)还可以选择提供可供应用访问的其他原生库,方法是将它们放在相应的库文件夹中,并在 .txt 文件中明确列出它们。
</p>
<p>库文件夹是:</p>
<ul>
<li><code>/vendor/lib</code>(对于芯片供应商的 32 位库)和 <code>/vendor/lib64</code>(对于芯片供应商的 64 位库)</li>
<li><code>/system/lib</code>(对于设备制造商的 32 位库)和 <code>/system/lib64</code>(对于设备制造商的 64 位库)</li>
</ul>
<p>.txt 文件是:</p>
<ul>
<li><code>/vendor/etc/public.libraries.txt</code>(对于芯片供应商的库)</li>
<li><code>/system/etc/public.libraries-COMPANYNAME.txt</code>(对于设备制造商的库),其中 <code>COMPANYNAME</code> 指的是制造商的名称(例如 <code>awesome.company</code>)。<code>COMPANYNAME</code> 应该匹配 <code>[A-Za-z0-9_.-]+</code>; 字母数字字符、_、.(点)和 -。如果某些库来自外部解决方案提供商,则可以在设备中包含多个此类 .txt 文件。
</li></ul>
<p>
<strong>必须</strong><code>system</code> 分区内由设备制造商公开的原生库命名为 <code>lib*COMPANYNAME.so</code>,例如 <code>libFoo.awesome.company.so</code>。换句话说,没有公司名称后缀的 <code>libFoo.so</code> 不得公开。库文件名中的 <code>COMPANYNAME</code> 必须与列出库名称的 txt 文件的名称中的 <code>COMPANYNAME</code> 匹配。
</p>
<p>
作为 AOSP 一部分的原生库不得公开(默认情况下公开的标准公共原生库除外)。只有芯片供应商或设备制造商添加的其他库可供应用访问。
</p>
<p>
从 Android 8.0 开始,供应商的公共库需要遵循以下额外限制,并需要进行设置:
</p>
<ol>
<li>供应商的原生库必须添加适当的标签,以供应用访问。如有任何应用(包括第三方应用)要求访问原生库,则该库必须在供应商特定的 <code>file_contexts</code> 文件中标记为 <code>same_process_hal_file</code>,具体如下所示:
<pre class="devsite-click-to-copy">/vendor/lib(64)?/libnative.so u:object_r:same_process_hal_file:s0</pre>
其中,<code>libnative.so</code> 为原生库的名称。
</li>
<li>库不得依赖(无论是直接依赖,还是通过其依赖项间接依赖)VNDK-SP 库和 LLNDK 库之外的任何系统库。您可以在 <code>development/vndk/tools/definition/tool/datasets/eligible-list-&lt;version&gt;-release.csv</code> 中找到 VNDK-SP 库和 LLNDK 库的列表。
</li>
</ol>
<h2 id="updating-app-non-public">将应用更新为不使用非公共原生库</h2>
<p>
仅针对 SDK 版本为 24 或更高版本的应用启用此功能;要了解向后兼容性,请参阅<a href="http://android-developers.blogspot.com/2016/06/improving-stability-with-private-cc.html">表 1. 当应用关联到私有原生库时会发生什么情况</a>。可供应用访问的 Android 原生库(又称为公共原生库)列表列于 CDD 部分 3.1.1。适用于版本 24 或更高版本且使用任何非公共库的应用应进行更新。要了解详情,请参阅<a href="https://developer.android.com/preview/behavior-changes.html#ndk">关联到平台库的 NDK 应用</a>
</p>
</body></html>