Merge "Add "exported" mode to xx_aconfig_library build rules" into main

This commit is contained in:
Zi Wang
2023-11-13 19:23:55 +00:00
committed by Gerrit Code Review
6 changed files with 238 additions and 19 deletions

View File

@@ -39,7 +39,14 @@ type CcAconfigLibraryProperties struct {
Aconfig_declarations string Aconfig_declarations string
// whether to generate test mode version of the library // whether to generate test mode version of the library
// TODO: remove "Test" property when "Mode" can be used in all the branches
Test *bool Test *bool
// default mode is "production", the other accepted modes are:
// "test": to generate test mode version of the library
// "exported": to generate exported mode version of the library
// an error will be thrown if the mode is not supported
Mode *string
} }
type CcAconfigLibraryCallbacks struct { type CcAconfigLibraryCallbacks struct {
@@ -121,11 +128,16 @@ func (this *CcAconfigLibraryCallbacks) GeneratorBuildActions(ctx cc.ModuleContex
} }
declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData) declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
var mode string if this.properties.Mode != nil && this.properties.Test != nil {
ctx.PropertyErrorf("test", "test prop should not be specified when mode prop is set")
}
mode := proptools.StringDefault(this.properties.Mode, "production")
if !isModeSupported(mode) {
ctx.PropertyErrorf("mode", "%q is not a supported mode", mode)
}
// TODO: remove "Test" property
if proptools.Bool(this.properties.Test) { if proptools.Bool(this.properties.Test) {
mode = "test" mode = "test"
} else {
mode = "production"
} }
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: cppRule, Rule: cppRule,

View File

@@ -22,16 +22,17 @@ import (
"android/soong/cc" "android/soong/cc"
) )
var codegenModeTestData = []struct { var ccCodegenModeTestData = []struct {
setting, expected string setting, expected string
}{ }{
{"", "production"}, {"", "production"},
{"test: false,", "production"}, {"mode: `production`,", "production"},
{"test: true,", "test"}, {"mode: `test`,", "test"},
{"mode: `exported`,", "exported"},
} }
func TestCCCodegenMode(t *testing.T) { func TestCCCodegenMode(t *testing.T) {
for _, testData := range codegenModeTestData { for _, testData := range ccCodegenModeTestData {
testCCCodegenModeHelper(t, testData.setting, testData.expected) testCCCodegenModeHelper(t, testData.setting, testData.expected)
} }
} }
@@ -65,3 +66,43 @@ func testCCCodegenModeHelper(t *testing.T, bpMode string, ruleMode string) {
rule := module.Rule("cc_aconfig_library") rule := module.Rule("cc_aconfig_library")
android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode) android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode)
} }
var incorrectCCCodegenModeTestData = []struct {
setting, expectedErr string
}{
{"mode: `unsupported`,", "mode: \"unsupported\" is not a supported mode"},
// TODO: remove this test case when test prop is removed
{"mode: `test`, test: true", "test prop should not be specified when mode prop is set"},
}
func TestIncorrectCCCodegenMode(t *testing.T) {
for _, testData := range incorrectCCCodegenModeTestData {
testIncorrectCCCodegenModeHelper(t, testData.setting, testData.expectedErr)
}
}
func testIncorrectCCCodegenModeHelper(t *testing.T, bpMode string, err string) {
t.Helper()
android.GroupFixturePreparers(
PrepareForTestWithAconfigBuildComponents,
cc.PrepareForTestWithCcDefaultModules).
ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(err)).
RunTestWithBp(t, fmt.Sprintf(`
aconfig_declarations {
name: "my_aconfig_declarations",
package: "com.example.package",
srcs: ["foo.aconfig"],
}
cc_library {
name: "server_configurable_flags",
srcs: ["server_configurable_flags.cc"],
}
cc_aconfig_library {
name: "my_cc_aconfig_library",
aconfig_declarations: "my_aconfig_declarations",
%s
}
`, bpMode))
}

View File

@@ -30,12 +30,21 @@ type declarationsTagType struct {
var declarationsTag = declarationsTagType{} var declarationsTag = declarationsTagType{}
var aconfigSupportedModes = []string{"production", "test", "exported"}
type JavaAconfigDeclarationsLibraryProperties struct { type JavaAconfigDeclarationsLibraryProperties struct {
// name of the aconfig_declarations module to generate a library for // name of the aconfig_declarations module to generate a library for
Aconfig_declarations string Aconfig_declarations string
// whether to generate test mode version of the library // whether to generate test mode version of the library
// TODO: remove "Test" property when "Mode" can be used in all the branches
Test *bool Test *bool
// default mode is "production", the other accepted modes are:
// "test": to generate test mode version of the library
// "exported": to generate exported mode version of the library
// an error will be thrown if the mode is not supported
Mode *string
} }
type JavaAconfigDeclarationsLibraryCallbacks struct { type JavaAconfigDeclarationsLibraryCallbacks struct {
@@ -72,12 +81,19 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild
// Generate the action to build the srcjar // Generate the action to build the srcjar
srcJarPath := android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar") srcJarPath := android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar")
var mode string
if callbacks.properties.Mode != nil && callbacks.properties.Test != nil {
ctx.PropertyErrorf("test", "test prop should not be specified when mode prop is set")
}
mode := proptools.StringDefault(callbacks.properties.Mode, "production")
if !isModeSupported(mode) {
ctx.PropertyErrorf("mode", "%q is not a supported mode", mode)
}
// TODO: remove "Test" property
if proptools.Bool(callbacks.properties.Test) { if proptools.Bool(callbacks.properties.Test) {
mode = "test" mode = "test"
} else {
mode = "production"
} }
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: javaRule, Rule: javaRule,
Input: declarations.IntermediatePath, Input: declarations.IntermediatePath,
@@ -95,9 +111,12 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild
return srcJarPath return srcJarPath
} }
func isModeSupported(mode string) bool {
return android.InList(mode, aconfigSupportedModes)
}
type bazelJavaAconfigLibraryAttributes struct { type bazelJavaAconfigLibraryAttributes struct {
Aconfig_declarations bazel.LabelAttribute Aconfig_declarations bazel.LabelAttribute
Test *bool
Sdk_version *string Sdk_version *string
Libs bazel.LabelListAttribute Libs bazel.LabelListAttribute
} }
@@ -138,7 +157,6 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) Bp2build(ctx android.B
attrs := bazelJavaAconfigLibraryAttributes{ attrs := bazelJavaAconfigLibraryAttributes{
Aconfig_declarations: *bazel.MakeLabelAttribute(android.BazelLabelForModuleDepSingle(ctx, callbacks.properties.Aconfig_declarations).Label), Aconfig_declarations: *bazel.MakeLabelAttribute(android.BazelLabelForModuleDepSingle(ctx, callbacks.properties.Aconfig_declarations).Label),
Test: callbacks.properties.Test,
Sdk_version: &sdkVersion, Sdk_version: &sdkVersion,
Libs: libs, Libs: libs,
} }

View File

@@ -178,14 +178,48 @@ func testCodegenMode(t *testing.T, bpMode string, ruleMode string) {
android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode) android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode)
} }
func testCodegenModeWithError(t *testing.T, bpMode string, err string) {
android.GroupFixturePreparers(
PrepareForTestWithAconfigBuildComponents,
java.PrepareForTestWithJavaDefaultModules).
ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(err)).
RunTestWithBp(t, fmt.Sprintf(`
aconfig_declarations {
name: "my_aconfig_declarations",
package: "com.example.package",
srcs: ["foo.aconfig"],
}
java_aconfig_library {
name: "my_java_aconfig_library",
aconfig_declarations: "my_aconfig_declarations",
%s
}
`, bpMode))
}
func TestDefaultProdMode(t *testing.T) { func TestDefaultProdMode(t *testing.T) {
testCodegenMode(t, "", "production") testCodegenMode(t, "", "production")
} }
func TestProdMode(t *testing.T) { func TestProdMode(t *testing.T) {
testCodegenMode(t, "test: false,", "production") testCodegenMode(t, "mode: `production`,", "production")
} }
func TestTestMode(t *testing.T) { func TestTestMode(t *testing.T) {
testCodegenMode(t, "test: true,", "test") testCodegenMode(t, "mode: `test`,", "test")
}
func TestExportedMode(t *testing.T) {
testCodegenMode(t, "mode: `exported`,", "exported")
}
func TestUnsupportedMode(t *testing.T) {
testCodegenModeWithError(t, "mode: `unsupported`,", "mode: \"unsupported\" is not a supported mode")
}
// TODO: remove this test case when test prop is removed
func TestBothModeAndTestAreSet(t *testing.T) {
testCodegenModeWithError(t, "mode: `test`, test: true",
"test prop should not be specified when mode prop is set")
} }

View File

@@ -1,9 +1,10 @@
package aconfig package aconfig
import ( import (
"fmt"
"android/soong/android" "android/soong/android"
"android/soong/rust" "android/soong/rust"
"fmt"
"github.com/google/blueprint" "github.com/google/blueprint"
"github.com/google/blueprint/proptools" "github.com/google/blueprint/proptools"
@@ -18,7 +19,16 @@ var rustDeclarationsTag = rustDeclarationsTagType{}
type RustAconfigLibraryProperties struct { type RustAconfigLibraryProperties struct {
// name of the aconfig_declarations module to generate a library for // name of the aconfig_declarations module to generate a library for
Aconfig_declarations string Aconfig_declarations string
Test *bool
// whether to generate test mode version of the library
// TODO: remove "Test" property when "Mode" can be used in all the branches
Test *bool
// default mode is "production", the other accepted modes are:
// "test": to generate test mode version of the library
// "exported": to generate exported mode version of the library
// an error will be thrown if the mode is not supported
Mode *string
} }
type aconfigDecorator struct { type aconfigDecorator struct {
@@ -60,7 +70,15 @@ func (a *aconfigDecorator) GenerateSource(ctx rust.ModuleContext, deps rust.Path
} }
declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData) declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
mode := "production" if a.Properties.Mode != nil && a.Properties.Test != nil {
ctx.PropertyErrorf("test", "test prop should not be specified when mode prop is set")
}
mode := proptools.StringDefault(a.Properties.Mode, "production")
if !isModeSupported(mode) {
ctx.PropertyErrorf("mode", "%q is not a supported mode", mode)
}
// TODO: remove "Test" property
if proptools.Bool(a.Properties.Test) { if proptools.Bool(a.Properties.Test) {
mode = "test" mode = "test"
} }

View File

@@ -1,10 +1,11 @@
package aconfig package aconfig
import ( import (
"android/soong/android"
"android/soong/rust"
"fmt" "fmt"
"testing" "testing"
"android/soong/android"
"android/soong/rust"
) )
func TestRustAconfigLibrary(t *testing.T) { func TestRustAconfigLibrary(t *testing.T) {
@@ -63,3 +64,98 @@ func TestRustAconfigLibrary(t *testing.T) {
) )
} }
} }
var rustCodegenModeTestData = []struct {
setting, expected string
}{
{"", "production"},
{"mode: `production`,", "production"},
{"mode: `test`,", "test"},
{"mode: `exported`,", "exported"},
}
func TestRustCodegenMode(t *testing.T) {
for _, testData := range rustCodegenModeTestData {
testRustCodegenModeHelper(t, testData.setting, testData.expected)
}
}
func testRustCodegenModeHelper(t *testing.T, bpMode string, ruleMode string) {
t.Helper()
result := android.GroupFixturePreparers(
PrepareForTestWithAconfigBuildComponents,
rust.PrepareForTestWithRustIncludeVndk).
ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
RunTestWithBp(t, fmt.Sprintf(`
rust_library {
name: "libflags_rust", // test mock
crate_name: "flags_rust",
srcs: ["lib.rs"],
}
rust_library {
name: "liblazy_static", // test mock
crate_name: "lazy_static",
srcs: ["src/lib.rs"],
}
aconfig_declarations {
name: "my_aconfig_declarations",
package: "com.example.package",
srcs: ["foo.aconfig"],
}
rust_aconfig_library {
name: "libmy_rust_aconfig_library",
crate_name: "my_rust_aconfig_library",
aconfig_declarations: "my_aconfig_declarations",
%s
}
`, bpMode))
module := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_source")
rule := module.Rule("rust_aconfig_library")
android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode)
}
var incorrectRustCodegenModeTestData = []struct {
setting, expectedErr string
}{
{"mode: `unsupported`,", "mode: \"unsupported\" is not a supported mode"},
// TODO: remove this test case when test prop is removed
{"mode: `test`, test: true", "test prop should not be specified when mode prop is set"},
}
func TestIncorrectRustCodegenMode(t *testing.T) {
for _, testData := range incorrectRustCodegenModeTestData {
testIncorrectRustCodegenModeHelper(t, testData.setting, testData.expectedErr)
}
}
func testIncorrectRustCodegenModeHelper(t *testing.T, bpMode string, err string) {
t.Helper()
android.GroupFixturePreparers(
PrepareForTestWithAconfigBuildComponents,
rust.PrepareForTestWithRustIncludeVndk).
ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(err)).
RunTestWithBp(t, fmt.Sprintf(`
rust_library {
name: "libflags_rust", // test mock
crate_name: "flags_rust",
srcs: ["lib.rs"],
}
rust_library {
name: "liblazy_static", // test mock
crate_name: "lazy_static",
srcs: ["src/lib.rs"],
}
aconfig_declarations {
name: "my_aconfig_declarations",
package: "com.example.package",
srcs: ["foo.aconfig"],
}
rust_aconfig_library {
name: "libmy_rust_aconfig_library",
crate_name: "my_rust_aconfig_library",
aconfig_declarations: "my_aconfig_declarations",
%s
}
`, bpMode))
}