blob: d0492fc4fdb78f12f9b35adc0f8102e285f58722 [file] [log] [blame]
Justin Yun8effde42017-06-23 19:24:43 +09001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
Inseob Kimae553032019-05-14 18:52:49 +090018 "encoding/json"
Martin Stjernholm257eb0c2018-10-15 13:05:27 +010019 "errors"
Jooyung Han0302a842019-10-30 18:43:49 +090020 "fmt"
Inseob Kim1f086e22019-05-09 13:29:15 +090021 "path/filepath"
Inseob Kim242ef0c2019-10-22 20:15:20 +090022 "sort"
Jiyong Parkd5b18a52017-08-03 21:22:50 +090023 "strings"
24 "sync"
25
Justin Yun8effde42017-06-23 19:24:43 +090026 "android/soong/android"
Vic Yangefd249e2018-11-12 20:19:56 -080027 "android/soong/cc/config"
Justin Yun8effde42017-06-23 19:24:43 +090028)
29
Jooyung Han39edb6c2019-11-06 16:53:07 +090030const (
31 llndkLibrariesTxt = "llndk.libraries.txt"
32 vndkCoreLibrariesTxt = "vndkcore.libraries.txt"
33 vndkSpLibrariesTxt = "vndksp.libraries.txt"
34 vndkPrivateLibrariesTxt = "vndkprivate.libraries.txt"
35 vndkUsingCoreVariantLibrariesTxt = "vndkcorevariant.libraries.txt"
36)
37
38func VndkLibrariesTxtModules(vndkVersion string) []string {
39 if vndkVersion == "current" {
40 return []string{
41 llndkLibrariesTxt,
42 vndkCoreLibrariesTxt,
43 vndkSpLibrariesTxt,
44 vndkPrivateLibrariesTxt,
Jooyung Han39edb6c2019-11-06 16:53:07 +090045 }
46 }
47 // Snapshot vndks have their own *.libraries.VER.txt files.
48 // Note that snapshots don't have "vndkcorevariant.libraries.VER.txt"
49 return []string{
50 insertVndkVersion(llndkLibrariesTxt, vndkVersion),
51 insertVndkVersion(vndkCoreLibrariesTxt, vndkVersion),
52 insertVndkVersion(vndkSpLibrariesTxt, vndkVersion),
53 insertVndkVersion(vndkPrivateLibrariesTxt, vndkVersion),
54 }
55}
56
Justin Yun8effde42017-06-23 19:24:43 +090057type VndkProperties struct {
58 Vndk struct {
59 // declared as a VNDK or VNDK-SP module. The vendor variant
60 // will be installed in /system instead of /vendor partition.
61 //
Roland Levillaindfe75b32019-07-23 16:53:32 +010062 // `vendor_available` must be explicitly set to either true or
Jiyong Park82e2bf32017-08-16 14:05:54 +090063 // false together with `vndk: {enabled: true}`.
Justin Yun8effde42017-06-23 19:24:43 +090064 Enabled *bool
65
66 // declared as a VNDK-SP module, which is a subset of VNDK.
67 //
68 // `vndk: { enabled: true }` must set together.
69 //
70 // All these modules are allowed to link to VNDK-SP or LL-NDK
71 // modules only. Other dependency will cause link-type errors.
72 //
73 // If `support_system_process` is not set or set to false,
74 // the module is VNDK-core and can link to other VNDK-core,
75 // VNDK-SP or LL-NDK modules only.
76 Support_system_process *bool
Logan Chienf3511742017-10-31 18:04:35 +080077
78 // Extending another module
79 Extends *string
Justin Yun8effde42017-06-23 19:24:43 +090080 }
81}
82
83type vndkdep struct {
84 Properties VndkProperties
85}
86
87func (vndk *vndkdep) props() []interface{} {
88 return []interface{}{&vndk.Properties}
89}
90
91func (vndk *vndkdep) begin(ctx BaseModuleContext) {}
92
93func (vndk *vndkdep) deps(ctx BaseModuleContext, deps Deps) Deps {
94 return deps
95}
96
97func (vndk *vndkdep) isVndk() bool {
98 return Bool(vndk.Properties.Vndk.Enabled)
99}
100
101func (vndk *vndkdep) isVndkSp() bool {
102 return Bool(vndk.Properties.Vndk.Support_system_process)
103}
104
Logan Chienf3511742017-10-31 18:04:35 +0800105func (vndk *vndkdep) isVndkExt() bool {
106 return vndk.Properties.Vndk.Extends != nil
107}
108
109func (vndk *vndkdep) getVndkExtendsModuleName() string {
110 return String(vndk.Properties.Vndk.Extends)
111}
112
Justin Yun8effde42017-06-23 19:24:43 +0900113func (vndk *vndkdep) typeName() string {
114 if !vndk.isVndk() {
115 return "native:vendor"
116 }
Logan Chienf3511742017-10-31 18:04:35 +0800117 if !vndk.isVndkExt() {
118 if !vndk.isVndkSp() {
119 return "native:vendor:vndk"
120 }
121 return "native:vendor:vndksp"
Justin Yun8effde42017-06-23 19:24:43 +0900122 }
Logan Chienf3511742017-10-31 18:04:35 +0800123 if !vndk.isVndkSp() {
124 return "native:vendor:vndkext"
125 }
126 return "native:vendor:vndkspext"
Justin Yun8effde42017-06-23 19:24:43 +0900127}
128
Ivan Lozano183a3212019-10-18 14:18:45 -0700129func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag DependencyTag) {
Justin Yun8effde42017-06-23 19:24:43 +0900130 if to.linker == nil {
131 return
132 }
Jiyong Park82e2bf32017-08-16 14:05:54 +0900133 if !vndk.isVndk() {
Justin Yun5f7f7e82019-11-18 19:52:14 +0900134 // Non-VNDK modules (those installed to /vendor, /product, or /system/product) can't depend
135 // on modules marked with vendor_available: false.
Jiyong Park82e2bf32017-08-16 14:05:54 +0900136 violation := false
Nan Zhang0007d812017-11-07 10:57:05 -0800137 if lib, ok := to.linker.(*llndkStubDecorator); ok && !Bool(lib.Properties.Vendor_available) {
Jiyong Park82e2bf32017-08-16 14:05:54 +0900138 violation = true
139 } else {
140 if _, ok := to.linker.(libraryInterface); ok && to.VendorProperties.Vendor_available != nil && !Bool(to.VendorProperties.Vendor_available) {
141 // Vendor_available == nil && !Bool(Vendor_available) should be okay since
Justin Yun5f7f7e82019-11-18 19:52:14 +0900142 // it means a vendor-only, or product-only library which is a valid dependency
143 // for non-VNDK modules.
Jiyong Park82e2bf32017-08-16 14:05:54 +0900144 violation = true
145 }
146 }
147 if violation {
148 ctx.ModuleErrorf("Vendor module that is not VNDK should not link to %q which is marked as `vendor_available: false`", to.Name())
149 }
150 }
Justin Yun8effde42017-06-23 19:24:43 +0900151 if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() {
152 // Check only shared libraries.
153 // Other (static and LL-NDK) libraries are allowed to link.
154 return
155 }
Ivan Lozano52767be2019-10-18 14:49:46 -0700156 if !to.UseVndk() {
Justin Yun8effde42017-06-23 19:24:43 +0900157 ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library",
158 vndk.typeName(), to.Name())
159 return
160 }
Logan Chienf3511742017-10-31 18:04:35 +0800161 if tag == vndkExtDepTag {
162 // Ensure `extends: "name"` property refers a vndk module that has vendor_available
163 // and has identical vndk properties.
164 if to.vndkdep == nil || !to.vndkdep.isVndk() {
165 ctx.ModuleErrorf("`extends` refers a non-vndk module %q", to.Name())
166 return
167 }
168 if vndk.isVndkSp() != to.vndkdep.isVndkSp() {
169 ctx.ModuleErrorf(
170 "`extends` refers a module %q with mismatched support_system_process",
171 to.Name())
172 return
173 }
174 if !Bool(to.VendorProperties.Vendor_available) {
175 ctx.ModuleErrorf(
176 "`extends` refers module %q which does not have `vendor_available: true`",
177 to.Name())
178 return
179 }
180 }
Justin Yun8effde42017-06-23 19:24:43 +0900181 if to.vndkdep == nil {
182 return
183 }
Logan Chienf3511742017-10-31 18:04:35 +0800184
Logan Chiend3c59a22018-03-29 14:08:15 +0800185 // Check the dependencies of VNDK shared libraries.
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100186 if err := vndkIsVndkDepAllowed(vndk, to.vndkdep); err != nil {
187 ctx.ModuleErrorf("(%s) should not link to %q (%s): %v",
188 vndk.typeName(), to.Name(), to.vndkdep.typeName(), err)
Logan Chienf3511742017-10-31 18:04:35 +0800189 return
190 }
Logan Chiend3c59a22018-03-29 14:08:15 +0800191}
Logan Chienf3511742017-10-31 18:04:35 +0800192
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100193func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) error {
Logan Chiend3c59a22018-03-29 14:08:15 +0800194 // Check the dependencies of VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext and vendor modules.
195 if from.isVndkExt() {
196 if from.isVndkSp() {
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100197 if to.isVndk() && !to.isVndkSp() {
198 return errors.New("VNDK-SP extensions must not depend on VNDK or VNDK extensions")
199 }
200 return nil
Logan Chiend3c59a22018-03-29 14:08:15 +0800201 }
202 // VNDK-Ext may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100203 return nil
Justin Yun8effde42017-06-23 19:24:43 +0900204 }
Logan Chiend3c59a22018-03-29 14:08:15 +0800205 if from.isVndk() {
206 if to.isVndkExt() {
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100207 return errors.New("VNDK-core and VNDK-SP must not depend on VNDK extensions")
Logan Chiend3c59a22018-03-29 14:08:15 +0800208 }
209 if from.isVndkSp() {
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100210 if !to.isVndkSp() {
211 return errors.New("VNDK-SP must only depend on VNDK-SP")
212 }
213 return nil
Logan Chiend3c59a22018-03-29 14:08:15 +0800214 }
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100215 if !to.isVndk() {
216 return errors.New("VNDK-core must only depend on VNDK-core or VNDK-SP")
217 }
218 return nil
Logan Chiend3c59a22018-03-29 14:08:15 +0800219 }
220 // Vendor modules may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100221 return nil
Justin Yun8effde42017-06-23 19:24:43 +0900222}
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900223
224var (
Jooyung Hana463f722019-11-01 08:45:59 +0900225 vndkCoreLibrariesKey = android.NewOnceKey("vndkCoreLibrarires")
226 vndkSpLibrariesKey = android.NewOnceKey("vndkSpLibrarires")
227 llndkLibrariesKey = android.NewOnceKey("llndkLibrarires")
228 vndkPrivateLibrariesKey = android.NewOnceKey("vndkPrivateLibrarires")
Kiyoung Kime1aa8ea2019-12-30 11:12:55 +0900229 vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibraries")
Jooyung Hana463f722019-11-01 08:45:59 +0900230 vndkMustUseVendorVariantListKey = android.NewOnceKey("vndkMustUseVendorVariantListKey")
231 vndkLibrariesLock sync.Mutex
Inseob Kimae553032019-05-14 18:52:49 +0900232)
Inseob Kim1f086e22019-05-09 13:29:15 +0900233
Jooyung Han0302a842019-10-30 18:43:49 +0900234func vndkCoreLibraries(config android.Config) map[string]string {
Inseob Kim9516ee92019-05-09 10:56:13 +0900235 return config.Once(vndkCoreLibrariesKey, func() interface{} {
Jooyung Han0302a842019-10-30 18:43:49 +0900236 return make(map[string]string)
237 }).(map[string]string)
Inseob Kim9516ee92019-05-09 10:56:13 +0900238}
239
Jooyung Han0302a842019-10-30 18:43:49 +0900240func vndkSpLibraries(config android.Config) map[string]string {
Inseob Kim9516ee92019-05-09 10:56:13 +0900241 return config.Once(vndkSpLibrariesKey, func() interface{} {
Jooyung Han0302a842019-10-30 18:43:49 +0900242 return make(map[string]string)
243 }).(map[string]string)
Inseob Kim9516ee92019-05-09 10:56:13 +0900244}
245
Jooyung Han0302a842019-10-30 18:43:49 +0900246func isLlndkLibrary(baseModuleName string, config android.Config) bool {
247 _, ok := llndkLibraries(config)[baseModuleName]
248 return ok
249}
250
251func llndkLibraries(config android.Config) map[string]string {
Inseob Kim9516ee92019-05-09 10:56:13 +0900252 return config.Once(llndkLibrariesKey, func() interface{} {
Jooyung Han0302a842019-10-30 18:43:49 +0900253 return make(map[string]string)
254 }).(map[string]string)
Inseob Kim9516ee92019-05-09 10:56:13 +0900255}
256
Jooyung Han0302a842019-10-30 18:43:49 +0900257func isVndkPrivateLibrary(baseModuleName string, config android.Config) bool {
258 _, ok := vndkPrivateLibraries(config)[baseModuleName]
259 return ok
260}
261
262func vndkPrivateLibraries(config android.Config) map[string]string {
Inseob Kim9516ee92019-05-09 10:56:13 +0900263 return config.Once(vndkPrivateLibrariesKey, func() interface{} {
Jooyung Han0302a842019-10-30 18:43:49 +0900264 return make(map[string]string)
265 }).(map[string]string)
Inseob Kim9516ee92019-05-09 10:56:13 +0900266}
267
Jooyung Han0302a842019-10-30 18:43:49 +0900268func vndkUsingCoreVariantLibraries(config android.Config) map[string]string {
Inseob Kim9516ee92019-05-09 10:56:13 +0900269 return config.Once(vndkUsingCoreVariantLibrariesKey, func() interface{} {
Jooyung Han0302a842019-10-30 18:43:49 +0900270 return make(map[string]string)
271 }).(map[string]string)
Inseob Kim9516ee92019-05-09 10:56:13 +0900272}
273
Jooyung Han097087b2019-10-22 19:32:18 +0900274func vndkMustUseVendorVariantList(cfg android.Config) []string {
275 return cfg.Once(vndkMustUseVendorVariantListKey, func() interface{} {
Jooyung Han097087b2019-10-22 19:32:18 +0900276 return config.VndkMustUseVendorVariantList
277 }).([]string)
278}
279
280// test may call this to override global configuration(config.VndkMustUseVendorVariantList)
281// when it is called, it must be before the first call to vndkMustUseVendorVariantList()
282func setVndkMustUseVendorVariantListForTest(config android.Config, mustUseVendorVariantList []string) {
Jooyung Hana463f722019-11-01 08:45:59 +0900283 config.Once(vndkMustUseVendorVariantListKey, func() interface{} {
Jooyung Han097087b2019-10-22 19:32:18 +0900284 return mustUseVendorVariantList
285 })
286}
287
Inseob Kim1f086e22019-05-09 13:29:15 +0900288func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
289 lib := m.linker.(*llndkStubDecorator)
Jooyung Han0302a842019-10-30 18:43:49 +0900290 name := m.BaseModuleName()
291 filename := m.BaseModuleName() + ".so"
Inseob Kim9516ee92019-05-09 10:56:13 +0900292
Inseob Kim1f086e22019-05-09 13:29:15 +0900293 vndkLibrariesLock.Lock()
294 defer vndkLibrariesLock.Unlock()
Inseob Kim9516ee92019-05-09 10:56:13 +0900295
Jooyung Han0302a842019-10-30 18:43:49 +0900296 llndkLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900297 if !Bool(lib.Properties.Vendor_available) {
Jooyung Han0302a842019-10-30 18:43:49 +0900298 vndkPrivateLibraries(mctx.Config())[name] = filename
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900299 }
300}
Inseob Kim1f086e22019-05-09 13:29:15 +0900301
302func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
Jooyung Han0302a842019-10-30 18:43:49 +0900303 name := m.BaseModuleName()
304 filename, err := getVndkFileName(m)
305 if err != nil {
306 panic(err)
307 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900308
309 vndkLibrariesLock.Lock()
310 defer vndkLibrariesLock.Unlock()
311
Jooyung Han097087b2019-10-22 19:32:18 +0900312 if inList(name, vndkMustUseVendorVariantList(mctx.Config())) {
313 m.Properties.MustUseVendorVariant = true
314 }
Jooyung Han0302a842019-10-30 18:43:49 +0900315 if mctx.DeviceConfig().VndkUseCoreVariant() && !m.Properties.MustUseVendorVariant {
316 vndkUsingCoreVariantLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900317 }
Jooyung Han0302a842019-10-30 18:43:49 +0900318
Inseob Kim1f086e22019-05-09 13:29:15 +0900319 if m.vndkdep.isVndkSp() {
Jooyung Han0302a842019-10-30 18:43:49 +0900320 vndkSpLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900321 } else {
Jooyung Han0302a842019-10-30 18:43:49 +0900322 vndkCoreLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900323 }
324 if !Bool(m.VendorProperties.Vendor_available) {
Jooyung Han0302a842019-10-30 18:43:49 +0900325 vndkPrivateLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900326 }
327}
328
Jooyung Han31c470b2019-10-18 16:26:59 +0900329func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
330 if !m.Enabled() {
331 return false
332 }
333
Jooyung Han87a7f302019-10-29 05:18:21 +0900334 if !mctx.Device() {
335 return false
336 }
337
Jooyung Han31c470b2019-10-18 16:26:59 +0900338 if m.Target().NativeBridge == android.NativeBridgeEnabled {
339 return false
340 }
341
342 // prebuilt vndk modules should match with device
343 // TODO(b/142675459): Use enabled: to select target device in vndk_prebuilt_shared
344 // When b/142675459 is landed, remove following check
345 if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.matchesWithDevice(mctx.DeviceConfig()) {
346 return false
347 }
348
349 if lib, ok := m.linker.(libraryInterface); ok {
Justin Yun5f7f7e82019-11-18 19:52:14 +0900350 useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
Jooyung Han87a7f302019-10-29 05:18:21 +0900351 mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
Jooyung Hana57af4a2020-01-23 05:36:59 +0000352 return lib.shared() && m.inVendor() && m.IsVndk() && !m.isVndkExt() && !useCoreVariant
Jooyung Han31c470b2019-10-18 16:26:59 +0900353 }
354 return false
355}
356
Inseob Kim1f086e22019-05-09 13:29:15 +0900357// gather list of vndk-core, vndk-sp, and ll-ndk libs
358func VndkMutator(mctx android.BottomUpMutatorContext) {
359 m, ok := mctx.Module().(*Module)
360 if !ok {
361 return
362 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900363 if !m.Enabled() {
364 return
365 }
Justin Yun7390ea32019-09-08 11:34:06 +0900366 if m.Target().NativeBridge == android.NativeBridgeEnabled {
367 // Skip native_bridge modules
368 return
369 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900370
371 if _, ok := m.linker.(*llndkStubDecorator); ok {
372 processLlndkLibrary(mctx, m)
373 return
374 }
375
376 lib, is_lib := m.linker.(*libraryDecorator)
377 prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
378
Inseob Kim64c43952019-08-26 16:52:35 +0900379 if (is_lib && lib.buildShared()) || (is_prebuilt_lib && prebuilt_lib.buildShared()) {
380 if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
Inseob Kim1f086e22019-05-09 13:29:15 +0900381 processVndkLibrary(mctx, m)
382 return
383 }
384 }
385}
386
387func init() {
Jooyung Han39edb6c2019-11-06 16:53:07 +0900388 android.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory)
Inseob Kim1f086e22019-05-09 13:29:15 +0900389 android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
Inseob Kim1f086e22019-05-09 13:29:15 +0900390}
391
Jooyung Han2216fb12019-11-06 16:46:15 +0900392type vndkLibrariesTxt struct {
393 android.ModuleBase
394 outputFile android.OutputPath
395}
396
Jooyung Han39edb6c2019-11-06 16:53:07 +0900397var _ android.PrebuiltEtcModule = &vndkLibrariesTxt{}
398var _ android.OutputFileProducer = &vndkLibrariesTxt{}
399
Jooyung Han2216fb12019-11-06 16:46:15 +0900400// vndk_libraries_txt is a special kind of module type in that it name is one of
401// - llndk.libraries.txt
402// - vndkcore.libraries.txt
403// - vndksp.libraries.txt
404// - vndkprivate.libraries.txt
405// - vndkcorevariant.libraries.txt
406// A module behaves like a prebuilt_etc but its content is generated by soong.
407// By being a soong module, these files can be referenced by other soong modules.
408// For example, apex_vndk can depend on these files as prebuilt.
Jooyung Han39edb6c2019-11-06 16:53:07 +0900409func VndkLibrariesTxtFactory() android.Module {
Jooyung Han2216fb12019-11-06 16:46:15 +0900410 m := &vndkLibrariesTxt{}
411 android.InitAndroidModule(m)
412 return m
413}
414
415func insertVndkVersion(filename string, vndkVersion string) string {
416 if index := strings.LastIndex(filename, "."); index != -1 {
417 return filename[:index] + "." + vndkVersion + filename[index:]
418 }
419 return filename
420}
421
422func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
423 var list []string
424 switch txt.Name() {
Jooyung Han39edb6c2019-11-06 16:53:07 +0900425 case llndkLibrariesTxt:
Jooyung Han2216fb12019-11-06 16:46:15 +0900426 for _, filename := range android.SortedStringMapValues(llndkLibraries(ctx.Config())) {
427 if strings.HasPrefix(filename, "libclang_rt.hwasan-") {
428 continue
429 }
430 list = append(list, filename)
431 }
Jooyung Han39edb6c2019-11-06 16:53:07 +0900432 case vndkCoreLibrariesTxt:
Jooyung Han2216fb12019-11-06 16:46:15 +0900433 list = android.SortedStringMapValues(vndkCoreLibraries(ctx.Config()))
Jooyung Han39edb6c2019-11-06 16:53:07 +0900434 case vndkSpLibrariesTxt:
Jooyung Han2216fb12019-11-06 16:46:15 +0900435 list = android.SortedStringMapValues(vndkSpLibraries(ctx.Config()))
Jooyung Han39edb6c2019-11-06 16:53:07 +0900436 case vndkPrivateLibrariesTxt:
Jooyung Han2216fb12019-11-06 16:46:15 +0900437 list = android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config()))
Jooyung Han39edb6c2019-11-06 16:53:07 +0900438 case vndkUsingCoreVariantLibrariesTxt:
Jooyung Han2216fb12019-11-06 16:46:15 +0900439 list = android.SortedStringMapValues(vndkUsingCoreVariantLibraries(ctx.Config()))
440 default:
441 ctx.ModuleErrorf("name(%s) is unknown.", txt.Name())
442 return
443 }
444
Kiyoung Kime1aa8ea2019-12-30 11:12:55 +0900445 var filename string
446 if txt.Name() != vndkUsingCoreVariantLibrariesTxt {
447 filename = insertVndkVersion(txt.Name(), ctx.DeviceConfig().PlatformVndkVersion())
448 } else {
449 filename = txt.Name()
450 }
451
Jooyung Han2216fb12019-11-06 16:46:15 +0900452 txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath
453 ctx.Build(pctx, android.BuildParams{
454 Rule: android.WriteFile,
455 Output: txt.outputFile,
456 Description: "Writing " + txt.outputFile.String(),
457 Args: map[string]string{
458 "content": strings.Join(list, "\\n"),
459 },
460 })
461
462 installPath := android.PathForModuleInstall(ctx, "etc")
463 ctx.InstallFile(installPath, filename, txt.outputFile)
464}
465
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900466func (txt *vndkLibrariesTxt) AndroidMkEntries() []android.AndroidMkEntries {
467 return []android.AndroidMkEntries{android.AndroidMkEntries{
Jooyung Han2216fb12019-11-06 16:46:15 +0900468 Class: "ETC",
469 OutputFile: android.OptionalPathForPath(txt.outputFile),
470 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
471 func(entries *android.AndroidMkEntries) {
472 entries.SetString("LOCAL_MODULE_STEM", txt.outputFile.Base())
473 },
474 },
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900475 }}
Jooyung Han2216fb12019-11-06 16:46:15 +0900476}
477
Jooyung Han39edb6c2019-11-06 16:53:07 +0900478func (txt *vndkLibrariesTxt) OutputFile() android.OutputPath {
479 return txt.outputFile
480}
481
482func (txt *vndkLibrariesTxt) OutputFiles(tag string) (android.Paths, error) {
483 return android.Paths{txt.outputFile}, nil
484}
485
486func (txt *vndkLibrariesTxt) SubDir() string {
487 return ""
488}
489
Inseob Kim1f086e22019-05-09 13:29:15 +0900490func VndkSnapshotSingleton() android.Singleton {
491 return &vndkSnapshotSingleton{}
492}
493
Jooyung Han0302a842019-10-30 18:43:49 +0900494type vndkSnapshotSingleton struct {
Jooyung Han39edb6c2019-11-06 16:53:07 +0900495 vndkLibrariesFile android.OutputPath
496 vndkSnapshotZipFile android.OptionalPath
Jooyung Han0302a842019-10-30 18:43:49 +0900497}
Inseob Kim1f086e22019-05-09 13:29:15 +0900498
Inseob Kim1f086e22019-05-09 13:29:15 +0900499func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Jooyung Han0302a842019-10-30 18:43:49 +0900500 // build these files even if PlatformVndkVersion or BoardVndkVersion is not set
501 c.buildVndkLibrariesTxtFiles(ctx)
502
Inseob Kim1f086e22019-05-09 13:29:15 +0900503 // BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
504 if ctx.DeviceConfig().VndkVersion() != "current" {
505 return
506 }
507
508 if ctx.DeviceConfig().PlatformVndkVersion() == "" {
509 return
510 }
511
512 if ctx.DeviceConfig().BoardVndkRuntimeDisable() {
513 return
514 }
515
Inseob Kim242ef0c2019-10-22 20:15:20 +0900516 var snapshotOutputs android.Paths
517
518 /*
519 VNDK snapshot zipped artifacts directory structure:
520 {SNAPSHOT_ARCH}/
521 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
522 shared/
523 vndk-core/
524 (VNDK-core libraries, e.g. libbinder.so)
525 vndk-sp/
526 (VNDK-SP libraries, e.g. libc++.so)
527 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
528 shared/
529 vndk-core/
530 (VNDK-core libraries, e.g. libbinder.so)
531 vndk-sp/
532 (VNDK-SP libraries, e.g. libc++.so)
533 binder32/
534 (This directory is newly introduced in v28 (Android P) to hold
535 prebuilts built for 32-bit binder interface.)
536 arch-{TARGET_ARCH}-{TARGE_ARCH_VARIANT}/
537 ...
538 configs/
539 (various *.txt configuration files)
540 include/
541 (header files of same directory structure with source tree)
542 NOTICE_FILES/
543 (notice files of libraries, e.g. libcutils.so.txt)
544 */
Inseob Kim1f086e22019-05-09 13:29:15 +0900545
546 snapshotDir := "vndk-snapshot"
Inseob Kim242ef0c2019-10-22 20:15:20 +0900547 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
Inseob Kim1f086e22019-05-09 13:29:15 +0900548
Inseob Kim242ef0c2019-10-22 20:15:20 +0900549 configsDir := filepath.Join(snapshotArchDir, "configs")
550 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
551 includeDir := filepath.Join(snapshotArchDir, "include")
552
Inseob Kim242ef0c2019-10-22 20:15:20 +0900553 // set of notice files copied.
Inseob Kim1f086e22019-05-09 13:29:15 +0900554 noticeBuilt := make(map[string]bool)
555
Inseob Kim242ef0c2019-10-22 20:15:20 +0900556 // paths of VNDK modules for GPL license checking
557 modulePaths := make(map[string]string)
558
559 // actual module names of .so files
560 // e.g. moduleNames["libprotobuf-cpp-full-3.9.1.so"] = "libprotobuf-cpp-full"
561 moduleNames := make(map[string]string)
562
Inseob Kim8471cda2019-11-15 09:59:12 +0900563 var headers android.Paths
Inseob Kim242ef0c2019-10-22 20:15:20 +0900564
Inseob Kim8471cda2019-11-15 09:59:12 +0900565 installVndkSnapshotLib := func(m *Module, l snapshotLibraryInterface, vndkType string) (android.Paths, bool) {
Inseob Kim242ef0c2019-10-22 20:15:20 +0900566 var ret android.Paths
567
Inseob Kim8471cda2019-11-15 09:59:12 +0900568 targetArch := "arch-" + m.Target().Arch.ArchType.String()
569 if m.Target().Arch.ArchVariant != "" {
570 targetArch += "-" + m.Target().Arch.ArchVariant
Inseob Kim242ef0c2019-10-22 20:15:20 +0900571 }
Inseob Kimae553032019-05-14 18:52:49 +0900572
Inseob Kim8471cda2019-11-15 09:59:12 +0900573 libPath := m.outputFile.Path()
574 snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, libPath.Base())
575 ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
576
Inseob Kimae553032019-05-14 18:52:49 +0900577 if ctx.Config().VndkSnapshotBuildArtifacts() {
578 prop := struct {
579 ExportedDirs []string `json:",omitempty"`
580 ExportedSystemDirs []string `json:",omitempty"`
581 ExportedFlags []string `json:",omitempty"`
582 RelativeInstallPath string `json:",omitempty"`
583 }{}
584 prop.ExportedFlags = l.exportedFlags()
Jiyong Park74955042019-10-22 20:19:51 +0900585 prop.ExportedDirs = l.exportedDirs().Strings()
586 prop.ExportedSystemDirs = l.exportedSystemDirs().Strings()
Inseob Kimae553032019-05-14 18:52:49 +0900587 prop.RelativeInstallPath = m.RelativeInstallPath()
588
Inseob Kim242ef0c2019-10-22 20:15:20 +0900589 propOut := snapshotLibOut + ".json"
Inseob Kimae553032019-05-14 18:52:49 +0900590
591 j, err := json.Marshal(prop)
592 if err != nil {
593 ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
Inseob Kim242ef0c2019-10-22 20:15:20 +0900594 return nil, false
Inseob Kimae553032019-05-14 18:52:49 +0900595 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900596 ret = append(ret, writeStringToFile(ctx, string(j), propOut))
Inseob Kimae553032019-05-14 18:52:49 +0900597 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900598 return ret, true
Inseob Kimae553032019-05-14 18:52:49 +0900599 }
600
Inseob Kim8471cda2019-11-15 09:59:12 +0900601 isVndkSnapshotLibrary := func(m *Module) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) {
Inseob Kimae553032019-05-14 18:52:49 +0900602 if m.Target().NativeBridge == android.NativeBridgeEnabled {
603 return nil, "", false
604 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900605 if !m.inVendor() || !m.installable() || m.isSnapshotPrebuilt() {
Inseob Kimae553032019-05-14 18:52:49 +0900606 return nil, "", false
607 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900608 l, ok := m.linker.(snapshotLibraryInterface)
Inseob Kimae553032019-05-14 18:52:49 +0900609 if !ok || !l.shared() {
610 return nil, "", false
611 }
Justin Yun5f7f7e82019-11-18 19:52:14 +0900612 if m.VndkVersion() == ctx.DeviceConfig().PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() {
Inseob Kim242ef0c2019-10-22 20:15:20 +0900613 if m.isVndkSp() {
614 return l, "vndk-sp", true
615 } else {
616 return l, "vndk-core", true
617 }
Inseob Kimae553032019-05-14 18:52:49 +0900618 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900619
620 return nil, "", false
Inseob Kimae553032019-05-14 18:52:49 +0900621 }
622
Inseob Kim1f086e22019-05-09 13:29:15 +0900623 ctx.VisitAllModules(func(module android.Module) {
624 m, ok := module.(*Module)
Inseob Kimae553032019-05-14 18:52:49 +0900625 if !ok || !m.Enabled() {
Inseob Kim1f086e22019-05-09 13:29:15 +0900626 return
627 }
628
Inseob Kim242ef0c2019-10-22 20:15:20 +0900629 l, vndkType, ok := isVndkSnapshotLibrary(m)
Inseob Kimae553032019-05-14 18:52:49 +0900630 if !ok {
dimitry51ea18a2019-05-20 10:39:52 +0200631 return
632 }
633
Inseob Kim8471cda2019-11-15 09:59:12 +0900634 // install .so files for appropriate modules.
635 // Also install .json files if VNDK_SNAPSHOT_BUILD_ARTIFACTS
Inseob Kim242ef0c2019-10-22 20:15:20 +0900636 libs, ok := installVndkSnapshotLib(m, l, vndkType)
Inseob Kimae553032019-05-14 18:52:49 +0900637 if !ok {
Inseob Kim1f086e22019-05-09 13:29:15 +0900638 return
639 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900640 snapshotOutputs = append(snapshotOutputs, libs...)
Inseob Kim1f086e22019-05-09 13:29:15 +0900641
Inseob Kim8471cda2019-11-15 09:59:12 +0900642 // These are for generating module_names.txt and module_paths.txt
643 stem := m.outputFile.Path().Base()
644 moduleNames[stem] = ctx.ModuleName(m)
645 modulePaths[stem] = ctx.ModuleDir(m)
646
Bob Badoura75b0572020-02-18 20:21:55 -0800647 if len(m.NoticeFiles()) > 0 {
Inseob Kim8471cda2019-11-15 09:59:12 +0900648 noticeName := stem + ".txt"
649 // skip already copied notice file
650 if _, ok := noticeBuilt[noticeName]; !ok {
651 noticeBuilt[noticeName] = true
Bob Badoura75b0572020-02-18 20:21:55 -0800652 snapshotOutputs = append(snapshotOutputs, combineNotices(
653 ctx, m.NoticeFiles(), filepath.Join(noticeDir, noticeName)))
Inseob Kim8471cda2019-11-15 09:59:12 +0900654 }
655 }
656
657 if ctx.Config().VndkSnapshotBuildArtifacts() {
658 headers = append(headers, exportedHeaders(ctx, l)...)
Inseob Kimae553032019-05-14 18:52:49 +0900659 }
660 })
Inseob Kim1f086e22019-05-09 13:29:15 +0900661
Inseob Kim8471cda2019-11-15 09:59:12 +0900662 // install all headers after removing duplicates
663 for _, header := range android.FirstUniquePaths(headers) {
664 snapshotOutputs = append(snapshotOutputs, copyFile(
665 ctx, header, filepath.Join(includeDir, header.String())))
Inseob Kimae553032019-05-14 18:52:49 +0900666 }
667
Jooyung Han39edb6c2019-11-06 16:53:07 +0900668 // install *.libraries.txt except vndkcorevariant.libraries.txt
669 ctx.VisitAllModules(func(module android.Module) {
670 m, ok := module.(*vndkLibrariesTxt)
671 if !ok || !m.Enabled() || m.Name() == vndkUsingCoreVariantLibrariesTxt {
672 return
673 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900674 snapshotOutputs = append(snapshotOutputs, copyFile(
675 ctx, m.OutputFile(), filepath.Join(configsDir, m.Name())))
Jooyung Han39edb6c2019-11-06 16:53:07 +0900676 })
Inseob Kim1f086e22019-05-09 13:29:15 +0900677
Inseob Kim242ef0c2019-10-22 20:15:20 +0900678 /*
679 Dump a map to a list file as:
Inseob Kim1f086e22019-05-09 13:29:15 +0900680
Inseob Kim242ef0c2019-10-22 20:15:20 +0900681 {key1} {value1}
682 {key2} {value2}
683 ...
684 */
685 installMapListFile := func(m map[string]string, path string) android.OutputPath {
686 var txtBuilder strings.Builder
687 for idx, k := range android.SortedStringKeys(m) {
688 if idx > 0 {
689 txtBuilder.WriteString("\\n")
690 }
691 txtBuilder.WriteString(k)
692 txtBuilder.WriteString(" ")
693 txtBuilder.WriteString(m[k])
Inseob Kim1f086e22019-05-09 13:29:15 +0900694 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900695 return writeStringToFile(ctx, txtBuilder.String(), path)
Inseob Kim1f086e22019-05-09 13:29:15 +0900696 }
697
Inseob Kim242ef0c2019-10-22 20:15:20 +0900698 /*
699 module_paths.txt contains paths on which VNDK modules are defined.
700 e.g.,
701 libbase.so system/core/base
702 libc.so bionic/libc
703 ...
704 */
705 snapshotOutputs = append(snapshotOutputs, installMapListFile(modulePaths, filepath.Join(configsDir, "module_paths.txt")))
706
707 /*
708 module_names.txt contains names as which VNDK modules are defined,
709 because output filename and module name can be different with stem and suffix properties.
710
711 e.g.,
712 libcutils.so libcutils
713 libprotobuf-cpp-full-3.9.2.so libprotobuf-cpp-full
714 ...
715 */
716 snapshotOutputs = append(snapshotOutputs, installMapListFile(moduleNames, filepath.Join(configsDir, "module_names.txt")))
717
718 // All artifacts are ready. Sort them to normalize ninja and then zip.
719 sort.Slice(snapshotOutputs, func(i, j int) bool {
720 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
721 })
722
723 zipPath := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+".zip")
724 zipRule := android.NewRuleBuilder()
725
Inseob Kim8471cda2019-11-15 09:59:12 +0900726 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with xargs
Inseob Kim242ef0c2019-10-22 20:15:20 +0900727 snapshotOutputList := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+"_list")
728 zipRule.Command().
Inseob Kim8471cda2019-11-15 09:59:12 +0900729 Text("tr").
730 FlagWithArg("-d ", "\\'").
731 FlagWithRspFileInputList("< ", snapshotOutputs).
732 FlagWithOutput("> ", snapshotOutputList)
Inseob Kim242ef0c2019-10-22 20:15:20 +0900733
734 zipRule.Temporary(snapshotOutputList)
735
736 zipRule.Command().
737 BuiltTool(ctx, "soong_zip").
738 FlagWithOutput("-o ", zipPath).
739 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
740 FlagWithInput("-l ", snapshotOutputList)
741
742 zipRule.Build(pctx, ctx, zipPath.String(), "vndk snapshot "+zipPath.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900743 zipRule.DeleteTemporaryFiles()
Inseob Kim242ef0c2019-10-22 20:15:20 +0900744 c.vndkSnapshotZipFile = android.OptionalPathForPath(zipPath)
Inseob Kim1f086e22019-05-09 13:29:15 +0900745}
Jooyung Han097087b2019-10-22 19:32:18 +0900746
Jooyung Han0302a842019-10-30 18:43:49 +0900747func getVndkFileName(m *Module) (string, error) {
748 if library, ok := m.linker.(*libraryDecorator); ok {
749 return library.getLibNameHelper(m.BaseModuleName(), true) + ".so", nil
750 }
751 if prebuilt, ok := m.linker.(*prebuiltLibraryLinker); ok {
752 return prebuilt.libraryDecorator.getLibNameHelper(m.BaseModuleName(), true) + ".so", nil
753 }
754 return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker)
Jooyung Han097087b2019-10-22 19:32:18 +0900755}
756
757func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) {
Jooyung Han39edb6c2019-11-06 16:53:07 +0900758 llndk := android.SortedStringMapValues(llndkLibraries(ctx.Config()))
Jooyung Han0302a842019-10-30 18:43:49 +0900759 vndkcore := android.SortedStringMapValues(vndkCoreLibraries(ctx.Config()))
760 vndksp := android.SortedStringMapValues(vndkSpLibraries(ctx.Config()))
761 vndkprivate := android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config()))
Jooyung Han0302a842019-10-30 18:43:49 +0900762
Jooyung Han2216fb12019-11-06 16:46:15 +0900763 // Build list of vndk libs as merged & tagged & filter-out(libclang_rt):
Jooyung Han0302a842019-10-30 18:43:49 +0900764 // Since each target have different set of libclang_rt.* files,
765 // keep the common set of files in vndk.libraries.txt
766 var merged []string
Jooyung Han097087b2019-10-22 19:32:18 +0900767 filterOutLibClangRt := func(libList []string) (filtered []string) {
768 for _, lib := range libList {
769 if !strings.HasPrefix(lib, "libclang_rt.") {
770 filtered = append(filtered, lib)
771 }
772 }
773 return
774 }
775 merged = append(merged, addPrefix(filterOutLibClangRt(llndk), "LLNDK: ")...)
776 merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...)
777 merged = append(merged, addPrefix(filterOutLibClangRt(vndkcore), "VNDK-core: ")...)
778 merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...)
Jooyung Han39edb6c2019-11-06 16:53:07 +0900779 c.vndkLibrariesFile = android.PathForOutput(ctx, "vndk", "vndk.libraries.txt")
780 ctx.Build(pctx, android.BuildParams{
781 Rule: android.WriteFile,
782 Output: c.vndkLibrariesFile,
783 Description: "Writing " + c.vndkLibrariesFile.String(),
784 Args: map[string]string{
785 "content": strings.Join(merged, "\\n"),
786 },
787 })
Jooyung Han0302a842019-10-30 18:43:49 +0900788}
Jooyung Han097087b2019-10-22 19:32:18 +0900789
Jooyung Han0302a842019-10-30 18:43:49 +0900790func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
791 // Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if
792 // they been moved to an apex.
793 movedToApexLlndkLibraries := []string{}
Jooyung Han39edb6c2019-11-06 16:53:07 +0900794 for lib := range llndkLibraries(ctx.Config()) {
Jooyung Han0302a842019-10-30 18:43:49 +0900795 // Skip bionic libs, they are handled in different manner
796 if android.DirectlyInAnyApex(&notOnHostContext{}, lib) && !isBionic(lib) {
797 movedToApexLlndkLibraries = append(movedToApexLlndkLibraries, lib)
798 }
799 }
800 ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES", strings.Join(movedToApexLlndkLibraries, " "))
Jooyung Han39edb6c2019-11-06 16:53:07 +0900801
802 // Make uses LLNDK_LIBRARIES to determine which libraries to install.
803 // HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN.
804 // Therefore, by removing the library here, we cause it to only be installed if libc
805 // depends on it.
806 installedLlndkLibraries := []string{}
807 for lib := range llndkLibraries(ctx.Config()) {
808 if strings.HasPrefix(lib, "libclang_rt.hwasan-") {
809 continue
810 }
811 installedLlndkLibraries = append(installedLlndkLibraries, lib)
812 }
813 sort.Strings(installedLlndkLibraries)
814 ctx.Strict("LLNDK_LIBRARIES", strings.Join(installedLlndkLibraries, " "))
815
Jooyung Han0302a842019-10-30 18:43:49 +0900816 ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkCoreLibraries(ctx.Config())), " "))
817 ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(android.SortedStringKeys(vndkSpLibraries(ctx.Config())), " "))
818 ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkPrivateLibraries(ctx.Config())), " "))
819 ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(android.SortedStringKeys(vndkUsingCoreVariantLibraries(ctx.Config())), " "))
820
Jooyung Han0302a842019-10-30 18:43:49 +0900821 ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String())
Inseob Kim242ef0c2019-10-22 20:15:20 +0900822 ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String())
Jooyung Han097087b2019-10-22 19:32:18 +0900823}