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 }