Home | History | Annotate | Download | only in cc
      1 // 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 
     15 package cc
     16 
     17 import (
     18 	"sort"
     19 	"strings"
     20 	"sync"
     21 
     22 	"android/soong/android"
     23 )
     24 
     25 type 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 		//
     30 		// `vendor_vailable` must be explicitly set to either true or
     31 		// false together with `vndk: {enabled: true}`.
     32 		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
     45 
     46 		// Extending another module
     47 		Extends *string
     48 	}
     49 }
     50 
     51 type vndkdep struct {
     52 	Properties VndkProperties
     53 }
     54 
     55 func (vndk *vndkdep) props() []interface{} {
     56 	return []interface{}{&vndk.Properties}
     57 }
     58 
     59 func (vndk *vndkdep) begin(ctx BaseModuleContext) {}
     60 
     61 func (vndk *vndkdep) deps(ctx BaseModuleContext, deps Deps) Deps {
     62 	return deps
     63 }
     64 
     65 func (vndk *vndkdep) isVndk() bool {
     66 	return Bool(vndk.Properties.Vndk.Enabled)
     67 }
     68 
     69 func (vndk *vndkdep) isVndkSp() bool {
     70 	return Bool(vndk.Properties.Vndk.Support_system_process)
     71 }
     72 
     73 func (vndk *vndkdep) isVndkExt() bool {
     74 	return vndk.Properties.Vndk.Extends != nil
     75 }
     76 
     77 func (vndk *vndkdep) getVndkExtendsModuleName() string {
     78 	return String(vndk.Properties.Vndk.Extends)
     79 }
     80 
     81 func (vndk *vndkdep) typeName() string {
     82 	if !vndk.isVndk() {
     83 		return "native:vendor"
     84 	}
     85 	if !vndk.isVndkExt() {
     86 		if !vndk.isVndkSp() {
     87 			return "native:vendor:vndk"
     88 		}
     89 		return "native:vendor:vndksp"
     90 	}
     91 	if !vndk.isVndkSp() {
     92 		return "native:vendor:vndkext"
     93 	}
     94 	return "native:vendor:vndkspext"
     95 }
     96 
     97 func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag dependencyTag) {
     98 	if to.linker == nil {
     99 		return
    100 	}
    101 	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
    105 		if lib, ok := to.linker.(*llndkStubDecorator); ok && !Bool(lib.Properties.Vendor_available) {
    106 			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 	}
    119 	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 	}
    129 	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 	}
    149 	if to.vndkdep == nil {
    150 		return
    151 	}
    152 
    153 	// Check the dependencies of VNDK shared libraries.
    154 	if !vndkIsVndkDepAllowed(vndk, to.vndkdep) {
    155 		ctx.ModuleErrorf("(%s) should not link to %q (%s)",
    156 			vndk.typeName(), to.Name(), to.vndkdep.typeName())
    157 		return
    158 	}
    159 }
    160 
    161 func 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
    171 	}
    172 	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
    186 }
    187 
    188 var (
    189 	vndkCoreLibraries    []string
    190 	vndkSpLibraries      []string
    191 	llndkLibraries       []string
    192 	vndkPrivateLibraries []string
    193 	vndkLibrariesLock    sync.Mutex
    194 )
    195 
    196 // gather list of vndk-core, vndk-sp, and ll-ndk libs
    197 func vndkMutator(mctx android.BottomUpMutatorContext) {
    198 	if m, ok := mctx.Module().(*Module); ok && m.Enabled() {
    199 		if lib, ok := m.linker.(*llndkStubDecorator); ok {
    200 			vndkLibrariesLock.Lock()
    201 			defer vndkLibrariesLock.Unlock()
    202 			name := strings.TrimSuffix(m.Name(), llndkLibrarySuffix)
    203 			if !inList(name, llndkLibraries) {
    204 				llndkLibraries = append(llndkLibraries, name)
    205 				sort.Strings(llndkLibraries)
    206 			}
    207 			if !Bool(lib.Properties.Vendor_available) {
    208 				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_")
    218 				if m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
    219 					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 						}
    231 					}
    232 					if !Bool(m.VendorProperties.Vendor_available) {
    233 						if !inList(name, vndkPrivateLibraries) {
    234 							vndkPrivateLibraries = append(vndkPrivateLibraries, name)
    235 							sort.Strings(vndkPrivateLibraries)
    236 						}
    237 					}
    238 				}
    239 			}
    240 		}
    241 	}
    242 }
    243