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

Commit 4242f104 authored by Spandan Das's avatar Spandan Das
Browse files

Create config_setting per apex_name

These are created by bp2build in /build/bazel/rules/apex. Eventually
these config_settings should likely be colocated with the source apex
definition.

Another alternative was to make Bazel's apex a macro that generates a
config_setting. I did not pursue this further for now since it requires the
apex_available of every allowlisted cc_library to also be allowlisted.
This might not always be true (e.g. com.android.runtime)

Test: go test ./bp2build
Change-Id: Ibbb14b0d9c1491b3c79b7634a18d9d35b03922c1
parent 6a448ec1
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -268,9 +268,8 @@ func (ct configurationType) validateConfig(config string) {
	case productVariables:
		// do nothing
	case osAndInApex:
		if _, ok := osAndInApexMap[config]; !ok {
			panic(fmt.Errorf("Unknown os+in_apex config: %s", config))
		}
		// do nothing
		// this axis can contain additional per-apex keys
	case inApex:
		if _, ok := inApexMap[config]; !ok {
			panic(fmt.Errorf("Unknown in_apex config: %s", config))
@@ -299,7 +298,10 @@ func (ca ConfigurationAxis) SelectKey(config string) string {
		}
		return fmt.Sprintf("%s:%s", productVariableBazelPackage, config)
	case osAndInApex:
		return osAndInApexMap[config]
		if ret, exists := osAndInApexMap[config]; exists {
			return ret
		}
		return config
	case inApex:
		return inApexMap[config]
	default:
+29 −0
Original line number Diff line number Diff line
@@ -4454,3 +4454,32 @@ cc_library {
		},
	})
}

// Test that a config_setting specific to an apex is created by cc_library.
func TestCcLibraryCreatesInApexConfigSetting(t *testing.T) {
	runCcLibraryTestCase(t, Bp2buildTestCase{
		Description:                "cc_library creates a config_setting for each apex in apex_available",
		ModuleTypeUnderTest:        "cc_library",
		ModuleTypeUnderTestFactory: cc.LibraryFactory,
		Dir:                        "build/bazel/rules/apex",
		Blueprint: `
cc_library {
	name: "foo",
	apex_available: [
	"//apex_available:platform", // This will be skipped, since it is equivalent to //build/bazel/rules/apex:android-non_apex
	"myapex"
	],
}`,
		ExpectedBazelTargets: []string{
			MakeBazelTargetNoRestrictions(
				"config_setting",
				"android-in_myapex",
				AttrNameToString{
					"flag_values": `{
        "//build/bazel/rules/apex:apex_name": "myapex",
    }`,
				},
			),
		},
	})
}
+65 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ import (
	"fmt"
	"path/filepath"
	"strings"
	"sync"

	"android/soong/android"
	"android/soong/bazel"
@@ -1196,6 +1197,63 @@ func availableToSameApexes(a, b []string) bool {
	return !differ
}

var (
	apexConfigSettingKey  = android.NewOnceKey("apexConfigSetting")
	apexConfigSettingLock sync.Mutex
)

func getApexConfigSettingMap(config android.Config) *map[string]bool {
	return config.Once(apexConfigSettingKey, func() interface{} {
		return &map[string]bool{}
	}).(*map[string]bool)
}

// Create a config setting for this apex in build/bazel/rules/apex
// The use case for this is stub/impl selection in cc libraries
// Long term, these config_setting(s) should be colocated with the respective apex definitions.
// Note that this is an anti-pattern: The config_setting should be created from the apex definition
// and not from a cc_library.
// This anti-pattern is needed today since not all apexes have been allowlisted.
func createInApexConfigSetting(ctx android.TopDownMutatorContext, apexName string) {
	if apexName == android.AvailableToPlatform || apexName == android.AvailableToAnyApex {
		// These correspond to android-non_apex and android-in_apex
		return
	}
	apexConfigSettingLock.Lock()
	defer apexConfigSettingLock.Unlock()

	// Return if a config_setting has already been created
	acsm := getApexConfigSettingMap(ctx.Config())
	if _, exists := (*acsm)[apexName]; exists {
		return
	}
	(*acsm)[apexName] = true

	csa := bazel.ConfigSettingAttributes{
		Flag_values: bazel.StringMapAttribute{
			"//build/bazel/rules/apex:apex_name": apexName,
		},
	}
	ca := android.CommonAttributes{
		Name: "android-in_" + apexName,
	}
	ctx.CreateBazelConfigSetting(
		csa,
		ca,
		"build/bazel/rules/apex",
	)
}

func inApexConfigSetting(apexAvailable string) string {
	if apexAvailable == android.AvailableToPlatform {
		return bazel.AndroidAndNonApex
	}
	if apexAvailable == android.AvailableToAnyApex {
		return bazel.AndroidAndInApex
	}
	return "//build/bazel/rules/apex:android-in_" + apexAvailable
}

func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis,
	config string, apexAvailable []string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int, buildNonApexWithStubs bool) {

@@ -1241,6 +1299,13 @@ func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.C
			dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, bazel.FirstUniqueBazelLabelList(nonApexSelectValue))
		}
	}

	// Create a config_setting for each apex_available.
	// This will be used to select impl of a dep if dep is available to the same apex.
	for _, aa := range apexAvailable {
		createInApexConfigSetting(ctx.(android.TopDownMutatorContext), aa)
	}

}

func (la *linkerAttributes) convertStripProps(ctx android.BazelConversionPathContext, module *Module) {