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

     1  // Copyright 2015 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 android
    16  
    17  import (
    18  	"encoding/json"
    19  	"fmt"
    20  	"io/ioutil"
    21  	"os"
    22  	"path/filepath"
    23  	"runtime"
    24  	"strconv"
    25  	"strings"
    26  	"sync"
    27  
    28  	"github.com/google/blueprint/bootstrap"
    29  	"github.com/google/blueprint/proptools"
    30  )
    31  
    32  var Bool = proptools.Bool
    33  var String = proptools.String
    34  var FutureApiLevel = 10000
    35  
    36  // The configuration file name
    37  const configFileName = "soong.config"
    38  const productVariablesFileName = "soong.variables"
    39  
    40  // A FileConfigurableOptions contains options which can be configured by the
    41  // config file. These will be included in the config struct.
    42  type FileConfigurableOptions struct {
    43  	Mega_device *bool `json:",omitempty"`
    44  	Ndk_abis    *bool `json:",omitempty"`
    45  	Host_bionic *bool `json:",omitempty"`
    46  }
    47  
    48  func (f *FileConfigurableOptions) SetDefaultConfig() {
    49  	*f = FileConfigurableOptions{}
    50  }
    51  
    52  // A Config object represents the entire build configuration for Android.
    53  type Config struct {
    54  	*config
    55  }
    56  
    57  func (c Config) BuildDir() string {
    58  	return c.buildDir
    59  }
    60  
    61  // A DeviceConfig object represents the configuration for a particular device being built.  For
    62  // now there will only be one of these, but in the future there may be multiple devices being
    63  // built
    64  type DeviceConfig struct {
    65  	*deviceConfig
    66  }
    67  
    68  type VendorConfig interface {
    69  	// Bool interprets the variable named `name` as a boolean, returning true if, after
    70  	// lowercasing, it matches one of "1", "y", "yes", "on", or "true". Unset, or any other
    71  	// value will return false.
    72  	Bool(name string) bool
    73  
    74  	// String returns the string value of `name`. If the variable was not set, it will
    75  	// return the empty string.
    76  	String(name string) string
    77  
    78  	// IsSet returns whether the variable `name` was set by Make.
    79  	IsSet(name string) bool
    80  }
    81  
    82  type config struct {
    83  	FileConfigurableOptions
    84  	productVariables productVariables
    85  
    86  	// Only available on configs created by TestConfig
    87  	TestProductVariables *productVariables
    88  
    89  	PrimaryBuilder           string
    90  	ConfigFileName           string
    91  	ProductVariablesFileName string
    92  
    93  	Targets        map[OsClass][]Target
    94  	BuildOsVariant string
    95  
    96  	deviceConfig *deviceConfig
    97  
    98  	srcDir   string // the path of the root source directory
    99  	buildDir string // the path of the build output directory
   100  
   101  	env       map[string]string
   102  	envLock   sync.Mutex
   103  	envDeps   map[string]string
   104  	envFrozen bool
   105  
   106  	inMake bool
   107  
   108  	captureBuild      bool // true for tests, saves build parameters for each module
   109  	ignoreEnvironment bool // true for tests, returns empty from all Getenv calls
   110  
   111  	useOpenJDK9    bool // Use OpenJDK9, but possibly target 1.8
   112  	targetOpenJDK9 bool // Use OpenJDK9 and target 1.9
   113  
   114  	stopBefore bootstrap.StopBefore
   115  
   116  	OncePer
   117  }
   118  
   119  type deviceConfig struct {
   120  	config *config
   121  	OncePer
   122  }
   123  
   124  type vendorConfig map[string]string
   125  
   126  type jsonConfigurable interface {
   127  	SetDefaultConfig()
   128  }
   129  
   130  func loadConfig(config *config) error {
   131  	err := loadFromConfigFile(&config.FileConfigurableOptions, config.ConfigFileName)
   132  	if err != nil {
   133  		return err
   134  	}
   135  
   136  	return loadFromConfigFile(&config.productVariables, config.ProductVariablesFileName)
   137  }
   138  
   139  // loads configuration options from a JSON file in the cwd.
   140  func loadFromConfigFile(configurable jsonConfigurable, filename string) error {
   141  	// Try to open the file
   142  	configFileReader, err := os.Open(filename)
   143  	defer configFileReader.Close()
   144  	if os.IsNotExist(err) {
   145  		// Need to create a file, so that blueprint & ninja don't get in
   146  		// a dependency tracking loop.
   147  		// Make a file-configurable-options with defaults, write it out using
   148  		// a json writer.
   149  		configurable.SetDefaultConfig()
   150  		err = saveToConfigFile(configurable, filename)
   151  		if err != nil {
   152  			return err
   153  		}
   154  	} else if err != nil {
   155  		return fmt.Errorf("config file: could not open %s: %s", filename, err.Error())
   156  	} else {
   157  		// Make a decoder for it
   158  		jsonDecoder := json.NewDecoder(configFileReader)
   159  		err = jsonDecoder.Decode(configurable)
   160  		if err != nil {
   161  			return fmt.Errorf("config file: %s did not parse correctly: %s", filename, err.Error())
   162  		}
   163  	}
   164  
   165  	// No error
   166  	return nil
   167  }
   168  
   169  // atomically writes the config file in case two copies of soong_build are running simultaneously
   170  // (for example, docs generation and ninja manifest generation)
   171  func saveToConfigFile(config jsonConfigurable, filename string) error {
   172  	data, err := json.MarshalIndent(&config, "", "    ")
   173  	if err != nil {
   174  		return fmt.Errorf("cannot marshal config data: %s", err.Error())
   175  	}
   176  
   177  	f, err := ioutil.TempFile(filepath.Dir(filename), "config")
   178  	if err != nil {
   179  		return fmt.Errorf("cannot create empty config file %s: %s\n", filename, err.Error())
   180  	}
   181  	defer os.Remove(f.Name())
   182  	defer f.Close()
   183  
   184  	_, err = f.Write(data)
   185  	if err != nil {
   186  		return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error())
   187  	}
   188  
   189  	_, err = f.WriteString("\n")
   190  	if err != nil {
   191  		return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error())
   192  	}
   193  
   194  	f.Close()
   195  	os.Rename(f.Name(), filename)
   196  
   197  	return nil
   198  }
   199  
   200  // TestConfig returns a Config object suitable for using for tests
   201  func TestConfig(buildDir string, env map[string]string) Config {
   202  	config := &config{
   203  		productVariables: productVariables{
   204  			DeviceName:           stringPtr("test_device"),
   205  			Platform_sdk_version: intPtr(26),
   206  			AAPTConfig:           &[]string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
   207  			AAPTPreferredConfig:  stringPtr("xhdpi"),
   208  			AAPTCharacteristics:  stringPtr("nosdcard"),
   209  			AAPTPrebuiltDPI:      &[]string{"xhdpi", "xxhdpi"},
   210  		},
   211  
   212  		buildDir:     buildDir,
   213  		captureBuild: true,
   214  		env:          env,
   215  	}
   216  	config.deviceConfig = &deviceConfig{
   217  		config: config,
   218  	}
   219  	config.TestProductVariables = &config.productVariables
   220  
   221  	if err := config.fromEnv(); err != nil {
   222  		panic(err)
   223  	}
   224  
   225  	return Config{config}
   226  }
   227  
   228  // TestConfig returns a Config object suitable for using for tests that need to run the arch mutator
   229  func TestArchConfig(buildDir string, env map[string]string) Config {
   230  	testConfig := TestConfig(buildDir, env)
   231  	config := testConfig.config
   232  
   233  	config.Targets = map[OsClass][]Target{
   234  		Device: []Target{
   235  			{Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Native: true}},
   236  			{Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Native: true}},
   237  		},
   238  		Host: []Target{
   239  			{BuildOs, Arch{ArchType: X86_64}},
   240  			{BuildOs, Arch{ArchType: X86}},
   241  		},
   242  	}
   243  
   244  	return testConfig
   245  }
   246  
   247  // New creates a new Config object.  The srcDir argument specifies the path to
   248  // the root source directory. It also loads the config file, if found.
   249  func NewConfig(srcDir, buildDir string) (Config, error) {
   250  	// Make a config with default options
   251  	config := &config{
   252  		ConfigFileName:           filepath.Join(buildDir, configFileName),
   253  		ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName),
   254  
   255  		env: originalEnv,
   256  
   257  		srcDir:   srcDir,
   258  		buildDir: buildDir,
   259  	}
   260  
   261  	config.deviceConfig = &deviceConfig{
   262  		config: config,
   263  	}
   264  
   265  	// Sanity check the build and source directories. This won't catch strange
   266  	// configurations with symlinks, but at least checks the obvious cases.
   267  	absBuildDir, err := filepath.Abs(buildDir)
   268  	if err != nil {
   269  		return Config{}, err
   270  	}
   271  
   272  	absSrcDir, err := filepath.Abs(srcDir)
   273  	if err != nil {
   274  		return Config{}, err
   275  	}
   276  
   277  	if strings.HasPrefix(absSrcDir, absBuildDir) {
   278  		return Config{}, fmt.Errorf("Build dir must not contain source directory")
   279  	}
   280  
   281  	// Load any configurable options from the configuration file
   282  	err = loadConfig(config)
   283  	if err != nil {
   284  		return Config{}, err
   285  	}
   286  
   287  	inMakeFile := filepath.Join(buildDir, ".soong.in_make")
   288  	if _, err := os.Stat(inMakeFile); err == nil {
   289  		config.inMake = true
   290  	}
   291  
   292  	targets, err := decodeTargetProductVariables(config)
   293  	if err != nil {
   294  		return Config{}, err
   295  	}
   296  
   297  	var archConfig []archConfig
   298  	if Bool(config.Mega_device) {
   299  		archConfig = getMegaDeviceConfig()
   300  	} else if Bool(config.Ndk_abis) {
   301  		archConfig = getNdkAbisConfig()
   302  	}
   303  
   304  	if archConfig != nil {
   305  		deviceTargets, err := decodeArchSettings(archConfig)
   306  		if err != nil {
   307  			return Config{}, err
   308  		}
   309  		targets[Device] = deviceTargets
   310  	}
   311  
   312  	config.Targets = targets
   313  	config.BuildOsVariant = targets[Host][0].String()
   314  
   315  	if err := config.fromEnv(); err != nil {
   316  		return Config{}, err
   317  	}
   318  
   319  	return Config{config}, nil
   320  }
   321  
   322  func (c *config) fromEnv() error {
   323  	switch c.Getenv("EXPERIMENTAL_USE_OPENJDK9") {
   324  	case "":
   325  		if c.Getenv("RUN_ERROR_PRONE") != "true" {
   326  			// Use OpenJDK9, but target 1.8
   327  			c.useOpenJDK9 = true
   328  		}
   329  	case "false":
   330  		// Use OpenJDK8
   331  	case "1.8":
   332  		// Use OpenJDK9, but target 1.8
   333  		c.useOpenJDK9 = true
   334  	case "true":
   335  		// Use OpenJDK9 and target 1.9
   336  		c.useOpenJDK9 = true
   337  		c.targetOpenJDK9 = true
   338  	default:
   339  		return fmt.Errorf(`Invalid value for EXPERIMENTAL_USE_OPENJDK9, should be "", "false", "1.8", or "true"`)
   340  	}
   341  
   342  	return nil
   343  }
   344  
   345  func (c *config) StopBefore() bootstrap.StopBefore {
   346  	return c.stopBefore
   347  }
   348  
   349  func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) {
   350  	c.stopBefore = stopBefore
   351  }
   352  
   353  var _ bootstrap.ConfigStopBefore = (*config)(nil)
   354  
   355  func (c *config) BlueprintToolLocation() string {
   356  	return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin")
   357  }
   358  
   359  var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil)
   360  
   361  // HostSystemTool looks for non-hermetic tools from the system we're running on.
   362  // Generally shouldn't be used, but useful to find the XCode SDK, etc.
   363  func (c *config) HostSystemTool(name string) string {
   364  	for _, dir := range filepath.SplitList(c.Getenv("PATH")) {
   365  		path := filepath.Join(dir, name)
   366  		if s, err := os.Stat(path); err != nil {
   367  			continue
   368  		} else if m := s.Mode(); !s.IsDir() && m&0111 != 0 {
   369  			return path
   370  		}
   371  	}
   372  	return name
   373  }
   374  
   375  // PrebuiltOS returns the name of the host OS used in prebuilts directories
   376  func (c *config) PrebuiltOS() string {
   377  	switch runtime.GOOS {
   378  	case "linux":
   379  		return "linux-x86"
   380  	case "darwin":
   381  		return "darwin-x86"
   382  	default:
   383  		panic("Unknown GOOS")
   384  	}
   385  }
   386  
   387  // GoRoot returns the path to the root directory of the Go toolchain.
   388  func (c *config) GoRoot() string {
   389  	return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS())
   390  }
   391  
   392  func (c *config) CpPreserveSymlinksFlags() string {
   393  	switch runtime.GOOS {
   394  	case "darwin":
   395  		return "-R"
   396  	case "linux":
   397  		return "-d"
   398  	default:
   399  		return ""
   400  	}
   401  }
   402  
   403  func (c *config) Getenv(key string) string {
   404  	var val string
   405  	var exists bool
   406  	c.envLock.Lock()
   407  	defer c.envLock.Unlock()
   408  	if c.envDeps == nil {
   409  		c.envDeps = make(map[string]string)
   410  	}
   411  	if val, exists = c.envDeps[key]; !exists {
   412  		if c.envFrozen {
   413  			panic("Cannot access new environment variables after envdeps are frozen")
   414  		}
   415  		val, _ = c.env[key]
   416  		c.envDeps[key] = val
   417  	}
   418  	return val
   419  }
   420  
   421  func (c *config) GetenvWithDefault(key string, defaultValue string) string {
   422  	ret := c.Getenv(key)
   423  	if ret == "" {
   424  		return defaultValue
   425  	}
   426  	return ret
   427  }
   428  
   429  func (c *config) IsEnvTrue(key string) bool {
   430  	value := c.Getenv(key)
   431  	return value == "1" || value == "y" || value == "yes" || value == "on" || value == "true"
   432  }
   433  
   434  func (c *config) IsEnvFalse(key string) bool {
   435  	value := c.Getenv(key)
   436  	return value == "0" || value == "n" || value == "no" || value == "off" || value == "false"
   437  }
   438  
   439  func (c *config) EnvDeps() map[string]string {
   440  	c.envLock.Lock()
   441  	defer c.envLock.Unlock()
   442  	c.envFrozen = true
   443  	return c.envDeps
   444  }
   445  
   446  func (c *config) EmbeddedInMake() bool {
   447  	return c.inMake
   448  }
   449  
   450  func (c *config) BuildId() string {
   451  	return String(c.productVariables.BuildId)
   452  }
   453  
   454  func (c *config) BuildNumberFromFile() string {
   455  	return String(c.productVariables.BuildNumberFromFile)
   456  }
   457  
   458  // DeviceName returns the name of the current device target
   459  // TODO: take an AndroidModuleContext to select the device name for multi-device builds
   460  func (c *config) DeviceName() string {
   461  	return *c.productVariables.DeviceName
   462  }
   463  
   464  func (c *config) ResourceOverlays() []string {
   465  	if c.productVariables.ResourceOverlays == nil {
   466  		return nil
   467  	}
   468  	return *c.productVariables.ResourceOverlays
   469  }
   470  
   471  func (c *config) PlatformVersionName() string {
   472  	return String(c.productVariables.Platform_version_name)
   473  }
   474  
   475  func (c *config) PlatformSdkVersionInt() int {
   476  	return *c.productVariables.Platform_sdk_version
   477  }
   478  
   479  func (c *config) PlatformSdkVersion() string {
   480  	return strconv.Itoa(c.PlatformSdkVersionInt())
   481  }
   482  
   483  func (c *config) PlatformSdkCodename() string {
   484  	return String(c.productVariables.Platform_sdk_codename)
   485  }
   486  
   487  func (c *config) MinSupportedSdkVersion() int {
   488  	return 14
   489  }
   490  
   491  func (c *config) DefaultAppTargetSdkInt() int {
   492  	if Bool(c.productVariables.Platform_sdk_final) {
   493  		return c.PlatformSdkVersionInt()
   494  	} else {
   495  		return FutureApiLevel
   496  	}
   497  }
   498  
   499  func (c *config) DefaultAppTargetSdk() string {
   500  	if Bool(c.productVariables.Platform_sdk_final) {
   501  		return c.PlatformSdkVersion()
   502  	} else {
   503  		return c.PlatformSdkCodename()
   504  	}
   505  }
   506  
   507  func (c *config) AppsDefaultVersionName() string {
   508  	return String(c.productVariables.AppsDefaultVersionName)
   509  }
   510  
   511  // Codenames that are active in the current lunch target.
   512  func (c *config) PlatformVersionActiveCodenames() []string {
   513  	return c.productVariables.Platform_version_active_codenames
   514  }
   515  
   516  // Codenames that are available in the branch but not included in the current
   517  // lunch target.
   518  func (c *config) PlatformVersionFutureCodenames() []string {
   519  	return c.productVariables.Platform_version_future_codenames
   520  }
   521  
   522  // All possible codenames in the current branch. NB: Not named AllCodenames
   523  // because "all" has historically meant "active" in make, and still does in
   524  // build.prop.
   525  func (c *config) PlatformVersionCombinedCodenames() []string {
   526  	combined := []string{}
   527  	combined = append(combined, c.PlatformVersionActiveCodenames()...)
   528  	combined = append(combined, c.PlatformVersionFutureCodenames()...)
   529  	return combined
   530  }
   531  
   532  func (c *config) ProductAAPTConfig() []string {
   533  	return stringSlice(c.productVariables.AAPTConfig)
   534  }
   535  
   536  func (c *config) ProductAAPTPreferredConfig() string {
   537  	return String(c.productVariables.AAPTPreferredConfig)
   538  }
   539  
   540  func (c *config) ProductAAPTCharacteristics() string {
   541  	return String(c.productVariables.AAPTCharacteristics)
   542  }
   543  
   544  func (c *config) ProductAAPTPrebuiltDPI() []string {
   545  	return stringSlice(c.productVariables.AAPTPrebuiltDPI)
   546  }
   547  
   548  func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath {
   549  	defaultCert := String(c.productVariables.DefaultAppCertificate)
   550  	if defaultCert != "" {
   551  		return PathForSource(ctx, filepath.Dir(defaultCert))
   552  	} else {
   553  		return PathForSource(ctx, "build/target/product/security")
   554  	}
   555  }
   556  
   557  func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) {
   558  	defaultCert := String(c.productVariables.DefaultAppCertificate)
   559  	if defaultCert != "" {
   560  		return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8")
   561  	} else {
   562  		defaultDir := c.DefaultAppCertificateDir(ctx)
   563  		return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8")
   564  	}
   565  }
   566  
   567  func (c *config) AllowMissingDependencies() bool {
   568  	return Bool(c.productVariables.Allow_missing_dependencies)
   569  }
   570  
   571  func (c *config) UnbundledBuild() bool {
   572  	return Bool(c.productVariables.Unbundled_build)
   573  }
   574  
   575  func (c *config) IsPdkBuild() bool {
   576  	return Bool(c.productVariables.Pdk)
   577  }
   578  
   579  func (c *config) MinimizeJavaDebugInfo() bool {
   580  	return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng)
   581  }
   582  
   583  func (c *config) DevicePrefer32BitExecutables() bool {
   584  	return Bool(c.productVariables.DevicePrefer32BitExecutables)
   585  }
   586  
   587  func (c *config) SkipDeviceInstall() bool {
   588  	return c.EmbeddedInMake()
   589  }
   590  
   591  func (c *config) SkipMegaDeviceInstall(path string) bool {
   592  	return Bool(c.Mega_device) &&
   593  		strings.HasPrefix(path, filepath.Join(c.buildDir, "target", "product"))
   594  }
   595  
   596  func (c *config) SanitizeHost() []string {
   597  	return append([]string(nil), c.productVariables.SanitizeHost...)
   598  }
   599  
   600  func (c *config) SanitizeDevice() []string {
   601  	return append([]string(nil), c.productVariables.SanitizeDevice...)
   602  }
   603  
   604  func (c *config) SanitizeDeviceDiag() []string {
   605  	return append([]string(nil), c.productVariables.SanitizeDeviceDiag...)
   606  }
   607  
   608  func (c *config) SanitizeDeviceArch() []string {
   609  	return append([]string(nil), c.productVariables.SanitizeDeviceArch...)
   610  }
   611  
   612  func (c *config) EnableCFI() bool {
   613  	if c.productVariables.EnableCFI == nil {
   614  		return true
   615  	} else {
   616  		return *c.productVariables.EnableCFI
   617  	}
   618  }
   619  
   620  func (c *config) Android64() bool {
   621  	for _, t := range c.Targets[Device] {
   622  		if t.Arch.ArchType.Multilib == "lib64" {
   623  			return true
   624  		}
   625  	}
   626  
   627  	return false
   628  }
   629  
   630  func (c *config) UseD8Desugar() bool {
   631  	return !c.IsEnvFalse("USE_D8_DESUGAR")
   632  }
   633  
   634  func (c *config) UseGoma() bool {
   635  	return Bool(c.productVariables.UseGoma)
   636  }
   637  
   638  // Returns true if OpenJDK9 prebuilts are being used
   639  func (c *config) UseOpenJDK9() bool {
   640  	return c.useOpenJDK9
   641  }
   642  
   643  // Returns true if -source 1.9 -target 1.9 is being passed to javac
   644  func (c *config) TargetOpenJDK9() bool {
   645  	return c.targetOpenJDK9
   646  }
   647  
   648  func (c *config) ClangTidy() bool {
   649  	return Bool(c.productVariables.ClangTidy)
   650  }
   651  
   652  func (c *config) TidyChecks() string {
   653  	if c.productVariables.TidyChecks == nil {
   654  		return ""
   655  	}
   656  	return *c.productVariables.TidyChecks
   657  }
   658  
   659  func (c *config) LibartImgHostBaseAddress() string {
   660  	return "0x60000000"
   661  }
   662  
   663  func (c *config) LibartImgDeviceBaseAddress() string {
   664  	archType := Common
   665  	if len(c.Targets[Device]) > 0 {
   666  		archType = c.Targets[Device][0].Arch.ArchType
   667  	}
   668  	switch archType {
   669  	default:
   670  		return "0x70000000"
   671  	case Mips, Mips64:
   672  		return "0x5C000000"
   673  	}
   674  }
   675  
   676  func (c *config) ArtUseReadBarrier() bool {
   677  	return Bool(c.productVariables.ArtUseReadBarrier)
   678  }
   679  
   680  func (c *config) EnforceRROForModule(name string) bool {
   681  	enforceList := c.productVariables.EnforceRROTargets
   682  	if enforceList != nil {
   683  		if len(*enforceList) == 1 && (*enforceList)[0] == "*" {
   684  			return true
   685  		}
   686  		return InList(name, *enforceList)
   687  	}
   688  	return false
   689  }
   690  
   691  func (c *config) EnforceRROExcludedOverlay(path string) bool {
   692  	excluded := c.productVariables.EnforceRROExcludedOverlays
   693  	if excluded != nil {
   694  		for _, exclude := range *excluded {
   695  			if strings.HasPrefix(path, exclude) {
   696  				return true
   697  			}
   698  		}
   699  	}
   700  	return false
   701  }
   702  
   703  func (c *config) ExportedNamespaces() []string {
   704  	return append([]string(nil), c.productVariables.NamespacesToExport...)
   705  }
   706  
   707  func (c *config) HostStaticBinaries() bool {
   708  	return Bool(c.productVariables.HostStaticBinaries)
   709  }
   710  
   711  func (c *deviceConfig) Arches() []Arch {
   712  	var arches []Arch
   713  	for _, target := range c.config.Targets[Device] {
   714  		arches = append(arches, target.Arch)
   715  	}
   716  	return arches
   717  }
   718  
   719  func (c *deviceConfig) BinderBitness() string {
   720  	is32BitBinder := c.config.productVariables.Binder32bit
   721  	if is32BitBinder != nil && *is32BitBinder {
   722  		return "32"
   723  	}
   724  	return "64"
   725  }
   726  
   727  func (c *deviceConfig) VendorPath() string {
   728  	if c.config.productVariables.VendorPath != nil {
   729  		return *c.config.productVariables.VendorPath
   730  	}
   731  	return "vendor"
   732  }
   733  
   734  func (c *deviceConfig) VndkVersion() string {
   735  	return String(c.config.productVariables.DeviceVndkVersion)
   736  }
   737  
   738  func (c *deviceConfig) PlatformVndkVersion() string {
   739  	return String(c.config.productVariables.Platform_vndk_version)
   740  }
   741  
   742  func (c *deviceConfig) ExtraVndkVersions() []string {
   743  	return c.config.productVariables.ExtraVndkVersions
   744  }
   745  
   746  func (c *deviceConfig) SystemSdkVersions() []string {
   747  	if c.config.productVariables.DeviceSystemSdkVersions == nil {
   748  		return nil
   749  	}
   750  	return *c.config.productVariables.DeviceSystemSdkVersions
   751  }
   752  
   753  func (c *deviceConfig) PlatformSystemSdkVersions() []string {
   754  	return c.config.productVariables.Platform_systemsdk_versions
   755  }
   756  
   757  func (c *deviceConfig) OdmPath() string {
   758  	if c.config.productVariables.OdmPath != nil {
   759  		return *c.config.productVariables.OdmPath
   760  	}
   761  	return "odm"
   762  }
   763  
   764  func (c *deviceConfig) ProductPath() string {
   765  	if c.config.productVariables.ProductPath != nil {
   766  		return *c.config.productVariables.ProductPath
   767  	}
   768  	return "product"
   769  }
   770  
   771  func (c *deviceConfig) BtConfigIncludeDir() string {
   772  	return String(c.config.productVariables.BtConfigIncludeDir)
   773  }
   774  
   775  func (c *deviceConfig) DeviceKernelHeaderDirs() []string {
   776  	return c.config.productVariables.DeviceKernelHeaders
   777  }
   778  
   779  func (c *deviceConfig) NativeCoverageEnabled() bool {
   780  	return Bool(c.config.productVariables.NativeCoverage)
   781  }
   782  
   783  func (c *deviceConfig) CoverageEnabledForPath(path string) bool {
   784  	coverage := false
   785  	if c.config.productVariables.CoveragePaths != nil {
   786  		if PrefixInList(path, *c.config.productVariables.CoveragePaths) {
   787  			coverage = true
   788  		}
   789  	}
   790  	if coverage && c.config.productVariables.CoverageExcludePaths != nil {
   791  		if PrefixInList(path, *c.config.productVariables.CoverageExcludePaths) {
   792  			coverage = false
   793  		}
   794  	}
   795  	return coverage
   796  }
   797  
   798  func (c *deviceConfig) PgoAdditionalProfileDirs() []string {
   799  	return c.config.productVariables.PgoAdditionalProfileDirs
   800  }
   801  
   802  func (c *config) IntegerOverflowDisabledForPath(path string) bool {
   803  	if c.productVariables.IntegerOverflowExcludePaths == nil {
   804  		return false
   805  	}
   806  	return PrefixInList(path, *c.productVariables.IntegerOverflowExcludePaths)
   807  }
   808  
   809  func (c *config) CFIDisabledForPath(path string) bool {
   810  	if c.productVariables.CFIExcludePaths == nil {
   811  		return false
   812  	}
   813  	return PrefixInList(path, *c.productVariables.CFIExcludePaths)
   814  }
   815  
   816  func (c *config) CFIEnabledForPath(path string) bool {
   817  	if c.productVariables.CFIIncludePaths == nil {
   818  		return false
   819  	}
   820  	return PrefixInList(path, *c.productVariables.CFIIncludePaths)
   821  }
   822  
   823  func (c *config) VendorConfig(name string) VendorConfig {
   824  	return vendorConfig(c.productVariables.VendorVars[name])
   825  }
   826  
   827  func (c vendorConfig) Bool(name string) bool {
   828  	v := strings.ToLower(c[name])
   829  	return v == "1" || v == "y" || v == "yes" || v == "on" || v == "true"
   830  }
   831  
   832  func (c vendorConfig) String(name string) string {
   833  	return c[name]
   834  }
   835  
   836  func (c vendorConfig) IsSet(name string) bool {
   837  	_, ok := c[name]
   838  	return ok
   839  }
   840  
   841  func stringSlice(s *[]string) []string {
   842  	if s != nil {
   843  		return *s
   844  	} else {
   845  		return nil
   846  	}
   847  }