Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b46969dd authored by Cole Faust's avatar Cole Faust Committed by Gerrit Code Review
Browse files

Merge "Generate android_certificate_directory" into main

parents ef1fc04e 6054cdf3
Loading
Loading
Loading
Loading
+13 −23
Original line number Diff line number Diff line
@@ -82,15 +82,25 @@ func Codegen(ctx *CodegenContext) *CodegenMetrics {
		os.Exit(1)
	}
	var bp2buildFiles []BazelFile
	productConfig, err := createProductConfigFiles(ctx, res.metrics)
	ctx.Context().EventHandler.Do("CreateBazelFile", func() {
		bp2buildFiles = CreateBazelFiles(nil, res.buildFileToTargets, ctx.mode)
		allTargets := make(map[string]BazelTargets)
		for k, v := range res.buildFileToTargets {
			allTargets[k] = append(allTargets[k], v...)
		}
		for k, v := range productConfig.bp2buildTargets {
			allTargets[k] = append(allTargets[k], v...)
		}
		bp2buildFiles = CreateBazelFiles(nil, allTargets, ctx.mode)
	})
	injectionFiles, additionalBp2buildFiles, err := CreateSoongInjectionDirFiles(ctx, res.metrics)
	bp2buildFiles = append(bp2buildFiles, productConfig.bp2buildFiles...)
	injectionFiles, err := createSoongInjectionDirFiles(ctx, res.metrics)
	if err != nil {
		fmt.Printf("%s\n", err.Error())
		os.Exit(1)
	}
	bp2buildFiles = append(bp2buildFiles, additionalBp2buildFiles...)
	injectionFiles = append(injectionFiles, productConfig.injectionFiles...)

	writeFiles(ctx, bp2buildDir, bp2buildFiles)
	// Delete files under the bp2build root which weren't just written. An
	// alternative would have been to delete the whole directory and write these
@@ -109,26 +119,6 @@ func Codegen(ctx *CodegenContext) *CodegenMetrics {
	return &res.metrics
}

// Wrapper function that will be responsible for all files in soong_injection directory
// This includes
// 1. config value(s) that are hardcoded in Soong
// 2. product_config variables
func CreateSoongInjectionDirFiles(ctx *CodegenContext, metrics CodegenMetrics) ([]BazelFile, []BazelFile, error) {
	var ret []BazelFile

	productConfigInjectionFiles, productConfigBp2BuildDirFiles, err := CreateProductConfigFiles(ctx, metrics)
	if err != nil {
		return nil, nil, err
	}
	ret = append(ret, productConfigInjectionFiles...)
	injectionFiles, err := soongInjectionFiles(ctx.Config(), metrics)
	if err != nil {
		return nil, nil, err
	}
	ret = append(injectionFiles, ret...)
	return ret, productConfigBp2BuildDirFiles, nil
}

// Get the output directory and create it if it doesn't exist.
func getOrCreateOutputDir(outputDir android.OutputPath, ctx android.PathContext, dir string) android.OutputPath {
	dirPath := outputDir.Join(ctx, dir)
+71 −46
Original line number Diff line number Diff line
@@ -12,14 +12,19 @@ import (
	"android/soong/android/soongconfig"
	"android/soong/starlark_import"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
	"go.starlark.net/starlark"
)

func CreateProductConfigFiles(
type createProductConfigFilesResult struct {
	injectionFiles  []BazelFile
	bp2buildFiles   []BazelFile
	bp2buildTargets map[string]BazelTargets
}

func createProductConfigFiles(
	ctx *CodegenContext,
	metrics CodegenMetrics) ([]BazelFile, []BazelFile, error) {
	metrics CodegenMetrics) (createProductConfigFilesResult, error) {
	cfg := &ctx.config
	targetProduct := "unknown"
	if cfg.HasDeviceProduct() {
@@ -32,28 +37,21 @@ func CreateProductConfigFiles(
		targetBuildVariant = "userdebug"
	}

	var res createProductConfigFilesResult

	productVariablesFileName := cfg.ProductVariablesFileName
	if !strings.HasPrefix(productVariablesFileName, "/") {
		productVariablesFileName = filepath.Join(ctx.topDir, productVariablesFileName)
	}
	productVariablesBytes, err := os.ReadFile(productVariablesFileName)
	if err != nil {
		return nil, nil, err
		return res, err
	}
	productVariables := android.ProductVariables{}
	err = json.Unmarshal(productVariablesBytes, &productVariables)
	if err != nil {
		return nil, nil, err
	}

	// Visit all modules to determine the list of ndk libraries
	// This list will be used to add additional flags for cc stub generation
	ndkLibsStringFormatted := []string{}
	ctx.Context().VisitAllModules(func(m blueprint.Module) {
		if ctx.Context().ModuleType(m) == "ndk_library" {
			ndkLibsStringFormatted = append(ndkLibsStringFormatted, fmt.Sprintf(`"%s"`, m.Name())) // name will be `"libc.ndk"`
		return res, err
	}
	})

	// TODO(b/249685973): the name is product_config_platforms because product_config
	// was already used for other files. Deduplicate them.
@@ -64,25 +62,36 @@ func CreateProductConfigFiles(
		"{VARIANT}", targetBuildVariant,
		"{PRODUCT_FOLDER}", currentProductFolder)

	platformMappingContent, err := platformMappingContent(
		productReplacer.Replace("@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}"),
		&productVariables,
		ctx.Config().Bp2buildSoongConfigDefinitions,
		metrics.convertedModulePathMap)
	if err != nil {
		return nil, nil, err
	}

	productsForTestingMap, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing")
	if err != nil {
		return nil, nil, err
		return res, err
	}
	productsForTesting := android.SortedKeys(productsForTestingMap)
	for i := range productsForTesting {
		productsForTesting[i] = fmt.Sprintf("  \"@//build/bazel/tests/products:%s\",", productsForTesting[i])
	}

	injectionDirFiles := []BazelFile{
	productLabelsToVariables := make(map[string]*android.ProductVariables)
	productLabelsToVariables[productReplacer.Replace("@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}")] = &productVariables
	for product, productVariablesStarlark := range productsForTestingMap {
		productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
		if err != nil {
			return res, err
		}
		productLabelsToVariables["@//build/bazel/tests/products:"+product] = &productVariables
	}

	res.bp2buildTargets = createTargets(productLabelsToVariables)

	platformMappingContent, err := platformMappingContent(
		productLabelsToVariables,
		ctx.Config().Bp2buildSoongConfigDefinitions,
		metrics.convertedModulePathMap)
	if err != nil {
		return res, err
	}

	res.injectionFiles = []BazelFile{
		newFile(
			currentProductFolder,
			"soong.variables.bzl",
@@ -164,30 +173,21 @@ build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_lin
			productReplacer.Replace(`
build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_darwin_x86_64
`)),
		newFile(
			"cc_toolchain",
			"ndk_libs.bzl",
			fmt.Sprintf("ndk_libs = [%v]", strings.Join(ndkLibsStringFormatted, ", ")),
		),
	}
	bp2buildDirFiles := []BazelFile{
	res.bp2buildFiles = []BazelFile{
		newFile(
			"",
			"platform_mappings",
			platformMappingContent),
	}
	return injectionDirFiles, bp2buildDirFiles, nil

	return res, nil
}

func platformMappingContent(
	mainProductLabel string,
	mainProductVariables *android.ProductVariables,
	productLabelToVariables map[string]*android.ProductVariables,
	soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions,
	convertedModulePathMap map[string]string) (string, error) {
	productsForTesting, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing")
	if err != nil {
		return "", err
	}
	var result strings.Builder

	mergedConvertedModulePathMap := make(map[string]string)
@@ -203,13 +203,8 @@ func platformMappingContent(
	}

	result.WriteString("platforms:\n")
	platformMappingSingleProduct(mainProductLabel, mainProductVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result)
	for product, productVariablesStarlark := range productsForTesting {
		productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
		if err != nil {
			return "", err
		}
		platformMappingSingleProduct("@//build/bazel/tests/products:"+product, &productVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result)
	for productLabel, productVariables := range productLabelToVariables {
		platformMappingSingleProduct(productLabel, productVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result)
	}
	return result.String(), nil
}
@@ -248,7 +243,7 @@ func platformMappingSingleProduct(

	defaultAppCertificateFilegroup := "//build/bazel/utils:empty_filegroup"
	if proptools.String(productVariables.DefaultAppCertificate) != "" {
		defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":android_certificate_directory"
		defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":generated_android_certificate_directory"
	}

	for _, suffix := range bazelPlatformSuffixes {
@@ -419,3 +414,33 @@ func starlarkMapToProductVariables(in map[string]starlark.Value) (android.Produc

	return result, nil
}

func createTargets(productLabelsToVariables map[string]*android.ProductVariables) map[string]BazelTargets {
	res := make(map[string]BazelTargets)
	var allDefaultAppCertificateDirs []string
	for _, productVariables := range productLabelsToVariables {
		if proptools.String(productVariables.DefaultAppCertificate) != "" {
			d := filepath.Dir(proptools.String(productVariables.DefaultAppCertificate))
			if !android.InList(d, allDefaultAppCertificateDirs) {
				allDefaultAppCertificateDirs = append(allDefaultAppCertificateDirs, d)
			}
		}
	}
	for _, dir := range allDefaultAppCertificateDirs {
		content := fmt.Sprintf(ruleTargetTemplate, "filegroup", "generated_android_certificate_directory", propsToAttributes(map[string]string{
			"srcs": `glob([
        "*.pk8",
        "*.pem",
        "*.avbpubkey",
    ])`,
			"visibility": `["//visibility:public"]`,
		}))
		res[dir] = append(res[dir], BazelTarget{
			name:        "generated_android_certificate_directory",
			packageName: dir,
			content:     content,
			ruleClass:   "filegroup",
		})
	}
	return res
}
+15 −2
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ import (
	rust_config "android/soong/rust/config"
	"android/soong/starlark_fmt"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
)

@@ -24,16 +25,28 @@ type BazelFile struct {
	Contents string
}

// PRIVATE: Use CreateSoongInjectionDirFiles instead
func soongInjectionFiles(cfg android.Config, metrics CodegenMetrics) ([]BazelFile, error) {
// createSoongInjectionDirFiles returns most of the files to write to the soong_injection directory.
// Some other files also come from CreateProductConfigFiles
func createSoongInjectionDirFiles(ctx *CodegenContext, metrics CodegenMetrics) ([]BazelFile, error) {
	cfg := ctx.Config()
	var files []BazelFile

	files = append(files, newFile("android", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
	files = append(files, newFile("android", "constants.bzl", android.BazelCcToolchainVars(cfg)))

	// Visit all modules to determine the list of ndk libraries
	// This list will be used to add additional flags for cc stub generation
	ndkLibsStringFormatted := []string{}
	ctx.Context().VisitAllModules(func(m blueprint.Module) {
		if ctx.Context().ModuleType(m) == "ndk_library" {
			ndkLibsStringFormatted = append(ndkLibsStringFormatted, fmt.Sprintf(`"%s"`, m.Name())) // name will be `"libc.ndk"`
		}
	})

	files = append(files, newFile("cc_toolchain", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
	files = append(files, newFile("cc_toolchain", "config_constants.bzl", cc_config.BazelCcToolchainVars(cfg)))
	files = append(files, newFile("cc_toolchain", "sanitizer_constants.bzl", cc.BazelCcSanitizerToolchainVars(cfg)))
	files = append(files, newFile("cc_toolchain", "ndk_libs.bzl", fmt.Sprintf("ndk_libs = [%v]", strings.Join(ndkLibsStringFormatted, ", "))))

	files = append(files, newFile("java_toolchain", GeneratedBuildFileName, "")) // Creates a //java_toolchain package.
	files = append(files, newFile("java_toolchain", "constants.bzl", java_config.BazelJavaToolchainVars(cfg)))
+42 −7
Original line number Diff line number Diff line
@@ -83,7 +83,8 @@ func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) {

func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
	testConfig := android.TestConfig("", make(map[string]string), "", make(map[string][]byte))
	files, err := soongInjectionFiles(testConfig, CreateCodegenMetrics())
	codegenCtx := NewCodegenContext(testConfig, android.NewTestContext(testConfig).Context, Bp2Build, "")
	files, err := createSoongInjectionDirFiles(codegenCtx, CreateCodegenMetrics())
	if err != nil {
		t.Error(err)
	}
@@ -104,6 +105,10 @@ func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
			dir:      "cc_toolchain",
			basename: "config_constants.bzl",
		},
		{
			dir:      "cc_toolchain",
			basename: "ndk_libs.bzl",
		},
		{
			dir:      "cc_toolchain",
			basename: "sanitizer_constants.bzl",
@@ -182,15 +187,45 @@ func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
		},
	}

	if len(files) != len(expectedFilePaths) {
		t.Errorf("Expected %d file, got %d", len(expectedFilePaths), len(files))
	less := func(a bazelFilepath, b bazelFilepath) bool {
		return a.dir+"/"+a.basename < b.dir+"/"+b.basename
	}

	for i := range files {
		actualFile, expectedFile := files[i], expectedFilePaths[i]
	fileToFilepath := func(a BazelFile) bazelFilepath {
		return bazelFilepath{basename: a.Basename, dir: a.Dir}
	}

		if actualFile.Dir != expectedFile.dir || actualFile.Basename != expectedFile.basename {
			t.Errorf("Did not find expected file %s/%s", actualFile.Dir, actualFile.Basename)
	sort.Slice(expectedFilePaths, func(i, j int) bool {
		return less(expectedFilePaths[i], expectedFilePaths[j])
	})
	sort.Slice(files, func(i, j int) bool {
		return less(fileToFilepath(files[i]), fileToFilepath(files[j]))
	})

	i := 0
	j := 0
	for i < len(expectedFilePaths) && j < len(files) {
		expectedFile, actualFile := expectedFilePaths[i], files[j]

		if actualFile.Dir == expectedFile.dir && actualFile.Basename == expectedFile.basename {
			i++
			j++
		} else if less(expectedFile, fileToFilepath(actualFile)) {
			t.Errorf("Did not find expected file %s/%s", expectedFile.dir, expectedFile.basename)
			i++
		} else {
			t.Errorf("Found unexpected file %s/%s", actualFile.Dir, actualFile.Basename)
			j++
		}
	}
	for i < len(expectedFilePaths) {
		expectedFile := expectedFilePaths[i]
		t.Errorf("Did not find expected file %s/%s", expectedFile.dir, expectedFile.basename)
		i++
	}
	for j < len(files) {
		actualFile := files[j]
		t.Errorf("Found unexpected file %s/%s", actualFile.Dir, actualFile.Basename)
		j++
	}
}