blob: 5a24a9816dc66194f90065a09a1fb55fe31fff05 [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 (
Colin Cross766efbc2017-08-17 14:55:15 -070018 "sort"
Jiyong Parkd5b18a52017-08-03 21:22:50 +090019 "strings"
20 "sync"
21
Justin Yun8effde42017-06-23 19:24:43 +090022 "android/soong/android"
23)
24
25type VndkProperties struct {
26 Vndk struct {
27 // declared as a VNDK or VNDK-SP module. The vendor variant
28 // will be installed in /system instead of /vendor partition.
29 //
Jiyong Park82e2bf32017-08-16 14:05:54 +090030 // `vendor_vailable` must be explicitly set to either true or
31 // false together with `vndk: {enabled: true}`.
Justin Yun8effde42017-06-23 19:24:43 +090032 Enabled *bool
33
34 // declared as a VNDK-SP module, which is a subset of VNDK.
35 //
36 // `vndk: { enabled: true }` must set together.
37 //
38 // All these modules are allowed to link to VNDK-SP or LL-NDK
39 // modules only. Other dependency will cause link-type errors.
40 //
41 // If `support_system_process` is not set or set to false,
42 // the module is VNDK-core and can link to other VNDK-core,
43 // VNDK-SP or LL-NDK modules only.
44 Support_system_process *bool
Logan Chienf3511742017-10-31 18:04:35 +080045
46 // Extending another module
47 Extends *string
Justin Yun8effde42017-06-23 19:24:43 +090048 }
49}
50
51type vndkdep struct {
52 Properties VndkProperties
53}
54
55func (vndk *vndkdep) props() []interface{} {
56 return []interface{}{&vndk.Properties}
57}
58
59func (vndk *vndkdep) begin(ctx BaseModuleContext) {}
60
61func (vndk *vndkdep) deps(ctx BaseModuleContext, deps Deps) Deps {
62 return deps
63}
64
65func (vndk *vndkdep) isVndk() bool {
66 return Bool(vndk.Properties.Vndk.Enabled)
67}
68
69func (vndk *vndkdep) isVndkSp() bool {
70 return Bool(vndk.Properties.Vndk.Support_system_process)
71}
72
Logan Chienf3511742017-10-31 18:04:35 +080073func (vndk *vndkdep) isVndkExt() bool {
74 return vndk.Properties.Vndk.Extends != nil
75}
76
77func (vndk *vndkdep) getVndkExtendsModuleName() string {
78 return String(vndk.Properties.Vndk.Extends)
79}
80
Justin Yun8effde42017-06-23 19:24:43 +090081func (vndk *vndkdep) typeName() string {
82 if !vndk.isVndk() {
83 return "native:vendor"
84 }
Logan Chienf3511742017-10-31 18:04:35 +080085 if !vndk.isVndkExt() {
86 if !vndk.isVndkSp() {
87 return "native:vendor:vndk"
88 }
89 return "native:vendor:vndksp"
Justin Yun8effde42017-06-23 19:24:43 +090090 }
Logan Chienf3511742017-10-31 18:04:35 +080091 if !vndk.isVndkSp() {
92 return "native:vendor:vndkext"
93 }
94 return "native:vendor:vndkspext"
Justin Yun8effde42017-06-23 19:24:43 +090095}
96
Logan Chienf3511742017-10-31 18:04:35 +080097func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag dependencyTag) {
Justin Yun8effde42017-06-23 19:24:43 +090098 if to.linker == nil {
99 return
100 }
Jiyong Park82e2bf32017-08-16 14:05:54 +0900101 if !vndk.isVndk() {
102 // Non-VNDK modules (those installed to /vendor) can't depend on modules marked with
103 // vendor_available: false.
104 violation := false
Nan Zhang0007d812017-11-07 10:57:05 -0800105 if lib, ok := to.linker.(*llndkStubDecorator); ok && !Bool(lib.Properties.Vendor_available) {
Jiyong Park82e2bf32017-08-16 14:05:54 +0900106 violation = true
107 } else {
108 if _, ok := to.linker.(libraryInterface); ok && to.VendorProperties.Vendor_available != nil && !Bool(to.VendorProperties.Vendor_available) {
109 // Vendor_available == nil && !Bool(Vendor_available) should be okay since
110 // it means a vendor-only library which is a valid dependency for non-VNDK
111 // modules.
112 violation = true
113 }
114 }
115 if violation {
116 ctx.ModuleErrorf("Vendor module that is not VNDK should not link to %q which is marked as `vendor_available: false`", to.Name())
117 }
118 }
Justin Yun8effde42017-06-23 19:24:43 +0900119 if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() {
120 // Check only shared libraries.
121 // Other (static and LL-NDK) libraries are allowed to link.
122 return
123 }
124 if !to.Properties.UseVndk {
125 ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library",
126 vndk.typeName(), to.Name())
127 return
128 }
Logan Chienf3511742017-10-31 18:04:35 +0800129 if tag == vndkExtDepTag {
130 // Ensure `extends: "name"` property refers a vndk module that has vendor_available
131 // and has identical vndk properties.
132 if to.vndkdep == nil || !to.vndkdep.isVndk() {
133 ctx.ModuleErrorf("`extends` refers a non-vndk module %q", to.Name())
134 return
135 }
136 if vndk.isVndkSp() != to.vndkdep.isVndkSp() {
137 ctx.ModuleErrorf(
138 "`extends` refers a module %q with mismatched support_system_process",
139 to.Name())
140 return
141 }
142 if !Bool(to.VendorProperties.Vendor_available) {
143 ctx.ModuleErrorf(
144 "`extends` refers module %q which does not have `vendor_available: true`",
145 to.Name())
146 return
147 }
148 }
Justin Yun8effde42017-06-23 19:24:43 +0900149 if to.vndkdep == nil {
150 return
151 }
Logan Chienf3511742017-10-31 18:04:35 +0800152
Logan Chiend3c59a22018-03-29 14:08:15 +0800153 // Check the dependencies of VNDK shared libraries.
154 if !vndkIsVndkDepAllowed(vndk, to.vndkdep) {
Logan Chienf3511742017-10-31 18:04:35 +0800155 ctx.ModuleErrorf("(%s) should not link to %q (%s)",
156 vndk.typeName(), to.Name(), to.vndkdep.typeName())
157 return
158 }
Logan Chiend3c59a22018-03-29 14:08:15 +0800159}
Logan Chienf3511742017-10-31 18:04:35 +0800160
Logan Chiend3c59a22018-03-29 14:08:15 +0800161func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) bool {
162 // Check the dependencies of VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext and vendor modules.
163 if from.isVndkExt() {
164 if from.isVndkSp() {
165 // VNDK-SP-Ext may depend on VNDK-SP, VNDK-SP-Ext, or vendor libs (excluding
166 // VNDK and VNDK-Ext).
167 return to.isVndkSp() || !to.isVndk()
168 }
169 // VNDK-Ext may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
170 return true
Justin Yun8effde42017-06-23 19:24:43 +0900171 }
Logan Chiend3c59a22018-03-29 14:08:15 +0800172 if from.isVndk() {
173 if to.isVndkExt() {
174 // VNDK-core and VNDK-SP must not depend on VNDK extensions.
175 return false
176 }
177 if from.isVndkSp() {
178 // VNDK-SP must only depend on VNDK-SP.
179 return to.isVndkSp()
180 }
181 // VNDK-core may depend on VNDK-core or VNDK-SP.
182 return to.isVndk()
183 }
184 // Vendor modules may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
185 return true
Justin Yun8effde42017-06-23 19:24:43 +0900186}
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900187
188var (
Jiyong Park82e2bf32017-08-16 14:05:54 +0900189 vndkCoreLibraries []string
190 vndkSpLibraries []string
191 llndkLibraries []string
192 vndkPrivateLibraries []string
193 vndkLibrariesLock sync.Mutex
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900194)
195
196// gather list of vndk-core, vndk-sp, and ll-ndk libs
197func vndkMutator(mctx android.BottomUpMutatorContext) {
Jiyong Park4b032222018-02-16 22:14:07 +0900198 if m, ok := mctx.Module().(*Module); ok && m.Enabled() {
Jiyong Park82e2bf32017-08-16 14:05:54 +0900199 if lib, ok := m.linker.(*llndkStubDecorator); ok {
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900200 vndkLibrariesLock.Lock()
201 defer vndkLibrariesLock.Unlock()
202 name := strings.TrimSuffix(m.Name(), llndkLibrarySuffix)
203 if !inList(name, llndkLibraries) {
204 llndkLibraries = append(llndkLibraries, name)
Colin Cross766efbc2017-08-17 14:55:15 -0700205 sort.Strings(llndkLibraries)
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900206 }
Nan Zhang0007d812017-11-07 10:57:05 -0800207 if !Bool(lib.Properties.Vendor_available) {
Jiyong Park82e2bf32017-08-16 14:05:54 +0900208 if !inList(name, vndkPrivateLibraries) {
209 vndkPrivateLibraries = append(vndkPrivateLibraries, name)
210 sort.Strings(vndkPrivateLibraries)
211 }
212 }
213 } else {
214 lib, is_lib := m.linker.(*libraryDecorator)
215 prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
216 if (is_lib && lib.shared()) || (is_prebuilt_lib && prebuilt_lib.shared()) {
217 name := strings.TrimPrefix(m.Name(), "prebuilt_")
Logan Chienf3511742017-10-31 18:04:35 +0800218 if m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
Jiyong Park82e2bf32017-08-16 14:05:54 +0900219 vndkLibrariesLock.Lock()
220 defer vndkLibrariesLock.Unlock()
221 if m.vndkdep.isVndkSp() {
222 if !inList(name, vndkSpLibraries) {
223 vndkSpLibraries = append(vndkSpLibraries, name)
224 sort.Strings(vndkSpLibraries)
225 }
226 } else {
227 if !inList(name, vndkCoreLibraries) {
228 vndkCoreLibraries = append(vndkCoreLibraries, name)
229 sort.Strings(vndkCoreLibraries)
230 }
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900231 }
Jiyong Park82e2bf32017-08-16 14:05:54 +0900232 if !Bool(m.VendorProperties.Vendor_available) {
233 if !inList(name, vndkPrivateLibraries) {
234 vndkPrivateLibraries = append(vndkPrivateLibraries, name)
235 sort.Strings(vndkPrivateLibraries)
236 }
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900237 }
238 }
239 }
240 }
241 }
242}