blob: 73ff38bab55e5576cfd876e202e415dca0853398 [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 }
Jooyung Han61b66e92020-03-21 14:21:46 +0000300 if mctx.OtherModuleExists(name) {
301 mctx.AddFarVariationDependencies(m.Target().Variations(), llndkImplDep, name)
302 }
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900303}
Inseob Kim1f086e22019-05-09 13:29:15 +0900304
305func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
Jooyung Han0302a842019-10-30 18:43:49 +0900306 name := m.BaseModuleName()
307 filename, err := getVndkFileName(m)
308 if err != nil {
309 panic(err)
310 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900311
Jiyong Parkea97f512020-03-31 15:31:17 +0900312 if m.HasStubsVariants() {
313 mctx.PropertyErrorf("vndk.enabled", "This library provides stubs. Shouldn't be VNDK. Consider making it as LLNDK")
314 }
315
Inseob Kim1f086e22019-05-09 13:29:15 +0900316 vndkLibrariesLock.Lock()
317 defer vndkLibrariesLock.Unlock()
318
Jooyung Han097087b2019-10-22 19:32:18 +0900319 if inList(name, vndkMustUseVendorVariantList(mctx.Config())) {
320 m.Properties.MustUseVendorVariant = true
321 }
Jooyung Han0302a842019-10-30 18:43:49 +0900322 if mctx.DeviceConfig().VndkUseCoreVariant() && !m.Properties.MustUseVendorVariant {
323 vndkUsingCoreVariantLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900324 }
Jooyung Han0302a842019-10-30 18:43:49 +0900325
Inseob Kim1f086e22019-05-09 13:29:15 +0900326 if m.vndkdep.isVndkSp() {
Jooyung Han0302a842019-10-30 18:43:49 +0900327 vndkSpLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900328 } else {
Jooyung Han0302a842019-10-30 18:43:49 +0900329 vndkCoreLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900330 }
331 if !Bool(m.VendorProperties.Vendor_available) {
Jooyung Han0302a842019-10-30 18:43:49 +0900332 vndkPrivateLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900333 }
334}
335
Jooyung Han31c470b2019-10-18 16:26:59 +0900336func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
337 if !m.Enabled() {
338 return false
339 }
340
Jooyung Han87a7f302019-10-29 05:18:21 +0900341 if !mctx.Device() {
342 return false
343 }
344
Jooyung Han31c470b2019-10-18 16:26:59 +0900345 if m.Target().NativeBridge == android.NativeBridgeEnabled {
346 return false
347 }
348
349 // prebuilt vndk modules should match with device
350 // TODO(b/142675459): Use enabled: to select target device in vndk_prebuilt_shared
351 // When b/142675459 is landed, remove following check
352 if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.matchesWithDevice(mctx.DeviceConfig()) {
353 return false
354 }
355
356 if lib, ok := m.linker.(libraryInterface); ok {
Justin Yun5f7f7e82019-11-18 19:52:14 +0900357 useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
Jooyung Han87a7f302019-10-29 05:18:21 +0900358 mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
Jooyung Hana57af4a2020-01-23 05:36:59 +0000359 return lib.shared() && m.inVendor() && m.IsVndk() && !m.isVndkExt() && !useCoreVariant
Jooyung Han31c470b2019-10-18 16:26:59 +0900360 }
361 return false
362}
363
Inseob Kim1f086e22019-05-09 13:29:15 +0900364// gather list of vndk-core, vndk-sp, and ll-ndk libs
365func VndkMutator(mctx android.BottomUpMutatorContext) {
366 m, ok := mctx.Module().(*Module)
367 if !ok {
368 return
369 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900370 if !m.Enabled() {
371 return
372 }
Justin Yun7390ea32019-09-08 11:34:06 +0900373 if m.Target().NativeBridge == android.NativeBridgeEnabled {
374 // Skip native_bridge modules
375 return
376 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900377
378 if _, ok := m.linker.(*llndkStubDecorator); ok {
379 processLlndkLibrary(mctx, m)
380 return
381 }
382
383 lib, is_lib := m.linker.(*libraryDecorator)
384 prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
385
Inseob Kim64c43952019-08-26 16:52:35 +0900386 if (is_lib && lib.buildShared()) || (is_prebuilt_lib && prebuilt_lib.buildShared()) {
387 if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
Inseob Kim1f086e22019-05-09 13:29:15 +0900388 processVndkLibrary(mctx, m)
389 return
390 }
391 }
392}
393
394func init() {
Jooyung Han39edb6c2019-11-06 16:53:07 +0900395 android.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory)
Inseob Kim1f086e22019-05-09 13:29:15 +0900396 android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
Inseob Kim1f086e22019-05-09 13:29:15 +0900397}
398
Jooyung Han2216fb12019-11-06 16:46:15 +0900399type vndkLibrariesTxt struct {
400 android.ModuleBase
401 outputFile android.OutputPath
402}
403
Jooyung Han39edb6c2019-11-06 16:53:07 +0900404var _ android.PrebuiltEtcModule = &vndkLibrariesTxt{}
405var _ android.OutputFileProducer = &vndkLibrariesTxt{}
406
Jooyung Han2216fb12019-11-06 16:46:15 +0900407// vndk_libraries_txt is a special kind of module type in that it name is one of
408// - llndk.libraries.txt
409// - vndkcore.libraries.txt
410// - vndksp.libraries.txt
411// - vndkprivate.libraries.txt
412// - vndkcorevariant.libraries.txt
413// A module behaves like a prebuilt_etc but its content is generated by soong.
414// By being a soong module, these files can be referenced by other soong modules.
415// For example, apex_vndk can depend on these files as prebuilt.
Jooyung Han39edb6c2019-11-06 16:53:07 +0900416func VndkLibrariesTxtFactory() android.Module {
Jooyung Han2216fb12019-11-06 16:46:15 +0900417 m := &vndkLibrariesTxt{}
418 android.InitAndroidModule(m)
419 return m
420}
421
422func insertVndkVersion(filename string, vndkVersion string) string {
423 if index := strings.LastIndex(filename, "."); index != -1 {
424 return filename[:index] + "." + vndkVersion + filename[index:]
425 }
426 return filename
427}
428
429func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
430 var list []string
431 switch txt.Name() {
Jooyung Han39edb6c2019-11-06 16:53:07 +0900432 case llndkLibrariesTxt:
Jooyung Han2216fb12019-11-06 16:46:15 +0900433 for _, filename := range android.SortedStringMapValues(llndkLibraries(ctx.Config())) {
434 if strings.HasPrefix(filename, "libclang_rt.hwasan-") {
435 continue
436 }
437 list = append(list, filename)
438 }
Jooyung Han39edb6c2019-11-06 16:53:07 +0900439 case vndkCoreLibrariesTxt:
Jooyung Han2216fb12019-11-06 16:46:15 +0900440 list = android.SortedStringMapValues(vndkCoreLibraries(ctx.Config()))
Jooyung Han39edb6c2019-11-06 16:53:07 +0900441 case vndkSpLibrariesTxt:
Jooyung Han2216fb12019-11-06 16:46:15 +0900442 list = android.SortedStringMapValues(vndkSpLibraries(ctx.Config()))
Jooyung Han39edb6c2019-11-06 16:53:07 +0900443 case vndkPrivateLibrariesTxt:
Jooyung Han2216fb12019-11-06 16:46:15 +0900444 list = android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config()))
Jooyung Han39edb6c2019-11-06 16:53:07 +0900445 case vndkUsingCoreVariantLibrariesTxt:
Jooyung Han2216fb12019-11-06 16:46:15 +0900446 list = android.SortedStringMapValues(vndkUsingCoreVariantLibraries(ctx.Config()))
447 default:
448 ctx.ModuleErrorf("name(%s) is unknown.", txt.Name())
449 return
450 }
451
Kiyoung Kime1aa8ea2019-12-30 11:12:55 +0900452 var filename string
453 if txt.Name() != vndkUsingCoreVariantLibrariesTxt {
454 filename = insertVndkVersion(txt.Name(), ctx.DeviceConfig().PlatformVndkVersion())
455 } else {
456 filename = txt.Name()
457 }
458
Jooyung Han2216fb12019-11-06 16:46:15 +0900459 txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath
460 ctx.Build(pctx, android.BuildParams{
461 Rule: android.WriteFile,
462 Output: txt.outputFile,
463 Description: "Writing " + txt.outputFile.String(),
464 Args: map[string]string{
465 "content": strings.Join(list, "\\n"),
466 },
467 })
468
469 installPath := android.PathForModuleInstall(ctx, "etc")
470 ctx.InstallFile(installPath, filename, txt.outputFile)
471}
472
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900473func (txt *vndkLibrariesTxt) AndroidMkEntries() []android.AndroidMkEntries {
474 return []android.AndroidMkEntries{android.AndroidMkEntries{
Jooyung Han2216fb12019-11-06 16:46:15 +0900475 Class: "ETC",
476 OutputFile: android.OptionalPathForPath(txt.outputFile),
477 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
478 func(entries *android.AndroidMkEntries) {
479 entries.SetString("LOCAL_MODULE_STEM", txt.outputFile.Base())
480 },
481 },
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900482 }}
Jooyung Han2216fb12019-11-06 16:46:15 +0900483}
484
Jooyung Han39edb6c2019-11-06 16:53:07 +0900485func (txt *vndkLibrariesTxt) OutputFile() android.OutputPath {
486 return txt.outputFile
487}
488
489func (txt *vndkLibrariesTxt) OutputFiles(tag string) (android.Paths, error) {
490 return android.Paths{txt.outputFile}, nil
491}
492
493func (txt *vndkLibrariesTxt) SubDir() string {
494 return ""
495}
496
Inseob Kim1f086e22019-05-09 13:29:15 +0900497func VndkSnapshotSingleton() android.Singleton {
498 return &vndkSnapshotSingleton{}
499}
500
Jooyung Han0302a842019-10-30 18:43:49 +0900501type vndkSnapshotSingleton struct {
Jooyung Han39edb6c2019-11-06 16:53:07 +0900502 vndkLibrariesFile android.OutputPath
503 vndkSnapshotZipFile android.OptionalPath
Jooyung Han0302a842019-10-30 18:43:49 +0900504}
Inseob Kim1f086e22019-05-09 13:29:15 +0900505
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900506func isVndkSnapshotLibrary(config android.DeviceConfig, m *Module) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) {
507 if m.Target().NativeBridge == android.NativeBridgeEnabled {
508 return nil, "", false
509 }
510 if !m.inVendor() || !m.installable() || m.isSnapshotPrebuilt() {
511 return nil, "", false
512 }
513 l, ok := m.linker.(snapshotLibraryInterface)
514 if !ok || !l.shared() {
515 return nil, "", false
516 }
517 if m.VndkVersion() == config.PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() {
518 if m.isVndkSp() {
519 return l, "vndk-sp", true
520 } else {
521 return l, "vndk-core", true
522 }
523 }
524
525 return nil, "", false
526}
527
Inseob Kim1f086e22019-05-09 13:29:15 +0900528func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Jooyung Han0302a842019-10-30 18:43:49 +0900529 // build these files even if PlatformVndkVersion or BoardVndkVersion is not set
530 c.buildVndkLibrariesTxtFiles(ctx)
531
Inseob Kim1f086e22019-05-09 13:29:15 +0900532 // BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
533 if ctx.DeviceConfig().VndkVersion() != "current" {
534 return
535 }
536
537 if ctx.DeviceConfig().PlatformVndkVersion() == "" {
538 return
539 }
540
541 if ctx.DeviceConfig().BoardVndkRuntimeDisable() {
542 return
543 }
544
Inseob Kim242ef0c2019-10-22 20:15:20 +0900545 var snapshotOutputs android.Paths
546
547 /*
548 VNDK snapshot zipped artifacts directory structure:
549 {SNAPSHOT_ARCH}/
550 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
551 shared/
552 vndk-core/
553 (VNDK-core libraries, e.g. libbinder.so)
554 vndk-sp/
555 (VNDK-SP libraries, e.g. libc++.so)
556 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
557 shared/
558 vndk-core/
559 (VNDK-core libraries, e.g. libbinder.so)
560 vndk-sp/
561 (VNDK-SP libraries, e.g. libc++.so)
562 binder32/
563 (This directory is newly introduced in v28 (Android P) to hold
564 prebuilts built for 32-bit binder interface.)
565 arch-{TARGET_ARCH}-{TARGE_ARCH_VARIANT}/
566 ...
567 configs/
568 (various *.txt configuration files)
569 include/
570 (header files of same directory structure with source tree)
571 NOTICE_FILES/
572 (notice files of libraries, e.g. libcutils.so.txt)
573 */
Inseob Kim1f086e22019-05-09 13:29:15 +0900574
575 snapshotDir := "vndk-snapshot"
Inseob Kim242ef0c2019-10-22 20:15:20 +0900576 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
Inseob Kim1f086e22019-05-09 13:29:15 +0900577
Inseob Kim242ef0c2019-10-22 20:15:20 +0900578 configsDir := filepath.Join(snapshotArchDir, "configs")
579 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
580 includeDir := filepath.Join(snapshotArchDir, "include")
581
Inseob Kim242ef0c2019-10-22 20:15:20 +0900582 // set of notice files copied.
Inseob Kim1f086e22019-05-09 13:29:15 +0900583 noticeBuilt := make(map[string]bool)
584
Inseob Kim242ef0c2019-10-22 20:15:20 +0900585 // paths of VNDK modules for GPL license checking
586 modulePaths := make(map[string]string)
587
588 // actual module names of .so files
589 // e.g. moduleNames["libprotobuf-cpp-full-3.9.1.so"] = "libprotobuf-cpp-full"
590 moduleNames := make(map[string]string)
591
Inseob Kim8471cda2019-11-15 09:59:12 +0900592 var headers android.Paths
Inseob Kim242ef0c2019-10-22 20:15:20 +0900593
Inseob Kim8471cda2019-11-15 09:59:12 +0900594 installVndkSnapshotLib := func(m *Module, l snapshotLibraryInterface, vndkType string) (android.Paths, bool) {
Inseob Kim242ef0c2019-10-22 20:15:20 +0900595 var ret android.Paths
596
Inseob Kim8471cda2019-11-15 09:59:12 +0900597 targetArch := "arch-" + m.Target().Arch.ArchType.String()
598 if m.Target().Arch.ArchVariant != "" {
599 targetArch += "-" + m.Target().Arch.ArchVariant
Inseob Kim242ef0c2019-10-22 20:15:20 +0900600 }
Inseob Kimae553032019-05-14 18:52:49 +0900601
Inseob Kim8471cda2019-11-15 09:59:12 +0900602 libPath := m.outputFile.Path()
603 snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, libPath.Base())
604 ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
605
Inseob Kimae553032019-05-14 18:52:49 +0900606 if ctx.Config().VndkSnapshotBuildArtifacts() {
607 prop := struct {
608 ExportedDirs []string `json:",omitempty"`
609 ExportedSystemDirs []string `json:",omitempty"`
610 ExportedFlags []string `json:",omitempty"`
611 RelativeInstallPath string `json:",omitempty"`
612 }{}
613 prop.ExportedFlags = l.exportedFlags()
Jiyong Park74955042019-10-22 20:19:51 +0900614 prop.ExportedDirs = l.exportedDirs().Strings()
615 prop.ExportedSystemDirs = l.exportedSystemDirs().Strings()
Inseob Kimae553032019-05-14 18:52:49 +0900616 prop.RelativeInstallPath = m.RelativeInstallPath()
617
Inseob Kim242ef0c2019-10-22 20:15:20 +0900618 propOut := snapshotLibOut + ".json"
Inseob Kimae553032019-05-14 18:52:49 +0900619
620 j, err := json.Marshal(prop)
621 if err != nil {
622 ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
Inseob Kim242ef0c2019-10-22 20:15:20 +0900623 return nil, false
Inseob Kimae553032019-05-14 18:52:49 +0900624 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900625 ret = append(ret, writeStringToFile(ctx, string(j), propOut))
Inseob Kimae553032019-05-14 18:52:49 +0900626 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900627 return ret, true
Inseob Kimae553032019-05-14 18:52:49 +0900628 }
629
Inseob Kim1f086e22019-05-09 13:29:15 +0900630 ctx.VisitAllModules(func(module android.Module) {
631 m, ok := module.(*Module)
Inseob Kimae553032019-05-14 18:52:49 +0900632 if !ok || !m.Enabled() {
Inseob Kim1f086e22019-05-09 13:29:15 +0900633 return
634 }
635
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900636 l, vndkType, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m)
Inseob Kimae553032019-05-14 18:52:49 +0900637 if !ok {
dimitry51ea18a2019-05-20 10:39:52 +0200638 return
639 }
640
Inseob Kim8471cda2019-11-15 09:59:12 +0900641 // install .so files for appropriate modules.
642 // Also install .json files if VNDK_SNAPSHOT_BUILD_ARTIFACTS
Inseob Kim242ef0c2019-10-22 20:15:20 +0900643 libs, ok := installVndkSnapshotLib(m, l, vndkType)
Inseob Kimae553032019-05-14 18:52:49 +0900644 if !ok {
Inseob Kim1f086e22019-05-09 13:29:15 +0900645 return
646 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900647 snapshotOutputs = append(snapshotOutputs, libs...)
Inseob Kim1f086e22019-05-09 13:29:15 +0900648
Inseob Kim8471cda2019-11-15 09:59:12 +0900649 // These are for generating module_names.txt and module_paths.txt
650 stem := m.outputFile.Path().Base()
651 moduleNames[stem] = ctx.ModuleName(m)
652 modulePaths[stem] = ctx.ModuleDir(m)
653
Bob Badoura75b0572020-02-18 20:21:55 -0800654 if len(m.NoticeFiles()) > 0 {
Inseob Kim8471cda2019-11-15 09:59:12 +0900655 noticeName := stem + ".txt"
656 // skip already copied notice file
657 if _, ok := noticeBuilt[noticeName]; !ok {
658 noticeBuilt[noticeName] = true
Bob Badoura75b0572020-02-18 20:21:55 -0800659 snapshotOutputs = append(snapshotOutputs, combineNotices(
660 ctx, m.NoticeFiles(), filepath.Join(noticeDir, noticeName)))
Inseob Kim8471cda2019-11-15 09:59:12 +0900661 }
662 }
663
664 if ctx.Config().VndkSnapshotBuildArtifacts() {
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900665 headers = append(headers, l.snapshotHeaders()...)
Inseob Kimae553032019-05-14 18:52:49 +0900666 }
667 })
Inseob Kim1f086e22019-05-09 13:29:15 +0900668
Inseob Kim8471cda2019-11-15 09:59:12 +0900669 // install all headers after removing duplicates
670 for _, header := range android.FirstUniquePaths(headers) {
671 snapshotOutputs = append(snapshotOutputs, copyFile(
672 ctx, header, filepath.Join(includeDir, header.String())))
Inseob Kimae553032019-05-14 18:52:49 +0900673 }
674
Jooyung Han39edb6c2019-11-06 16:53:07 +0900675 // install *.libraries.txt except vndkcorevariant.libraries.txt
676 ctx.VisitAllModules(func(module android.Module) {
677 m, ok := module.(*vndkLibrariesTxt)
678 if !ok || !m.Enabled() || m.Name() == vndkUsingCoreVariantLibrariesTxt {
679 return
680 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900681 snapshotOutputs = append(snapshotOutputs, copyFile(
682 ctx, m.OutputFile(), filepath.Join(configsDir, m.Name())))
Jooyung Han39edb6c2019-11-06 16:53:07 +0900683 })
Inseob Kim1f086e22019-05-09 13:29:15 +0900684
Inseob Kim242ef0c2019-10-22 20:15:20 +0900685 /*
686 Dump a map to a list file as:
Inseob Kim1f086e22019-05-09 13:29:15 +0900687
Inseob Kim242ef0c2019-10-22 20:15:20 +0900688 {key1} {value1}
689 {key2} {value2}
690 ...
691 */
692 installMapListFile := func(m map[string]string, path string) android.OutputPath {
693 var txtBuilder strings.Builder
694 for idx, k := range android.SortedStringKeys(m) {
695 if idx > 0 {
696 txtBuilder.WriteString("\\n")
697 }
698 txtBuilder.WriteString(k)
699 txtBuilder.WriteString(" ")
700 txtBuilder.WriteString(m[k])
Inseob Kim1f086e22019-05-09 13:29:15 +0900701 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900702 return writeStringToFile(ctx, txtBuilder.String(), path)
Inseob Kim1f086e22019-05-09 13:29:15 +0900703 }
704
Inseob Kim242ef0c2019-10-22 20:15:20 +0900705 /*
706 module_paths.txt contains paths on which VNDK modules are defined.
707 e.g.,
708 libbase.so system/core/base
709 libc.so bionic/libc
710 ...
711 */
712 snapshotOutputs = append(snapshotOutputs, installMapListFile(modulePaths, filepath.Join(configsDir, "module_paths.txt")))
713
714 /*
715 module_names.txt contains names as which VNDK modules are defined,
716 because output filename and module name can be different with stem and suffix properties.
717
718 e.g.,
719 libcutils.so libcutils
720 libprotobuf-cpp-full-3.9.2.so libprotobuf-cpp-full
721 ...
722 */
723 snapshotOutputs = append(snapshotOutputs, installMapListFile(moduleNames, filepath.Join(configsDir, "module_names.txt")))
724
725 // All artifacts are ready. Sort them to normalize ninja and then zip.
726 sort.Slice(snapshotOutputs, func(i, j int) bool {
727 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
728 })
729
730 zipPath := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+".zip")
731 zipRule := android.NewRuleBuilder()
732
Inseob Kim8471cda2019-11-15 09:59:12 +0900733 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with xargs
Inseob Kim242ef0c2019-10-22 20:15:20 +0900734 snapshotOutputList := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+"_list")
735 zipRule.Command().
Inseob Kim8471cda2019-11-15 09:59:12 +0900736 Text("tr").
737 FlagWithArg("-d ", "\\'").
738 FlagWithRspFileInputList("< ", snapshotOutputs).
739 FlagWithOutput("> ", snapshotOutputList)
Inseob Kim242ef0c2019-10-22 20:15:20 +0900740
741 zipRule.Temporary(snapshotOutputList)
742
743 zipRule.Command().
744 BuiltTool(ctx, "soong_zip").
745 FlagWithOutput("-o ", zipPath).
746 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
747 FlagWithInput("-l ", snapshotOutputList)
748
749 zipRule.Build(pctx, ctx, zipPath.String(), "vndk snapshot "+zipPath.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900750 zipRule.DeleteTemporaryFiles()
Inseob Kim242ef0c2019-10-22 20:15:20 +0900751 c.vndkSnapshotZipFile = android.OptionalPathForPath(zipPath)
Inseob Kim1f086e22019-05-09 13:29:15 +0900752}
Jooyung Han097087b2019-10-22 19:32:18 +0900753
Jooyung Han0302a842019-10-30 18:43:49 +0900754func getVndkFileName(m *Module) (string, error) {
755 if library, ok := m.linker.(*libraryDecorator); ok {
756 return library.getLibNameHelper(m.BaseModuleName(), true) + ".so", nil
757 }
758 if prebuilt, ok := m.linker.(*prebuiltLibraryLinker); ok {
759 return prebuilt.libraryDecorator.getLibNameHelper(m.BaseModuleName(), true) + ".so", nil
760 }
761 return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker)
Jooyung Han097087b2019-10-22 19:32:18 +0900762}
763
764func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) {
Jooyung Han39edb6c2019-11-06 16:53:07 +0900765 llndk := android.SortedStringMapValues(llndkLibraries(ctx.Config()))
Jooyung Han0302a842019-10-30 18:43:49 +0900766 vndkcore := android.SortedStringMapValues(vndkCoreLibraries(ctx.Config()))
767 vndksp := android.SortedStringMapValues(vndkSpLibraries(ctx.Config()))
768 vndkprivate := android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config()))
Jooyung Han0302a842019-10-30 18:43:49 +0900769
Jooyung Han2216fb12019-11-06 16:46:15 +0900770 // Build list of vndk libs as merged & tagged & filter-out(libclang_rt):
Jooyung Han0302a842019-10-30 18:43:49 +0900771 // Since each target have different set of libclang_rt.* files,
772 // keep the common set of files in vndk.libraries.txt
773 var merged []string
Jooyung Han097087b2019-10-22 19:32:18 +0900774 filterOutLibClangRt := func(libList []string) (filtered []string) {
775 for _, lib := range libList {
776 if !strings.HasPrefix(lib, "libclang_rt.") {
777 filtered = append(filtered, lib)
778 }
779 }
780 return
781 }
782 merged = append(merged, addPrefix(filterOutLibClangRt(llndk), "LLNDK: ")...)
783 merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...)
784 merged = append(merged, addPrefix(filterOutLibClangRt(vndkcore), "VNDK-core: ")...)
785 merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...)
Jooyung Han39edb6c2019-11-06 16:53:07 +0900786 c.vndkLibrariesFile = android.PathForOutput(ctx, "vndk", "vndk.libraries.txt")
787 ctx.Build(pctx, android.BuildParams{
788 Rule: android.WriteFile,
789 Output: c.vndkLibrariesFile,
790 Description: "Writing " + c.vndkLibrariesFile.String(),
791 Args: map[string]string{
792 "content": strings.Join(merged, "\\n"),
793 },
794 })
Jooyung Han0302a842019-10-30 18:43:49 +0900795}
Jooyung Han097087b2019-10-22 19:32:18 +0900796
Jooyung Han0302a842019-10-30 18:43:49 +0900797func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
798 // Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if
799 // they been moved to an apex.
800 movedToApexLlndkLibraries := []string{}
Jooyung Han39edb6c2019-11-06 16:53:07 +0900801 for lib := range llndkLibraries(ctx.Config()) {
Jooyung Han0302a842019-10-30 18:43:49 +0900802 // Skip bionic libs, they are handled in different manner
803 if android.DirectlyInAnyApex(&notOnHostContext{}, lib) && !isBionic(lib) {
804 movedToApexLlndkLibraries = append(movedToApexLlndkLibraries, lib)
805 }
806 }
807 ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES", strings.Join(movedToApexLlndkLibraries, " "))
Jooyung Han39edb6c2019-11-06 16:53:07 +0900808
809 // Make uses LLNDK_LIBRARIES to determine which libraries to install.
810 // HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN.
811 // Therefore, by removing the library here, we cause it to only be installed if libc
812 // depends on it.
813 installedLlndkLibraries := []string{}
814 for lib := range llndkLibraries(ctx.Config()) {
815 if strings.HasPrefix(lib, "libclang_rt.hwasan-") {
816 continue
817 }
818 installedLlndkLibraries = append(installedLlndkLibraries, lib)
819 }
820 sort.Strings(installedLlndkLibraries)
821 ctx.Strict("LLNDK_LIBRARIES", strings.Join(installedLlndkLibraries, " "))
822
Jooyung Han0302a842019-10-30 18:43:49 +0900823 ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkCoreLibraries(ctx.Config())), " "))
824 ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(android.SortedStringKeys(vndkSpLibraries(ctx.Config())), " "))
825 ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkPrivateLibraries(ctx.Config())), " "))
826 ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(android.SortedStringKeys(vndkUsingCoreVariantLibraries(ctx.Config())), " "))
827
Jooyung Han0302a842019-10-30 18:43:49 +0900828 ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String())
Inseob Kim242ef0c2019-10-22 20:15:20 +0900829 ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String())
Jooyung Han097087b2019-10-22 19:32:18 +0900830}