github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/cc/vndk.go (about)

     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  }