diff --git a/android/bazel_handler.go b/android/bazel_handler.go index 63145bff8..a1206dc53 100644 --- a/android/bazel_handler.go +++ b/android/bazel_handler.go @@ -567,7 +567,7 @@ func (p *bazelPaths) intermediatesDir() string { // Returns the path where the contents of the @soong_injection repository live. // It is used by Soong to tell Bazel things it cannot over the command line. func (p *bazelPaths) injectedFilesDir() string { - return filepath.Join(p.buildDir, "soong_injection") + return filepath.Join(p.buildDir, bazel.SoongInjectionDirName) } // Returns the path of the synthetic Bazel workspace that contains a symlink diff --git a/android/config.go b/android/config.go index 79917adf4..4847182d5 100644 --- a/android/config.go +++ b/android/config.go @@ -35,6 +35,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android/soongconfig" + "android/soong/bazel" "android/soong/remoteexec" ) @@ -169,7 +170,7 @@ func loadConfig(config *config) error { // loadFromConfigFile loads and decodes configuration options from a JSON file // in the current working directory. -func loadFromConfigFile(configurable jsonConfigurable, filename string) error { +func loadFromConfigFile(configurable *productVariables, filename string) error { // Try to open the file configFileReader, err := os.Open(filename) defer configFileReader.Close() @@ -194,13 +195,20 @@ func loadFromConfigFile(configurable jsonConfigurable, filename string) error { } } - // No error - return nil + if Bool(configurable.GcovCoverage) && Bool(configurable.ClangCoverage) { + return fmt.Errorf("GcovCoverage and ClangCoverage cannot both be set") + } + + configurable.Native_coverage = proptools.BoolPtr( + Bool(configurable.GcovCoverage) || + Bool(configurable.ClangCoverage)) + + return saveToBazelConfigFile(configurable, filepath.Dir(filename)) } // atomically writes the config file in case two copies of soong_build are running simultaneously // (for example, docs generation and ninja manifest generation) -func saveToConfigFile(config jsonConfigurable, filename string) error { +func saveToConfigFile(config *productVariables, filename string) error { data, err := json.MarshalIndent(&config, "", " ") if err != nil { return fmt.Errorf("cannot marshal config data: %s", err.Error()) @@ -229,6 +237,35 @@ func saveToConfigFile(config jsonConfigurable, filename string) error { return nil } +func saveToBazelConfigFile(config *productVariables, outDir string) error { + dir := filepath.Join(outDir, bazel.SoongInjectionDirName, "product_config") + err := createDirIfNonexistent(dir, os.ModePerm) + if err != nil { + return fmt.Errorf("Could not create dir %s: %s", dir, err) + } + + data, err := json.MarshalIndent(&config, "", " ") + if err != nil { + return fmt.Errorf("cannot marshal config data: %s", err.Error()) + } + + bzl := []string{ + bazel.GeneratedBazelFileWarning, + fmt.Sprintf(`_product_vars = json.decode("""%s""")`, data), + "product_vars = _product_vars\n", + } + err = ioutil.WriteFile(filepath.Join(dir, "product_variables.bzl"), []byte(strings.Join(bzl, "\n")), 0644) + if err != nil { + return fmt.Errorf("Could not write .bzl config file %s", err) + } + err = ioutil.WriteFile(filepath.Join(dir, "BUILD"), []byte(bazel.GeneratedBazelFileWarning), 0644) + if err != nil { + return fmt.Errorf("Could not write BUILD config file %s", err) + } + + return nil +} + // NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that // use the android package. func NullConfig(buildDir string) Config { @@ -448,14 +485,6 @@ func NewConfig(srcDir, buildDir string, moduleListFile string, availableEnv map[ config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] } - if Bool(config.productVariables.GcovCoverage) && Bool(config.productVariables.ClangCoverage) { - return Config{}, fmt.Errorf("GcovCoverage and ClangCoverage cannot both be set") - } - - config.productVariables.Native_coverage = proptools.BoolPtr( - Bool(config.productVariables.GcovCoverage) || - Bool(config.productVariables.ClangCoverage)) - config.BazelContext, err = NewBazelContext(config) config.bp2buildPackageConfig = bp2buildDefaultConfig config.bp2buildModuleTypeConfig = make(map[string]bool) diff --git a/android/paths.go b/android/paths.go index fb751175e..88d625a1f 100644 --- a/android/paths.go +++ b/android/paths.go @@ -1990,6 +1990,10 @@ func RemoveAllOutputDir(path WritablePath) error { func CreateOutputDirIfNonexistent(path WritablePath, perm os.FileMode) error { dir := absolutePath(path.String()) + return createDirIfNonexistent(dir, perm) +} + +func createDirIfNonexistent(dir string, perm os.FileMode) error { if _, err := os.Stat(dir); os.IsNotExist(err) { return os.MkdirAll(dir, os.ModePerm) } else { diff --git a/android/variable.go b/android/variable.go index e83084525..672576a9f 100644 --- a/android/variable.go +++ b/android/variable.go @@ -282,7 +282,7 @@ type productVariables struct { NativeCoverageExcludePaths []string `json:",omitempty"` // Set by NewConfig - Native_coverage *bool + Native_coverage *bool `json:",omitempty"` SanitizeHost []string `json:",omitempty"` SanitizeDevice []string `json:",omitempty"` diff --git a/bazel/constants.go b/bazel/constants.go index 15c75cf4a..6beb496a5 100644 --- a/bazel/constants.go +++ b/bazel/constants.go @@ -18,6 +18,10 @@ const ( // Run bazel as a ninja executer BazelNinjaExecRunName = RunName("bazel-ninja-exec") + + SoongInjectionDirName = "soong_injection" + + GeneratedBazelFileWarning = "# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT" ) // String returns the name of the run. diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go index 59c5acddb..ee36982c7 100644 --- a/bp2build/bp2build.go +++ b/bp2build/bp2build.go @@ -16,6 +16,7 @@ package bp2build import ( "android/soong/android" + "android/soong/bazel" "fmt" "os" ) @@ -32,7 +33,7 @@ func Codegen(ctx *CodegenContext) CodegenMetrics { bp2buildFiles := CreateBazelFiles(nil, buildToTargets, ctx.mode) writeFiles(ctx, bp2buildDir, bp2buildFiles) - soongInjectionDir := android.PathForOutput(ctx, "soong_injection") + soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName) writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles()) return metrics diff --git a/tests/lib.sh b/tests/lib.sh index e561a3d49..35ccea973 100644 --- a/tests/lib.sh +++ b/tests/lib.sh @@ -114,6 +114,7 @@ function create_mock_bazel() { symlink_directory prebuilts/jdk symlink_file WORKSPACE + symlink_file BUILD symlink_file tools/bazel }