Home | History | Annotate | Download | only in android
      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 	Host_bionic *bool `json:",omitempty"`
     45 }
     46 
     47 func (f *FileConfigurableOptions) SetDefaultConfig() {
     48 	*f = FileConfigurableOptions{}
     49 }
     50 
     51 // A Config object represents the entire build configuration for Android.
     52 type Config struct {
     53 	*config
     54 }
     55 
     56 func (c Config) BuildDir() string {
     57 	return c.buildDir
     58 }
     59 
     60 // A DeviceConfig object represents the configuration for a particular device being built.  For
     61 // now there will only be one of these, but in the future there may be multiple devices being
     62 // built
     63 type DeviceConfig struct {
     64 	*deviceConfig
     65 }
     66 
     67 type VendorConfig interface {
     68 	// Bool interprets the variable named `name` as a boolean, returning true if, after
     69 	// lowercasing, it matches one of "1", "y", "yes", "on", or "true". Unset, or any other
     70 	// value will return false.
     71 	Bool(name string) bool
     72 
     73 	// String returns the string value of `name`. If the variable was not set, it will
     74 	// return the empty string.
     75 	String(name string) string
     76 
     77 	// IsSet returns whether the variable `name` was set by Make.
     78 	IsSet(name string) bool
     79 }
     80 
     81 type config struct {
     82 	FileConfigurableOptions
     83 	productVariables productVariables
     84 
     85 	// Only available on configs created by TestConfig
     86 	TestProductVariables *productVariables
     87 
     88 	PrimaryBuilder           string
     89 	ConfigFileName           string
     90 	ProductVariablesFileName string
     91 
     92 	Targets              map[OsType][]Target
     93 	BuildOsVariant       string
     94 	BuildOsCommonVariant 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 	targetOpenJDK9 bool // Target 1.9
    112 
    113 	stopBefore bootstrap.StopBefore
    114 
    115 	OncePer
    116 }
    117 
    118 type deviceConfig struct {
    119 	config *config
    120 	OncePer
    121 }
    122 
    123 type vendorConfig map[string]string
    124 
    125 type jsonConfigurable interface {
    126 	SetDefaultConfig()
    127 }
    128 
    129 func loadConfig(config *config) error {
    130 	err := loadFromConfigFile(&config.FileConfigurableOptions, config.ConfigFileName)
    131 	if err != nil {
    132 		return err
    133 	}
    134 
    135 	return loadFromConfigFile(&config.productVariables, config.ProductVariablesFileName)
    136 }
    137 
    138 // loads configuration options from a JSON file in the cwd.
    139 func loadFromConfigFile(configurable jsonConfigurable, filename string) error {
    140 	// Try to open the file
    141 	configFileReader, err := os.Open(filename)
    142 	defer configFileReader.Close()
    143 	if os.IsNotExist(err) {
    144 		// Need to create a file, so that blueprint & ninja don't get in
    145 		// a dependency tracking loop.
    146 		// Make a file-configurable-options with defaults, write it out using
    147 		// a json writer.
    148 		configurable.SetDefaultConfig()
    149 		err = saveToConfigFile(configurable, filename)
    150 		if err != nil {
    151 			return err
    152 		}
    153 	} else if err != nil {
    154 		return fmt.Errorf("config file: could not open %s: %s", filename, err.Error())
    155 	} else {
    156 		// Make a decoder for it
    157 		jsonDecoder := json.NewDecoder(configFileReader)
    158 		err = jsonDecoder.Decode(configurable)
    159 		if err != nil {
    160 			return fmt.Errorf("config file: %s did not parse correctly: %s", filename, err.Error())
    161 		}
    162 	}
    163 
    164 	// No error
    165 	return nil
    166 }
    167 
    168 // atomically writes the config file in case two copies of soong_build are running simultaneously
    169 // (for example, docs generation and ninja manifest generation)
    170 func saveToConfigFile(config jsonConfigurable, filename string) error {
    171 	data, err := json.MarshalIndent(&config, "", "    ")
    172 	if err != nil {
    173 		return fmt.Errorf("cannot marshal config data: %s", err.Error())
    174 	}
    175 
    176 	f, err := ioutil.TempFile(filepath.Dir(filename), "config")
    177 	if err != nil {
    178 		return fmt.Errorf("cannot create empty config file %s: %s\n", filename, err.Error())
    179 	}
    180 	defer os.Remove(f.Name())
    181 	defer f.Close()
    182 
    183 	_, err = f.Write(data)
    184 	if err != nil {
    185 		return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error())
    186 	}
    187 
    188 	_, err = f.WriteString("\n")
    189 	if err != nil {
    190 		return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error())
    191 	}
    192 
    193 	f.Close()
    194 	os.Rename(f.Name(), filename)
    195 
    196 	return nil
    197 }
    198 
    199 // TestConfig returns a Config object suitable for using for tests
    200 func TestConfig(buildDir string, env map[string]string) Config {
    201 	config := &config{
    202 		productVariables: productVariables{
    203 			DeviceName:                  stringPtr("test_device"),
    204 			Platform_sdk_version:        intPtr(26),
    205 			DeviceSystemSdkVersions:     []string{"14", "15"},
    206 			Platform_systemsdk_versions: []string{"25", "26"},
    207 			AAPTConfig:                  []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
    208 			AAPTPreferredConfig:         stringPtr("xhdpi"),
    209 			AAPTCharacteristics:         stringPtr("nosdcard"),
    210 			AAPTPrebuiltDPI:             []string{"xhdpi", "xxhdpi"},
    211 			UncompressPrivAppDex:        boolPtr(true),
    212 		},
    213 
    214 		buildDir:     buildDir,
    215 		captureBuild: true,
    216 		env:          env,
    217 	}
    218 	config.deviceConfig = &deviceConfig{
    219 		config: config,
    220 	}
    221 	config.TestProductVariables = &config.productVariables
    222 
    223 	if err := config.fromEnv(); err != nil {
    224 		panic(err)
    225 	}
    226 
    227 	return Config{config}
    228 }
    229 
    230 func TestArchConfigFuchsia(buildDir string, env map[string]string) Config {
    231 	testConfig := TestConfig(buildDir, env)
    232 	config := testConfig.config
    233 
    234 	config.Targets = map[OsType][]Target{
    235 		Fuchsia: []Target{
    236 			{Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Native: true}},
    237 		},
    238 		BuildOs: []Target{
    239 			{BuildOs, Arch{ArchType: X86_64}},
    240 		},
    241 	}
    242 
    243 	return testConfig
    244 }
    245 
    246 // TestConfig returns a Config object suitable for using for tests that need to run the arch mutator
    247 func TestArchConfig(buildDir string, env map[string]string) Config {
    248 	testConfig := TestConfig(buildDir, env)
    249 	config := testConfig.config
    250 
    251 	config.Targets = map[OsType][]Target{
    252 		Android: []Target{
    253 			{Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}},
    254 			{Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}},
    255 		},
    256 		BuildOs: []Target{
    257 			{BuildOs, Arch{ArchType: X86_64}},
    258 			{BuildOs, Arch{ArchType: X86}},
    259 		},
    260 	}
    261 
    262 	config.BuildOsVariant = config.Targets[BuildOs][0].String()
    263 	config.BuildOsCommonVariant = getCommonTargets(config.Targets[BuildOs])[0].String()
    264 
    265 	return testConfig
    266 }
    267 
    268 // New creates a new Config object.  The srcDir argument specifies the path to
    269 // the root source directory. It also loads the config file, if found.
    270 func NewConfig(srcDir, buildDir string) (Config, error) {
    271 	// Make a config with default options
    272 	config := &config{
    273 		ConfigFileName:           filepath.Join(buildDir, configFileName),
    274 		ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName),
    275 
    276 		env: originalEnv,
    277 
    278 		srcDir:   srcDir,
    279 		buildDir: buildDir,
    280 	}
    281 
    282 	config.deviceConfig = &deviceConfig{
    283 		config: config,
    284 	}
    285 
    286 	// Sanity check the build and source directories. This won't catch strange
    287 	// configurations with symlinks, but at least checks the obvious cases.
    288 	absBuildDir, err := filepath.Abs(buildDir)
    289 	if err != nil {
    290 		return Config{}, err
    291 	}
    292 
    293 	absSrcDir, err := filepath.Abs(srcDir)
    294 	if err != nil {
    295 		return Config{}, err
    296 	}
    297 
    298 	if strings.HasPrefix(absSrcDir, absBuildDir) {
    299 		return Config{}, fmt.Errorf("Build dir must not contain source directory")
    300 	}
    301 
    302 	// Load any configurable options from the configuration file
    303 	err = loadConfig(config)
    304 	if err != nil {
    305 		return Config{}, err
    306 	}
    307 
    308 	inMakeFile := filepath.Join(buildDir, ".soong.in_make")
    309 	if _, err := os.Stat(inMakeFile); err == nil {
    310 		config.inMake = true
    311 	}
    312 
    313 	targets, err := decodeTargetProductVariables(config)
    314 	if err != nil {
    315 		return Config{}, err
    316 	}
    317 
    318 	var archConfig []archConfig
    319 	if Bool(config.Mega_device) {
    320 		archConfig = getMegaDeviceConfig()
    321 	} else if config.NdkAbis() {
    322 		archConfig = getNdkAbisConfig()
    323 	}
    324 
    325 	if archConfig != nil {
    326 		androidTargets, err := decodeArchSettings(Android, archConfig)
    327 		if err != nil {
    328 			return Config{}, err
    329 		}
    330 		targets[Android] = androidTargets
    331 	}
    332 
    333 	config.Targets = targets
    334 	config.BuildOsVariant = targets[BuildOs][0].String()
    335 	config.BuildOsCommonVariant = getCommonTargets(targets[BuildOs])[0].String()
    336 
    337 	if err := config.fromEnv(); err != nil {
    338 		return Config{}, err
    339 	}
    340 
    341 	return Config{config}, nil
    342 }
    343 
    344 func (c *config) fromEnv() error {
    345 	switch c.Getenv("EXPERIMENTAL_USE_OPENJDK9") {
    346 	case "", "1.8":
    347 		// Nothing, we always use OpenJDK9
    348 	case "true":
    349 		// Use OpenJDK9 and target 1.9
    350 		c.targetOpenJDK9 = true
    351 	default:
    352 		return fmt.Errorf(`Invalid value for EXPERIMENTAL_USE_OPENJDK9, should be "", "1.8", or "true"`)
    353 	}
    354 
    355 	return nil
    356 }
    357 
    358 func (c *config) StopBefore() bootstrap.StopBefore {
    359 	return c.stopBefore
    360 }
    361 
    362 func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) {
    363 	c.stopBefore = stopBefore
    364 }
    365 
    366 var _ bootstrap.ConfigStopBefore = (*config)(nil)
    367 
    368 func (c *config) BlueprintToolLocation() string {
    369 	return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin")
    370 }
    371 
    372 var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil)
    373 
    374 func (c *config) HostToolPath(ctx PathContext, tool string) Path {
    375 	return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool)
    376 }
    377 
    378 // HostSystemTool looks for non-hermetic tools from the system we're running on.
    379 // Generally shouldn't be used, but useful to find the XCode SDK, etc.
    380 func (c *config) HostSystemTool(name string) string {
    381 	for _, dir := range filepath.SplitList(c.Getenv("PATH")) {
    382 		path := filepath.Join(dir, name)
    383 		if s, err := os.Stat(path); err != nil {
    384 			continue
    385 		} else if m := s.Mode(); !s.IsDir() && m&0111 != 0 {
    386 			return path
    387 		}
    388 	}
    389 	return name
    390 }
    391 
    392 // PrebuiltOS returns the name of the host OS used in prebuilts directories
    393 func (c *config) PrebuiltOS() string {
    394 	switch runtime.GOOS {
    395 	case "linux":
    396 		return "linux-x86"
    397 	case "darwin":
    398 		return "darwin-x86"
    399 	default:
    400 		panic("Unknown GOOS")
    401 	}
    402 }
    403 
    404 // GoRoot returns the path to the root directory of the Go toolchain.
    405 func (c *config) GoRoot() string {
    406 	return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS())
    407 }
    408 
    409 func (c *config) CpPreserveSymlinksFlags() string {
    410 	switch runtime.GOOS {
    411 	case "darwin":
    412 		return "-R"
    413 	case "linux":
    414 		return "-d"
    415 	default:
    416 		return ""
    417 	}
    418 }
    419 
    420 func (c *config) Getenv(key string) string {
    421 	var val string
    422 	var exists bool
    423 	c.envLock.Lock()
    424 	defer c.envLock.Unlock()
    425 	if c.envDeps == nil {
    426 		c.envDeps = make(map[string]string)
    427 	}
    428 	if val, exists = c.envDeps[key]; !exists {
    429 		if c.envFrozen {
    430 			panic("Cannot access new environment variables after envdeps are frozen")
    431 		}
    432 		val, _ = c.env[key]
    433 		c.envDeps[key] = val
    434 	}
    435 	return val
    436 }
    437 
    438 func (c *config) GetenvWithDefault(key string, defaultValue string) string {
    439 	ret := c.Getenv(key)
    440 	if ret == "" {
    441 		return defaultValue
    442 	}
    443 	return ret
    444 }
    445 
    446 func (c *config) IsEnvTrue(key string) bool {
    447 	value := c.Getenv(key)
    448 	return value == "1" || value == "y" || value == "yes" || value == "on" || value == "true"
    449 }
    450 
    451 func (c *config) IsEnvFalse(key string) bool {
    452 	value := c.Getenv(key)
    453 	return value == "0" || value == "n" || value == "no" || value == "off" || value == "false"
    454 }
    455 
    456 func (c *config) EnvDeps() map[string]string {
    457 	c.envLock.Lock()
    458 	defer c.envLock.Unlock()
    459 	c.envFrozen = true
    460 	return c.envDeps
    461 }
    462 
    463 func (c *config) EmbeddedInMake() bool {
    464 	return c.inMake
    465 }
    466 
    467 func (c *config) BuildId() string {
    468 	return String(c.productVariables.BuildId)
    469 }
    470 
    471 func (c *config) BuildNumberFromFile() string {
    472 	return String(c.productVariables.BuildNumberFromFile)
    473 }
    474 
    475 // DeviceName returns the name of the current device target
    476 // TODO: take an AndroidModuleContext to select the device name for multi-device builds
    477 func (c *config) DeviceName() string {
    478 	return *c.productVariables.DeviceName
    479 }
    480 
    481 func (c *config) DeviceResourceOverlays() []string {
    482 	return c.productVariables.DeviceResourceOverlays
    483 }
    484 
    485 func (c *config) ProductResourceOverlays() []string {
    486 	return c.productVariables.ProductResourceOverlays
    487 }
    488 
    489 func (c *config) PlatformVersionName() string {
    490 	return String(c.productVariables.Platform_version_name)
    491 }
    492 
    493 func (c *config) PlatformSdkVersionInt() int {
    494 	return *c.productVariables.Platform_sdk_version
    495 }
    496 
    497 func (c *config) PlatformSdkVersion() string {
    498 	return strconv.Itoa(c.PlatformSdkVersionInt())
    499 }
    500 
    501 func (c *config) PlatformSdkCodename() string {
    502 	return String(c.productVariables.Platform_sdk_codename)
    503 }
    504 
    505 func (c *config) PlatformSecurityPatch() string {
    506 	return String(c.productVariables.Platform_security_patch)
    507 }
    508 
    509 func (c *config) PlatformPreviewSdkVersion() string {
    510 	return String(c.productVariables.Platform_preview_sdk_version)
    511 }
    512 
    513 func (c *config) PlatformMinSupportedTargetSdkVersion() string {
    514 	return String(c.productVariables.Platform_min_supported_target_sdk_version)
    515 }
    516 
    517 func (c *config) PlatformBaseOS() string {
    518 	return String(c.productVariables.Platform_base_os)
    519 }
    520 
    521 func (c *config) MinSupportedSdkVersion() int {
    522 	return 16
    523 }
    524 
    525 func (c *config) DefaultAppTargetSdkInt() int {
    526 	if Bool(c.productVariables.Platform_sdk_final) {
    527 		return c.PlatformSdkVersionInt()
    528 	} else {
    529 		return FutureApiLevel
    530 	}
    531 }
    532 
    533 func (c *config) DefaultAppTargetSdk() string {
    534 	if Bool(c.productVariables.Platform_sdk_final) {
    535 		return c.PlatformSdkVersion()
    536 	} else {
    537 		return c.PlatformSdkCodename()
    538 	}
    539 }
    540 
    541 func (c *config) AppsDefaultVersionName() string {
    542 	return String(c.productVariables.AppsDefaultVersionName)
    543 }
    544 
    545 // Codenames that are active in the current lunch target.
    546 func (c *config) PlatformVersionActiveCodenames() []string {
    547 	return c.productVariables.Platform_version_active_codenames
    548 }
    549 
    550 // Codenames that are available in the branch but not included in the current
    551 // lunch target.
    552 func (c *config) PlatformVersionFutureCodenames() []string {
    553 	return c.productVariables.Platform_version_future_codenames
    554 }
    555 
    556 // All possible codenames in the current branch. NB: Not named AllCodenames
    557 // because "all" has historically meant "active" in make, and still does in
    558 // build.prop.
    559 func (c *config) PlatformVersionCombinedCodenames() []string {
    560 	combined := []string{}
    561 	combined = append(combined, c.PlatformVersionActiveCodenames()...)
    562 	combined = append(combined, c.PlatformVersionFutureCodenames()...)
    563 	return combined
    564 }
    565 
    566 func (c *config) ProductAAPTConfig() []string {
    567 	return c.productVariables.AAPTConfig
    568 }
    569 
    570 func (c *config) ProductAAPTPreferredConfig() string {
    571 	return String(c.productVariables.AAPTPreferredConfig)
    572 }
    573 
    574 func (c *config) ProductAAPTCharacteristics() string {
    575 	return String(c.productVariables.AAPTCharacteristics)
    576 }
    577 
    578 func (c *config) ProductAAPTPrebuiltDPI() []string {
    579 	return c.productVariables.AAPTPrebuiltDPI
    580 }
    581 
    582 func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath {
    583 	defaultCert := String(c.productVariables.DefaultAppCertificate)
    584 	if defaultCert != "" {
    585 		return PathForSource(ctx, filepath.Dir(defaultCert))
    586 	} else {
    587 		return PathForSource(ctx, "build/target/product/security")
    588 	}
    589 }
    590 
    591 func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) {
    592 	defaultCert := String(c.productVariables.DefaultAppCertificate)
    593 	if defaultCert != "" {
    594 		return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8")
    595 	} else {
    596 		defaultDir := c.DefaultAppCertificateDir(ctx)
    597 		return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8")
    598 	}
    599 }
    600 
    601 func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath {
    602 	// TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE
    603 	defaultCert := String(c.productVariables.DefaultAppCertificate)
    604 	if defaultCert == "" || filepath.Dir(defaultCert) == "build/target/product/security" {
    605 		// When defaultCert is unset or is set to the testkeys path, use the APEX keys
    606 		// that is under the module dir
    607 		return pathForModuleSrc(ctx)
    608 	} else {
    609 		// If not, APEX keys are under the specified directory
    610 		return PathForSource(ctx, filepath.Dir(defaultCert))
    611 	}
    612 }
    613 
    614 func (c *config) AllowMissingDependencies() bool {
    615 	return Bool(c.productVariables.Allow_missing_dependencies)
    616 }
    617 
    618 func (c *config) UnbundledBuild() bool {
    619 	return Bool(c.productVariables.Unbundled_build)
    620 }
    621 
    622 func (c *config) UnbundledBuildUsePrebuiltSdks() bool {
    623 	return Bool(c.productVariables.Unbundled_build) && !Bool(c.productVariables.Unbundled_build_sdks_from_source)
    624 }
    625 
    626 func (c *config) Fuchsia() bool {
    627 	return Bool(c.productVariables.Fuchsia)
    628 }
    629 
    630 func (c *config) IsPdkBuild() bool {
    631 	return Bool(c.productVariables.Pdk)
    632 }
    633 
    634 func (c *config) MinimizeJavaDebugInfo() bool {
    635 	return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng)
    636 }
    637 
    638 func (c *config) Debuggable() bool {
    639 	return Bool(c.productVariables.Debuggable)
    640 }
    641 
    642 func (c *config) Eng() bool {
    643 	return Bool(c.productVariables.Eng)
    644 }
    645 
    646 func (c *config) DevicePrefer32BitApps() bool {
    647 	return Bool(c.productVariables.DevicePrefer32BitApps)
    648 }
    649 
    650 func (c *config) DevicePrefer32BitExecutables() bool {
    651 	return Bool(c.productVariables.DevicePrefer32BitExecutables)
    652 }
    653 
    654 func (c *config) DevicePrimaryArchType() ArchType {
    655 	return c.Targets[Android][0].Arch.ArchType
    656 }
    657 
    658 func (c *config) SkipDeviceInstall() bool {
    659 	return c.EmbeddedInMake()
    660 }
    661 
    662 func (c *config) SkipMegaDeviceInstall(path string) bool {
    663 	return Bool(c.Mega_device) &&
    664 		strings.HasPrefix(path, filepath.Join(c.buildDir, "target", "product"))
    665 }
    666 
    667 func (c *config) SanitizeHost() []string {
    668 	return append([]string(nil), c.productVariables.SanitizeHost...)
    669 }
    670 
    671 func (c *config) SanitizeDevice() []string {
    672 	return append([]string(nil), c.productVariables.SanitizeDevice...)
    673 }
    674 
    675 func (c *config) SanitizeDeviceDiag() []string {
    676 	return append([]string(nil), c.productVariables.SanitizeDeviceDiag...)
    677 }
    678 
    679 func (c *config) SanitizeDeviceArch() []string {
    680 	return append([]string(nil), c.productVariables.SanitizeDeviceArch...)
    681 }
    682 
    683 func (c *config) EnableCFI() bool {
    684 	if c.productVariables.EnableCFI == nil {
    685 		return true
    686 	} else {
    687 		return *c.productVariables.EnableCFI
    688 	}
    689 }
    690 
    691 func (c *config) DisableScudo() bool {
    692 	return Bool(c.productVariables.DisableScudo)
    693 }
    694 
    695 func (c *config) EnableXOM() bool {
    696 	if c.productVariables.EnableXOM == nil {
    697 		return true
    698 	} else {
    699 		return Bool(c.productVariables.EnableXOM)
    700 	}
    701 }
    702 
    703 func (c *config) Android64() bool {
    704 	for _, t := range c.Targets[Android] {
    705 		if t.Arch.ArchType.Multilib == "lib64" {
    706 			return true
    707 		}
    708 	}
    709 
    710 	return false
    711 }
    712 
    713 func (c *config) UseGoma() bool {
    714 	return Bool(c.productVariables.UseGoma)
    715 }
    716 
    717 func (c *config) RunErrorProne() bool {
    718 	return c.IsEnvTrue("RUN_ERROR_PRONE")
    719 }
    720 
    721 // Returns true if -source 1.9 -target 1.9 is being passed to javac
    722 func (c *config) TargetOpenJDK9() bool {
    723 	return c.targetOpenJDK9
    724 }
    725 
    726 func (c *config) ClangTidy() bool {
    727 	return Bool(c.productVariables.ClangTidy)
    728 }
    729 
    730 func (c *config) TidyChecks() string {
    731 	if c.productVariables.TidyChecks == nil {
    732 		return ""
    733 	}
    734 	return *c.productVariables.TidyChecks
    735 }
    736 
    737 func (c *config) LibartImgHostBaseAddress() string {
    738 	return "0x60000000"
    739 }
    740 
    741 func (c *config) LibartImgDeviceBaseAddress() string {
    742 	archType := Common
    743 	if len(c.Targets[Android]) > 0 {
    744 		archType = c.Targets[Android][0].Arch.ArchType
    745 	}
    746 	switch archType {
    747 	default:
    748 		return "0x70000000"
    749 	case Mips, Mips64:
    750 		return "0x5C000000"
    751 	}
    752 }
    753 
    754 func (c *config) ArtUseReadBarrier() bool {
    755 	return Bool(c.productVariables.ArtUseReadBarrier)
    756 }
    757 
    758 func (c *config) EnforceRROForModule(name string) bool {
    759 	enforceList := c.productVariables.EnforceRROTargets
    760 	if enforceList != nil {
    761 		if len(enforceList) == 1 && (enforceList)[0] == "*" {
    762 			return true
    763 		}
    764 		return InList(name, enforceList)
    765 	}
    766 	return false
    767 }
    768 
    769 func (c *config) EnforceRROExcludedOverlay(path string) bool {
    770 	excluded := c.productVariables.EnforceRROExcludedOverlays
    771 	if excluded != nil {
    772 		for _, exclude := range excluded {
    773 			if strings.HasPrefix(path, exclude) {
    774 				return true
    775 			}
    776 		}
    777 	}
    778 	return false
    779 }
    780 
    781 func (c *config) ExportedNamespaces() []string {
    782 	return append([]string(nil), c.productVariables.NamespacesToExport...)
    783 }
    784 
    785 func (c *config) HostStaticBinaries() bool {
    786 	return Bool(c.productVariables.HostStaticBinaries)
    787 }
    788 
    789 func (c *config) UncompressPrivAppDex() bool {
    790 	return Bool(c.productVariables.UncompressPrivAppDex)
    791 }
    792 
    793 func (c *config) ModulesLoadedByPrivilegedModules() []string {
    794 	return c.productVariables.ModulesLoadedByPrivilegedModules
    795 }
    796 
    797 func (c *config) BootJars() []string {
    798 	return c.productVariables.BootJars
    799 }
    800 
    801 func (c *config) DexpreoptGlobalConfig() string {
    802 	return String(c.productVariables.DexpreoptGlobalConfig)
    803 }
    804 
    805 func (c *config) FrameworksBaseDirExists(ctx PathContext) bool {
    806 	return ExistentPathForSource(ctx, "frameworks", "base").Valid()
    807 }
    808 
    809 func (c *deviceConfig) Arches() []Arch {
    810 	var arches []Arch
    811 	for _, target := range c.config.Targets[Android] {
    812 		arches = append(arches, target.Arch)
    813 	}
    814 	return arches
    815 }
    816 
    817 func (c *deviceConfig) BinderBitness() string {
    818 	is32BitBinder := c.config.productVariables.Binder32bit
    819 	if is32BitBinder != nil && *is32BitBinder {
    820 		return "32"
    821 	}
    822 	return "64"
    823 }
    824 
    825 func (c *deviceConfig) VendorPath() string {
    826 	if c.config.productVariables.VendorPath != nil {
    827 		return *c.config.productVariables.VendorPath
    828 	}
    829 	return "vendor"
    830 }
    831 
    832 func (c *deviceConfig) VndkVersion() string {
    833 	return String(c.config.productVariables.DeviceVndkVersion)
    834 }
    835 
    836 func (c *deviceConfig) PlatformVndkVersion() string {
    837 	return String(c.config.productVariables.Platform_vndk_version)
    838 }
    839 
    840 func (c *deviceConfig) ExtraVndkVersions() []string {
    841 	return c.config.productVariables.ExtraVndkVersions
    842 }
    843 
    844 func (c *deviceConfig) VndkUseCoreVariant() bool {
    845 	return Bool(c.config.productVariables.VndkUseCoreVariant)
    846 }
    847 
    848 func (c *deviceConfig) SystemSdkVersions() []string {
    849 	return c.config.productVariables.DeviceSystemSdkVersions
    850 }
    851 
    852 func (c *deviceConfig) PlatformSystemSdkVersions() []string {
    853 	return c.config.productVariables.Platform_systemsdk_versions
    854 }
    855 
    856 func (c *deviceConfig) OdmPath() string {
    857 	if c.config.productVariables.OdmPath != nil {
    858 		return *c.config.productVariables.OdmPath
    859 	}
    860 	return "odm"
    861 }
    862 
    863 func (c *deviceConfig) ProductPath() string {
    864 	if c.config.productVariables.ProductPath != nil {
    865 		return *c.config.productVariables.ProductPath
    866 	}
    867 	return "product"
    868 }
    869 
    870 func (c *deviceConfig) ProductServicesPath() string {
    871 	if c.config.productVariables.ProductServicesPath != nil {
    872 		return *c.config.productVariables.ProductServicesPath
    873 	}
    874 	return "product_services"
    875 }
    876 
    877 func (c *deviceConfig) BtConfigIncludeDir() string {
    878 	return String(c.config.productVariables.BtConfigIncludeDir)
    879 }
    880 
    881 func (c *deviceConfig) DeviceKernelHeaderDirs() []string {
    882 	return c.config.productVariables.DeviceKernelHeaders
    883 }
    884 
    885 func (c *deviceConfig) NativeCoverageEnabled() bool {
    886 	return Bool(c.config.productVariables.NativeCoverage)
    887 }
    888 
    889 func (c *deviceConfig) CoverageEnabledForPath(path string) bool {
    890 	coverage := false
    891 	if c.config.productVariables.CoveragePaths != nil {
    892 		if InList("*", c.config.productVariables.CoveragePaths) || PrefixInList(path, c.config.productVariables.CoveragePaths) {
    893 			coverage = true
    894 		}
    895 	}
    896 	if coverage && c.config.productVariables.CoverageExcludePaths != nil {
    897 		if PrefixInList(path, c.config.productVariables.CoverageExcludePaths) {
    898 			coverage = false
    899 		}
    900 	}
    901 	return coverage
    902 }
    903 
    904 func (c *deviceConfig) PgoAdditionalProfileDirs() []string {
    905 	return c.config.productVariables.PgoAdditionalProfileDirs
    906 }
    907 
    908 func (c *deviceConfig) VendorSepolicyDirs() []string {
    909 	return c.config.productVariables.BoardVendorSepolicyDirs
    910 }
    911 
    912 func (c *deviceConfig) OdmSepolicyDirs() []string {
    913 	return c.config.productVariables.BoardOdmSepolicyDirs
    914 }
    915 
    916 func (c *deviceConfig) PlatPublicSepolicyDirs() []string {
    917 	return c.config.productVariables.BoardPlatPublicSepolicyDirs
    918 }
    919 
    920 func (c *deviceConfig) PlatPrivateSepolicyDirs() []string {
    921 	return c.config.productVariables.BoardPlatPrivateSepolicyDirs
    922 }
    923 
    924 func (c *deviceConfig) OverrideManifestPackageNameFor(name string) (manifestName string, overridden bool) {
    925 	return findOverrideValue(c.config.productVariables.ManifestPackageNameOverrides, name,
    926 		"invalid override rule %q in PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES should be <module_name>:<manifest_name>")
    927 }
    928 
    929 func (c *deviceConfig) OverrideCertificateFor(name string) (certificatePath string, overridden bool) {
    930 	return findOverrideValue(c.config.productVariables.CertificateOverrides, name,
    931 		"invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>")
    932 }
    933 
    934 func (c *deviceConfig) OverridePackageNameFor(name string) string {
    935 	newName, overridden := findOverrideValue(
    936 		c.config.productVariables.PackageNameOverrides,
    937 		name,
    938 		"invalid override rule %q in PRODUCT_PACKAGE_NAME_OVERRIDES should be <module_name>:<package_name>")
    939 	if overridden {
    940 		return newName
    941 	}
    942 	return name
    943 }
    944 
    945 func findOverrideValue(overrides []string, name string, errorMsg string) (newValue string, overridden bool) {
    946 	if overrides == nil || len(overrides) == 0 {
    947 		return "", false
    948 	}
    949 	for _, o := range overrides {
    950 		split := strings.Split(o, ":")
    951 		if len(split) != 2 {
    952 			// This shouldn't happen as this is first checked in make, but just in case.
    953 			panic(fmt.Errorf(errorMsg, o))
    954 		}
    955 		if matchPattern(split[0], name) {
    956 			return substPattern(split[0], split[1], name), true
    957 		}
    958 	}
    959 	return "", false
    960 }
    961 
    962 // SecondArchIsTranslated returns true if the primary device arch is X86 or X86_64 and the device also has an arch
    963 // that is Arm or Arm64.
    964 func (c *config) SecondArchIsTranslated() bool {
    965 	deviceTargets := c.Targets[Android]
    966 	if len(deviceTargets) < 2 {
    967 		return false
    968 	}
    969 
    970 	arch := deviceTargets[0].Arch
    971 
    972 	return (arch.ArchType == X86 || arch.ArchType == X86_64) && hasArmAndroidArch(deviceTargets)
    973 }
    974 
    975 func (c *config) IntegerOverflowDisabledForPath(path string) bool {
    976 	if c.productVariables.IntegerOverflowExcludePaths == nil {
    977 		return false
    978 	}
    979 	return PrefixInList(path, c.productVariables.IntegerOverflowExcludePaths)
    980 }
    981 
    982 func (c *config) CFIDisabledForPath(path string) bool {
    983 	if c.productVariables.CFIExcludePaths == nil {
    984 		return false
    985 	}
    986 	return PrefixInList(path, c.productVariables.CFIExcludePaths)
    987 }
    988 
    989 func (c *config) CFIEnabledForPath(path string) bool {
    990 	if c.productVariables.CFIIncludePaths == nil {
    991 		return false
    992 	}
    993 	return PrefixInList(path, c.productVariables.CFIIncludePaths)
    994 }
    995 
    996 func (c *config) XOMDisabledForPath(path string) bool {
    997 	if c.productVariables.XOMExcludePaths == nil {
    998 		return false
    999 	}
   1000 	return PrefixInList(path, c.productVariables.XOMExcludePaths)
   1001 }
   1002 
   1003 func (c *config) VendorConfig(name string) VendorConfig {
   1004 	return vendorConfig(c.productVariables.VendorVars[name])
   1005 }
   1006 
   1007 func (c vendorConfig) Bool(name string) bool {
   1008 	v := strings.ToLower(c[name])
   1009 	return v == "1" || v == "y" || v == "yes" || v == "on" || v == "true"
   1010 }
   1011 
   1012 func (c vendorConfig) String(name string) string {
   1013 	return c[name]
   1014 }
   1015 
   1016 func (c vendorConfig) IsSet(name string) bool {
   1017 	_, ok := c[name]
   1018 	return ok
   1019 }
   1020 
   1021 func (c *config) NdkAbis() bool {
   1022 	return Bool(c.productVariables.Ndk_abis)
   1023 }
   1024 
   1025 func (c *config) ExcludeDraftNdkApis() bool {
   1026 	return Bool(c.productVariables.Exclude_draft_ndk_apis)
   1027 }
   1028 
   1029 func (c *config) FlattenApex() bool {
   1030 	return Bool(c.productVariables.FlattenApex)
   1031 }
   1032 
   1033 func (c *config) EnforceSystemCertificate() bool {
   1034 	return Bool(c.productVariables.EnforceSystemCertificate)
   1035 }
   1036 
   1037 func (c *config) EnforceSystemCertificateWhitelist() []string {
   1038 	return c.productVariables.EnforceSystemCertificateWhitelist
   1039 }
   1040 
   1041 func (c *config) ProductHiddenAPIStubs() []string {
   1042 	return c.productVariables.ProductHiddenAPIStubs
   1043 }
   1044 
   1045 func (c *config) ProductHiddenAPIStubsSystem() []string {
   1046 	return c.productVariables.ProductHiddenAPIStubsSystem
   1047 }
   1048 
   1049 func (c *config) ProductHiddenAPIStubsTest() []string {
   1050 	return c.productVariables.ProductHiddenAPIStubsTest
   1051 }
   1052 
   1053 func (c *deviceConfig) TargetFSConfigGen() []string {
   1054 	return c.config.productVariables.TargetFSConfigGen
   1055 }
   1056