aboutsummaryrefslogtreecommitdiff
path: root/zh-cn/devices/architecture/vndk/build-system.html
blob: 591669fc163d966276dc956ae3e8a6cef7d2fa78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
<html devsite><head>
    <title>VNDK 编译系统支持</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 8.1 中具有内置的 VNDK 支持。如果启用了 VNDK 支持,编译系统就会检查各模块之间的依赖关系,为供应商模块编译特定于供应商的变体,并自动将这些模块安装到指定目录中。</p>

<p>以下示例演示了基本概念:</p>

<p><img src="../images/treble_vndk_androidbp.png" alt="具有 vendor_available:true 和 vndk.enabled:true 的 libexample"/></p>
<figcaption><strong>图 1.</strong> 启用 VNDK 支持。</figcaption>

<p><code>Android.bp</code> 模块定义定义了一个名为 <code>libexample</code> 的库。<code>vendor_available</code> 属性表示框架模块和供应商模块均可能依赖于 <code>libexample</code>。在本示例中,框架可执行文件 <code>/system/bin/foo</code> 和供应商可执行文件 <code>/vendor/bin/bar</code> 均依赖于 <code>libexample</code>,并且在其 <code>shared_libs</code> 属性中具有 <code>libexample</code>。</p>

<p>如果框架模块和供应商模块均使用 <code>libexample</code>,则编译 <code>libexample</code> 的两个变体。核心变体(以 <code>libexample</code> 命名)由框架模块使用,供应商变体(以 <code>libexample.vendor</code> 命名)由供应商模块使用。</p>

<p>这两个变体将安装到不同的目录中。核心变体将安装到 <code>/system/lib[64]/libexample.so</code> 中。供应商变体将安装到 <code>/system/lib[64]/vndk/libexample.so</code> 中,因为 <code>vndk.enabled</code> 为 <code>true</code>。</p>

<p>有关更多详情,请参阅<a href="#module-definition">模块定义</a>。</p>

<h2 id="configuration">配置</h2>

<p>要为产品设备启用完整编译系统支持,请将 <code>BOARD_VNDK_VERSION</code> 添加到 <code>BoardConfig.mk</code>:</p>

<pre class="prettyprint">BOARD_VNDK_VERSION := current</pre>

<h3 id="migration-notes">迁移备注</h3>

<p>将 <code>BOARD_VNDK_VERSION</code> 添加到 <code>BoardConfig.mk</code> 会产生全局效应。如果是在 <code>BoardConfig.mk</code> 中定义,系统会检查所有模块。没有将违规模块列入黑名单或白名单的机制。建议您在清除所有不必要的依赖项后再添加 <code>BOARD_VNDK_VERSION</code>。</p>

<p>在迁移过程中,您可以通过在环境变量中设置 <code>BOARD_VNDK_VERSION</code> 来测试和编译模块:</p>

<pre class="prettyprint">$ BOARD_VNDK_VERSION=current m module_name.vendor</pre>

<p>而另一个副作用是,默认的全局标头搜索路径会被移除。<em></em>如果启用 <code>BOARD_VNDK_VERSION</code>,则在默认情况下,系统不会添加以下默认标头搜索路径:</p>

<ul>
 <li>frameworks/av/include</li>
 <li>frameworks/native/include</li>
 <li>frameworks/native/opengl/include</li>
 <li>hardware/libhardware/include</li>
 <li>hardware/libhardware_legacy/include</li>
 <li>hardware/ril/include</li>
 <li>libnativehelper/include</li>
 <li>libnativehelper/include_deprecated</li>
 <li>system/core/include</li>
 <li>system/media/audio/include</li>
</ul>

<p>如果某个模块依赖于这些目录中的标头,则其作者必须明确指定与 <code>header_libs</code>、<code>static_libs</code> 和/或 <code>shared_libs</code> 的依赖关系。</p>

<h2 id="module-definition">模块定义</h2>

<p>要使用 <code>BOARD_VNDK_VERSION</code> 编译 Android,开发者必须在 <code>Android.mk</code> 或 <code>Android.bp</code> 中修改其模块定义。本小节介绍了不同种类的模块定义,一些与 VNDK 相关的模块属性,以及在编译系统中实现的依赖性检查。</p>

<h3 id="vendor-modules">供应商模块</h3>

<p>供应商模块是特定于供应商的可执行文件或共享库(必须将这些模块安装到供应商分区中)。在 <code>Android.bp</code> 文件中,供应商模块必须将供应商或专有属性设置为 <code>true</code>。在 <code>Android.mk</code> 文件中,供应商模块必须将 <code>LOCAL_VENDOR_MODULE</code> 或 <code>LOCAL_PROPRIETARY_MODULE</code> 设置为 <code>true</code>。</p>

<p>如果定义了 <code>BOARD_VNDK_VERSION</code>,则编译系统不允许在供应商模块和框架模块之间建立依赖关系。在以下情况下,编译系统会发出错误:</p>

<ul>
 <li>不具有 <code>vendor:true</code> 的模块依赖于具有 <code>vendor:true</code> 的模块,或</li>

 <li>具有 <code>vendor:true</code> 的模块依赖于既不具有 <code>vendor:true</code> 也不具有 <code>vendor_available:true</code> 的非 <code>llndk_library</code> 模块。</li>
</ul>

<p>前面提到的依赖性检查适用于 <code>Android.bp</code> 中的 <code>header_libs</code>、<code>static_libs</code> 和 <code>shared_libs</code>,也适用于 <code>Android.mk</code> 中的 <code>LOCAL_HEADER_LIBRARIES</code>、<code>LOCAL_STATIC_LIBRARIES</code> 和 <code>LOCAL_SHARED_LIBRARIES</code>。</p>

<h3 id="ll-ndk">LL-NDK</h3>

<p>LL-NDK 共享库是具有稳定 ABI 的共享库。框架模块和供应商模块均具有相同的最新实现。对于每个 LL-NDK 共享库,<code>Android.bp</code> 文件中都有 <code>llndk_library</code> 模块定义:</p>

<pre class="prettyprint">llndk_library {
    name: "libvndksupport",
    symbol_file: "libvndksupport.map.txt",
}</pre>

<p>该模块定义指定了模块名称和符号文件,后者描述了应该对供应商模块可见的符号。例如:</p>

<pre class="prettyprint">LIBVNDKSUPPORT {
  global:
    android_load_sphal_library; # vndk
    android_unload_sphal_library; # vndk
  local:
    *;
};</pre>

<p>编译系统会根据符号文件为供应商模块生成存根共享库。如果启用了 <code>BOARD_VNDK_VERSION</code>,供应商模块将与这些存根共享库建立关联。</p>

<p>只有在满足以下条件时,存根共享库中才会包含符号:</p>

<ul>
 <li>它未在以 <code>_PRIVATE</code> 或 <code>_PLATFORM</code> 结尾的部分中定义。</li>

 <li>它不含 <code>#platform-only</code> 标记,并且</li>

 <li>它不含 <code>#introduce*</code> 标记或者该标记与目标匹配。</li>
</ul>

<aside class="note"><strong>注意</strong>:供应商不得定义自己的 LL-NDK 共享库,因为供应商模块无法在常规系统映像 (GSI) 中找到它们。<em></em></aside>

<h3 id="vndk">VNDK</h3>

<p>在 <code>Android.bp</code> 文件中,<code>cc_library</code>、<code>cc_library_static</code>、<code>cc_library_shared</code> 和 <code>cc_library_headers</code> 模块定义支持三个与 VNDK 相关的属性:<code>vendor_available</code>、<code>vndk.enabled</code> 和 <code>vndk.support_system_process</code>。</p>

<p>如果 <code>vendor_available</code> 或 <code>vndk.enabled</code> 为 <code>true</code>,则可以编译两种变体(核心变体和供应商变体)。<em></em><em></em>核心变体应被视为框架模块,而供应商变体应被视为供应商模块。如果某些框架模块依赖于此模块,则会编译核心变体。如果某些供应商模块依赖于此模块,则会编译供应商变体。</p>

<p>编译系统会强制执行以下依赖性检查:</p>

<ul>
 <li>核心变体始终供框架专用,无法供供应商模块访问。</li>

 <li>供应商变体始终无法供框架模块访问。</li>

 <li>供应商变体的所有依赖项(在 <code>header_libs</code>、<code>static_libs</code> 和/或 <code>shared_libs</code> 中指定)必须是 <code>llndk_library</code> 或具有 <code>vendor_available</code> 或 <code>vndk.enabled</code> 的模块。</li>

 <li>如果 <code>vendor_available</code> 为 <code>true</code>,则供应商变体可供所有供应商模块访问。</li>

 <li>如果 <code>vendor_available</code> 为 <code>false</code>,则供应商变体仅可供其他 VNDK 或 VNDK-SP 模块访问(即,具有 <code>vendor:true</code> 的模块无法与 <code>vendor_available:false</code> 模块相关联)。</li>
</ul>

<p>系统将通过以下规则确定 <code>cc_library</code> 或 <code>cc_library_shared</code> 的默认安装路径:</p>

<ul>
 <li>
  将核心变体安装到 <code>/system/lib[64]</code> 中。
 </li>

 <li>
  供应商变体安装路径可能会有所不同:

  <ul>
   <li>
    如果 <code>vndk.enabled</code> 为 <code>false</code>,则将供应商变体安装到 <code>/vendor/lib[64]</code> 中。
   </li>

   <li>
    如果 <code>vndk.enabled</code> 为 <code>true</code>,则 <code>vndk.support_system_process</code> 可以是 <code>true</code> 或 <code>false</code>。

    <ul>
     <li>
      如果 <code>vndk.support_system_process</code> 为 <code>false</code>,则供应商变体将安装到 <code>/system/lib[64]/vndk-${VER}</code> 中。
     </li>

     <li>
      否则,供应商变体将安装到 <code>/system/lib[64]/vndk-sp-${VER}</code> 中。
     </li>
    </ul>
   </li>
  </ul>
 </li>
</ul>

<p>下表总结了编译系统如何处理供应商变体:</p>

<table>
 <tbody><tr>
  <th rowspan="2"><p><code>vendor_available</code></p></th>
  <th colspan="2"><p><code>vndk</code></p></th>
  <th rowspan="2"><p><code>Vendor variant descriptions</code></p></th>
 </tr>

 <tr>
  <th><p><code>enabled</code></p></th>
  <th><p><code>support_same_process</code></p></th>
 </tr>

 <tr>
  <td rowspan="4"><p><code>true</code></p></td>
  <td rowspan="2"><p><code>false</code></p></td>
  <td><p><code>false</code></p></td>
  <td>
   <p>供应商变体是 VND-ONLY<em></em></p>
   <p>共享库将安装到 <code>/vendor/lib[64]</code> 中。</p>
  </td>
 </tr>

 <tr>
  <td><p><code>true</code></p></td>
  <td><p><em></em>无效(编译错误)</p></td>
 </tr>

 <tr>
  <td rowspan="2"><p><code>true</code></p></td>
  <td><p><code>false</code></p></td>
  <td>
   <p>供应商变体是 VNDK<em></em>。</p>
   <p>共享库将安装到 <code>/system/lib[64]/vndk-${VER}</code> 中。</p>
  </td>
 </tr>

 <tr>
  <td><p><code>true</code></p></td>
  <td>
   <p>供应商变体是 VNDK-SP<em></em>。</p>
   <p>共享库将安装到 <code>/system/lib[64]/vndk-sp-${VER}</code> 中。</p>
  </td>
 </tr>

 <tr>
  <td rowspan="4"><p><code>false</code></p></td>
  <td rowspan="2"><p><code>false</code></p></td>
  <td><p><code>false</code></p></td>
  <td><p>没有供应商变体。此模块为 FWK-ONLY。<em></em></p></td>
 </tr>

 <tr>
  <td><p><code>true</code></p></td>
  <td><p><em></em>无效(编译错误)</p></td>
 </tr>

 <tr>
  <td rowspan="2"><p><code>true</code></p></td>
  <td><p><code>false</code></p></td>
  <td>
   <p>供应商变体是 VNDK-Private<em></em>。</p>
   <p>共享库将安装到 <code>/system/lib[64]/vndk-${VER}</code> 中。</p>
   <p>供应商模块不得直接使用这些变体。</p>
  </td>
 </tr>

 <tr>
  <td><p><code>true</code></p></td>
  <td>
   <p>供应商变体是 <em></em>VNDK-SP-Private。</p>
   <p>共享库将安装到 <code>/system/lib[64]/vndk-sp-${VER}</code> 中。</p>
   <p>供应商模块不得直接使用这些变体。</p>
  </td>
 </tr>
</tbody></table>

<aside class="note"><strong>注意</strong>:供应商可以为其模块设置 <code>vendor_available</code>。不过,供应商不得设置 <code>vndk.enabled</code> 和 <code>vndk.support_system_process</code>,因为供应商模块无法在 GSI 中找到它们。</aside>

<h3 id="vndk-extensions">VNDK 扩展</h3>

<p>VNDK 扩展是具有额外 API 的 VNDK 共享库,将安装到 <code>/vendor/lib[64]/vndk[-sp]</code> 中(不含版本后缀),并在系统运行时替换原始的 VNDK 共享库。</p>

<h4 id="defining-vndk-extensions">定义 VNDK 扩展</h4>

<p>在 Android P 中,<code>Android.bp</code> 本身支持 VNDK 扩展。要编译 VNDK 扩展,请定义另一个具有 <code>vendor:true</code> 和 <code>extends</code> 属性的模块:</p>

<pre class="prettyprint">
cc_library {
    name: "libvndk",
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libvndk_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk",
    },
}
</pre>

<p>具有 <code>vendor:true</code>、<code>vndk.enabled:true</code> 和 <code>extends</code> 属性的模块可定义 VNDK 扩展:</p>

<ul>
 <li><code>extends</code> 属性必须指定基础 VNDK 共享库名称(或 VNDK-SP 共享库名称)。</li>

 <li>VNDK 扩展(或 VNDK-SP 扩展)以扩展时所基于的基础模块名称命名。例如,<code>libvndk_ext</code> 的输出二进制文件是 <code>libvndk.so</code>,而非 <code>libvndk_ext.so</code>。</li>

 <li>VNDK 扩展将安装到 <code>/vendor/lib[64]/vndk</code> 中。</li>

 <li>VNDK-SP 扩展将安装到 <code>/vendor/lib[64]/vndk-sp</code> 中。</li>

 <li>基础共享库必须同时具有 <code>vndk.enabled:true</code> 和 <code>vendor_available:true</code>。</li>
</ul>

<p>VNDK-SP 扩展必须从 VNDK-SP 共享库进行扩展。也就是说,<code>vndk.support_system_process</code> 必须等于:</p>

<pre class="prettyprint">
cc_library {
    name: "libvndk_sp",
    vendor_available: true,
    vndk: {
        enabled: true,
        support_system_process: true,
    },
}

cc_library {
    name: "libvndk_sp_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk_sp",
        support_system_process: true,
    },
}
</pre>

<p>VNDK 扩展(或 VNDK-SP 扩展)可以依赖于其他供应商共享库:</p>

<pre class="prettyprint">
cc_library {
    name: "libvndk",
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libvndk_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk",
    },
    shared_libs: [
        "libvendor",
    ],
}

cc_library {
    name: "libvendor",
    vendor: true,
}
</pre>

<aside class="note"><strong>注意</strong>:与 SP-HAL-Dep 类似,VNDK-SP 扩展及其依赖项(包括供应商库)在 sepolicy 中必须标记为 <code>same_process_hal_file</code>。</aside>

<h4 id="using-vndk-extensions">使用 VNDK 扩展</h4>

<p>如果供应商模块依赖于由 VNDK 扩展定义的一些其他 API,则必须在其 <code>shared_libs</code> 属性中指定 VNDK 扩展的名称:</p>

<pre class="prettyprint">
// A vendor shared library example
cc_library {
    name: "libvendor",
    vendor: true,
    shared_libs: [
        "libvndk_ext",
    ],
}

// A vendor executable example
cc_binary {
    name: "vendor-example",
    vendor: true,
    shared_libs: [
        "libvndk_ext",
    ],
}
</pre>

<p>如果供应商模块依赖于一些 VNDK 扩展,则这些 VNDK 扩展将自动安装到 <code>/vendor/lib[64]/vndk[-sp]</code> 中。</p>

<p>如果某个模块不再依赖于 VNDK 扩展,请向 <code>CleanSpec.mk</code> 添加一个清理步骤,以移除共享库。例如:</p>

<pre class="prettyprint">
$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)
</pre>

<h3 id="conditional-compilation">条件编译</h3>

<p>本小节介绍了如何处理以下三个 VNDK 共享库之间的细微差异<em></em>(例如,为其中一个变体添加或移除某项功能):(1) 核心变体(例如 <code>/system/lib[64]/libexample.so</code>)、(2) 供应商变体(例如 <code>/system/lib[64]/vndk[-sp]-${VER}/libexample.so</code>)和 (3) VNDK 扩展(例如 <code>/vendor/lib[64]/vndk[-sp]/libexample.so</code>)。

</p><h4 id="conditional-cflags">条件编译器标志</h4>

<p>默认情况下,Android 编译系统会为供应商变体(包括 VNDK 扩展)定义 <code>__ANDROID_VNDK__</code>。您可以使用 C 预处理器防护程序来保护相应代码:</p>

<pre class="prettyprint">
void all() { }

#if !defined(__ANDROID_VNDK__)
void framework_only() { }
#endif

#if defined(__ANDROID_VNDK__)
void vndk_only() { }
#endif
</pre>

<p>除了 <code>__ANDROID_VNDK__</code>,还可以在 <code>Android.bp</code> 中指定不同的 <code>cflags</code> 或 <code>cppflags</code>。在 <code>target.vendor</code> 中指定的 <code>cflags</code> 或 <code>cppflags</code> 是专门针对供应商变体的。例如,以下代码是针对 <code>libexample</code> 和 <code>libexample_ext</code> 的 <code>Android.bp</code> 模块定义:</p>

<pre class="prettyprint">
cc_library {
    name: "libexample",
    srcs: ["example.c"],
    vendor_available: true,
    vndk: {
        enabled: true,
    },
    target: {
        vendor: {
            cflags: ["-DLIBEXAMPLE_ENABLE_VNDK=1"],
        },
    },
}

cc_library {
    name: "libexample_ext",
    srcs: ["example.c"],
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libexample",
    },
    cflags: [
        "-DLIBEXAMPLE_ENABLE_VNDK=1",
        "-DLIBEXAMPLE_ENABLE_VNDK_EXT=1",
    ],
}
</pre>

<p><code>example.c</code> 的代码清单:</p>

<pre class="prettyprint">
void all() { }

#if !defined(LIBEXAMPLE_ENABLE_VNDK)
void framework_only() { }
#endif

#if defined(LIBEXAMPLE_ENABLE_VNDK)
void vndk() { }
#endif

#if defined(LIBEXAMPLE_ENABLE_VNDK_EXT)
void vndk_ext() { }
#endif
</pre>

<p>针对每个变体导出的符号如下:</p>

<table>
 <tbody><tr>
  <th>安装路径</th>
  <th>导出的符号</th>
 </tr>

 <tr>
  <td><code>/system/lib[64]/libexample.so</code></td>
  <td><code>all</code>、<code>framework_only</code></td>
 </tr>

 <tr>
  <td><code>/system/lib[64]/vndk-${VER}/libexample.so</code></td>
  <td><code>all</code>、<code>vndk</code></td>
 </tr>

 <tr>
  <td><code>/vendor/lib[64]/vndk/libexample.so</code></td>
  <td><code>all</code>、<code>vndk</code>、<code>vndk_ext</code></td>
 </tr>
</tbody></table>

<!-- TODO: The paragraph below looks awkward. Refine this subsection to make
this more fluent. -->

<p>VNDK ABI 合规性检查工具会将 VNDK 和 VNDK 扩展的 ABI 同 <code>prebuilts/abi-dumps/vndk</code> 下的 ABI 转储进行比较:</p>

<ul>
 <li>通过原始 VNDK 共享库导出的符号必须与 ABI 转储中定义的符号相同(而不是后者的超集)。</li>

 <li>通过 VNDK 扩展导出的符号必须是 ABI 转储中定义的符号的超集。</li>
</ul>

<h4 id="exclude-source-files-or-shared-libs">排除源文件或共享库</h4>

<p>要从供应商变体中排除源文件,请将相应文件添加到 <code>exclude_srcs</code> 属性中。同样,要确保特定共享库未与供应商变体相关联,请将这些共享库添加到 <code>exclude_shared_libs</code> 属性中。例如:</p>

<pre class="prettyprint">cc_library {
    name: "libcond_exclude_example",
    srcs: ["fwk.c", "both.c"],
    shared_libs: ["libfwk_only", "libboth"],
    target: {
        vendor: {
            exclude_srcs: ["fwk.c"],
            exclude_shared_libs: ["libfwk_only"],
        },
    },
}</pre>

<p>在本示例中,<code>libcond_exclude_example</code> 的核心变体包含 <code>fwk.c</code> 和 <code>both.c</code> 中的代码,并且依赖于共享库 <code>libfwk_only</code> 和 <code>libboth</code>。</p>

<p>另一方面,<code>libcond_exclude_example</code> 的供应商变体仅包含 <code>both.c</code> 中的代码,因为 <code>fwk.c</code> 已被 <code>exclude_srcs</code> 属性排除。同样,<code>libcond_exclude_example</code> 仅依赖于共享库 <code>libboth</code>,因为 <code>libfwk_only</code> 已被<br /> <code>exclude_shared_libs</code> 属性排除。

<!-- <h4 id="vndk-ext-header-guideline">VNDK extension header guidelines</h4> -->

<!-- TODO: Add the guide line for VNDK extension headers. -->

</p><h3 id="product-packages">产品包</h3>

<p>在 Android 编译系统中,变量 <code>PRODUCT_PACKAGES</code> 指定应安装到设备中的可执行文件、共享库或软件包。指定模块的传递依赖项也会隐式安装到设备中。</p>

<p>如果启用了 <code>BOARD_VNDK_VERSION</code>,具有 <code>vendor_available</code> 或 <code>vndk.enabled</code> 的模块会得到特殊处理。如果框架模块依赖于具有 <code>vendor_available</code> 或 <code>vndk.enabled</code> 的模块,则核心变体将纳入传递安装集中。同样,如果供应商模块依赖于具有 <code>vendor_available</code> 或 <code>vndk.enabled</code> 的模块,则供应商变体将纳入传递安装集中。</p>

<p>当相关依赖项对编译系统不可见时(例如,可以在运行时使用 <code>dlopen()</code> 打开的共享库),您应该在 <code>PRODUCT_PACKAGES</code> 中指定模块名称来明确安装这些模块。</p>

<p>如果某个模块具有 <code>vendor_available</code> 或 <code>vndk.enabled</code>,则模块名称代表该模块的核心变体。要在 <code>PRODUCT_PACKAGES</code> 中明确指定供应商变体,请将 <code>.vendor</code> 后缀附加到模块名称上。例如:</p>

<pre class="prettyprint">cc_library {
    name: "libexample",
    srcs: ["example.c"],
    vendor_available: true,
}</pre>

<p>在本示例中,<code>libexample</code> 代表 <code>/system/lib[64]/libexample.so</code>,<code>libexample.vendor</code> 代表 <code>/vendor/lib[64]/libexample.so</code>。要安装 <code>/vendor/lib[64]/libexample.so</code>,请将 <code>libexample.vendor</code> 添加到 <code>PRODUCT_PACKAGES</code>:</p>

<pre class="prettyprint">PRODUCT_PACKAGES += libexample.vendor</pre>

</body></html>