Merge "Only store what's used in SharedLibraryInfo"
diff --git a/android/paths.go b/android/paths.go
index b192a35..128ec12 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -1591,6 +1591,18 @@
// PathForModuleInstall returns a Path representing the install path for the
// module appended with paths...
func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string) InstallPath {
+ os, arch := osAndArch(ctx)
+ partition := modulePartition(ctx, os)
+ return makePathForInstall(ctx, os, arch, partition, ctx.Debug(), pathComponents...)
+}
+
+// PathForModuleInPartitionInstall is similar to PathForModuleInstall but partition is provided by the caller
+func PathForModuleInPartitionInstall(ctx ModuleInstallPathContext, partition string, pathComponents ...string) InstallPath {
+ os, arch := osAndArch(ctx)
+ return makePathForInstall(ctx, os, arch, partition, ctx.Debug(), pathComponents...)
+}
+
+func osAndArch(ctx ModuleInstallPathContext) (OsType, ArchType) {
os := ctx.Os()
arch := ctx.Arch().ArchType
forceOS, forceArch := ctx.InstallForceOS()
@@ -1600,14 +1612,14 @@
if forceArch != nil {
arch = *forceArch
}
- partition := modulePartition(ctx, os)
+ return os, arch
+}
- ret := pathForInstall(ctx, os, arch, partition, ctx.Debug(), pathComponents...)
-
+func makePathForInstall(ctx ModuleInstallPathContext, os OsType, arch ArchType, partition string, debug bool, pathComponents ...string) InstallPath {
+ ret := pathForInstall(ctx, os, arch, partition, debug, pathComponents...)
if ctx.InstallBypassMake() && ctx.Config().KatiEnabled() {
ret = ret.ToMakePath()
}
-
return ret
}
diff --git a/bazel/properties.go b/bazel/properties.go
index 99119cd..7093d6c 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -350,6 +350,83 @@
return keys
}
+type configToBools map[string]bool
+
+func (ctb configToBools) setValue(config string, value *bool) {
+ if value == nil {
+ if _, ok := ctb[config]; ok {
+ delete(ctb, config)
+ }
+ return
+ }
+ ctb[config] = *value
+}
+
+type configurableBools map[ConfigurationAxis]configToBools
+
+func (cb configurableBools) setValueForAxis(axis ConfigurationAxis, config string, value *bool) {
+ if cb[axis] == nil {
+ cb[axis] = make(configToBools)
+ }
+ cb[axis].setValue(config, value)
+}
+
+// BoolAttribute represents an attribute whose value is a single bool but may be configurable..
+type BoolAttribute struct {
+ Value *bool
+
+ ConfigurableValues configurableBools
+}
+
+// HasConfigurableValues returns whether there are configurable values for this attribute.
+func (ba BoolAttribute) HasConfigurableValues() bool {
+ return len(ba.ConfigurableValues) > 0
+}
+
+// SetSelectValue sets value for the given axis/config.
+func (ba *BoolAttribute) SetSelectValue(axis ConfigurationAxis, config string, value *bool) {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ ba.Value = value
+ case arch, os, osArch, productVariables:
+ if ba.ConfigurableValues == nil {
+ ba.ConfigurableValues = make(configurableBools)
+ }
+ ba.ConfigurableValues.setValueForAxis(axis, config, value)
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SelectValue gets the value for the given axis/config.
+func (ba BoolAttribute) SelectValue(axis ConfigurationAxis, config string) *bool {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ return ba.Value
+ case arch, os, osArch, productVariables:
+ if v, ok := ba.ConfigurableValues[axis][config]; ok {
+ return &v
+ } else {
+ return nil
+ }
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
+func (ba *BoolAttribute) SortedConfigurationAxes() []ConfigurationAxis {
+ keys := make([]ConfigurationAxis, 0, len(ba.ConfigurableValues))
+ for k := range ba.ConfigurableValues {
+ keys = append(keys, k)
+ }
+
+ sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) })
+ return keys
+}
+
// labelListSelectValues supports config-specific label_list typed Bazel attribute values.
type labelListSelectValues map[string]LabelList
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 6bdfc0e..4de5aae 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -567,6 +567,10 @@
} else {
return true
}
+ // Always print bools, if you want a bool attribute to be able to take the default value, use a
+ // bool pointer instead
+ case reflect.Bool:
+ return false
default:
if !value.IsValid() {
return true
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 6d0a9b2..33609af 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -23,12 +23,14 @@
func TestGenerateSoongModuleTargets(t *testing.T) {
testCases := []struct {
+ description string
bp string
expectedBazelTarget string
}{
{
+ description: "only name",
bp: `custom { name: "foo" }
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -36,14 +38,16 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = False,
)`,
},
{
+ description: "handles bool",
bp: `custom {
- name: "foo",
- ramdisk: true,
+ name: "foo",
+ bool_prop: true,
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -51,15 +55,16 @@
soong_module_variant = "",
soong_module_deps = [
],
- ramdisk = True,
+ bool_prop = True,
)`,
},
{
+ description: "string escaping",
bp: `custom {
- name: "foo",
- owner: "a_string_with\"quotes\"_and_\\backslashes\\\\",
+ name: "foo",
+ owner: "a_string_with\"quotes\"_and_\\backslashes\\\\",
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -67,15 +72,17 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = False,
owner = "a_string_with\"quotes\"_and_\\backslashes\\\\",
)`,
},
{
+ description: "single item string list",
bp: `custom {
- name: "foo",
- required: ["bar"],
+ name: "foo",
+ required: ["bar"],
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -83,15 +90,17 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = False,
required = ["bar"],
)`,
},
{
+ description: "list of strings",
bp: `custom {
- name: "foo",
- target_required: ["qux", "bazqux"],
+ name: "foo",
+ target_required: ["qux", "bazqux"],
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -99,6 +108,7 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = False,
target_required = [
"qux",
"bazqux",
@@ -106,18 +116,19 @@
)`,
},
{
+ description: "dist/dists",
bp: `custom {
- name: "foo",
- dist: {
- targets: ["goal_foo"],
- tag: ".foo",
- },
- dists: [{
- targets: ["goal_bar"],
- tag: ".bar",
- }],
+ name: "foo",
+ dist: {
+ targets: ["goal_foo"],
+ tag: ".foo",
+ },
+ dists: [{
+ targets: ["goal_bar"],
+ tag: ".bar",
+ }],
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -125,6 +136,7 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = False,
dist = {
"tag": ".foo",
"targets": ["goal_foo"],
@@ -136,20 +148,21 @@
)`,
},
{
+ description: "put it together",
bp: `custom {
- name: "foo",
- required: ["bar"],
- target_required: ["qux", "bazqux"],
- ramdisk: true,
- owner: "custom_owner",
- dists: [
- {
- tag: ".tag",
- targets: ["my_goal"],
- },
- ],
+ name: "foo",
+ required: ["bar"],
+ target_required: ["qux", "bazqux"],
+ bool_prop: true,
+ owner: "custom_owner",
+ dists: [
+ {
+ tag: ".tag",
+ targets: ["my_goal"],
+ },
+ ],
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -157,12 +170,12 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = True,
dists = [{
"tag": ".tag",
"targets": ["my_goal"],
}],
owner = "custom_owner",
- ramdisk = True,
required = ["bar"],
target_required = [
"qux",
@@ -174,31 +187,33 @@
dir := "."
for _, testCase := range testCases {
- config := android.TestConfig(buildDir, nil, testCase.bp, nil)
- ctx := android.NewTestContext(config)
+ t.Run(testCase.description, func(t *testing.T) {
+ config := android.TestConfig(buildDir, nil, testCase.bp, nil)
+ ctx := android.NewTestContext(config)
- ctx.RegisterModuleType("custom", customModuleFactory)
- ctx.Register()
+ ctx.RegisterModuleType("custom", customModuleFactory)
+ ctx.Register()
- _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
- android.FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- android.FailIfErrored(t, errs)
+ _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ android.FailIfErrored(t, errs)
- codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
- if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
- t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount)
- }
+ codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView)
+ bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
+ if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
+ t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount)
+ }
- actualBazelTarget := bazelTargets[0]
- if actualBazelTarget.content != testCase.expectedBazelTarget {
- t.Errorf(
- "Expected generated Bazel target to be '%s', got '%s'",
- testCase.expectedBazelTarget,
- actualBazelTarget.content,
- )
- }
+ actualBazelTarget := bazelTargets[0]
+ if actualBazelTarget.content != testCase.expectedBazelTarget {
+ t.Errorf(
+ "Expected generated Bazel target to be '%s', got '%s'",
+ testCase.expectedBazelTarget,
+ actualBazelTarget.content,
+ )
+ }
+ })
}
}
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index d84a7bb..c464cec 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -25,18 +25,18 @@
// See cc/testing.go for more context
soongCcLibraryPreamble = `
cc_defaults {
- name: "linux_bionic_supported",
+ name: "linux_bionic_supported",
}
toolchain_library {
- name: "libclang_rt.builtins-x86_64-android",
- defaults: ["linux_bionic_supported"],
- vendor_available: true,
- vendor_ramdisk_available: true,
- product_available: true,
- recovery_available: true,
- native_bridge_supported: true,
- src: "",
+ name: "libclang_rt.builtins-x86_64-android",
+ defaults: ["linux_bionic_supported"],
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ product_available: true,
+ recovery_available: true,
+ native_bridge_supported: true,
+ src: "",
}`
)
@@ -564,32 +564,32 @@
cc_library {
name: "a",
srcs: [
- "both_source.cpp",
- "both_source.cc",
- "both_source.c",
- "both_source.s",
- "both_source.S",
+ "both_source.cpp",
+ "both_source.cc",
+ "both_source.c",
+ "both_source.s",
+ "both_source.S",
":both_filegroup",
- ],
+ ],
static: {
- srcs: [
- "static_source.cpp",
- "static_source.cc",
- "static_source.c",
- "static_source.s",
- "static_source.S",
- ":static_filegroup",
- ],
+ srcs: [
+ "static_source.cpp",
+ "static_source.cc",
+ "static_source.c",
+ "static_source.s",
+ "static_source.S",
+ ":static_filegroup",
+ ],
},
shared: {
- srcs: [
- "shared_source.cpp",
- "shared_source.cc",
- "shared_source.c",
- "shared_source.s",
- "shared_source.S",
- ":shared_filegroup",
- ],
+ srcs: [
+ "shared_source.cpp",
+ "shared_source.cc",
+ "shared_source.c",
+ "shared_source.s",
+ "shared_source.S",
+ ":shared_filegroup",
+ ],
},
bazel_module: { bp2build_available: true },
}
@@ -598,21 +598,21 @@
name: "both_filegroup",
srcs: [
// Not relevant, handled by filegroup macro
- ],
+ ],
}
filegroup {
name: "shared_filegroup",
srcs: [
// Not relevant, handled by filegroup macro
- ],
+ ],
}
filegroup {
name: "static_filegroup",
srcs: [
// Not relevant, handled by filegroup macro
- ],
+ ],
}
`,
},
@@ -710,21 +710,21 @@
dir: "foo/bar",
filesystem: map[string]string{
"foo/bar/Android.bp": `
- cc_library {
- name: "a",
- srcs: ["a.cpp"],
- arch: {
- arm: {
- version_script: "arm.map",
- },
- arm64: {
- version_script: "arm64.map",
- },
- },
+ cc_library {
+ name: "a",
+ srcs: ["a.cpp"],
+ arch: {
+ arm: {
+ version_script: "arm.map",
+ },
+ arm64: {
+ version_script: "arm64.map",
+ },
+ },
- bazel_module: { bp2build_available: true },
- }
- `,
+ bazel_module: { bp2build_available: true },
+ }
+ `,
},
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
@@ -805,8 +805,8 @@
srcs: ["b.cpp"],
arch: {
x86_64: {
- pack_relocations: false,
- },
+ pack_relocations: false,
+ },
},
bazel_module: { bp2build_available: true },
}
@@ -816,8 +816,8 @@
srcs: ["c.cpp"],
target: {
darwin: {
- pack_relocations: false,
- },
+ pack_relocations: false,
+ },
},
bazel_module: { bp2build_available: true },
}`,
@@ -900,22 +900,22 @@
name: "a",
srcs: ["a.cpp"],
cflags: [
- "-Wall",
- ],
+ "-Wall",
+ ],
cppflags: [
"-fsigned-char",
"-pedantic",
- ],
+ ],
arch: {
arm64: {
cppflags: ["-DARM64=1"],
- },
- },
+ },
+ },
target: {
android: {
cppflags: ["-DANDROID=1"],
- },
- },
+ },
+ },
bazel_module: { bp2build_available: true },
}
`,
@@ -953,21 +953,21 @@
dir: "foo/bar",
filesystem: map[string]string{
"foo/bar/Android.bp": `
- cc_library {
- name: "a",
- srcs: ["a.cpp"],
- target: {
- android_arm: {
- version_script: "android_arm.map",
- },
- linux_bionic_arm64: {
- version_script: "linux_bionic_arm64.map",
- },
- },
+ cc_library {
+ name: "a",
+ srcs: ["a.cpp"],
+ target: {
+ android_arm: {
+ version_script: "android_arm.map",
+ },
+ linux_bionic_arm64: {
+ version_script: "linux_bionic_arm64.map",
+ },
+ },
- bazel_module: { bp2build_available: true },
- }
- `,
+ bazel_module: { bp2build_available: true },
+ }
+ `,
},
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
@@ -1099,3 +1099,135 @@
},
})
}
+
+func TestCCLibraryNoCrtTrue(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library - simple example",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library_headers { name: "some-headers" }
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ no_libcrt: true,
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ srcs = ["impl.cpp"],
+ use_libcrt = False,
+)`}})
+}
+
+func TestCCLibraryNoCrtFalse(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library_headers { name: "some-headers" }
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ no_libcrt: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ srcs = ["impl.cpp"],
+ use_libcrt = True,
+)`}})
+}
+
+func TestCCLibraryNoCrtArchVariant(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library_headers { name: "some-headers" }
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ arch: {
+ arm: {
+ no_libcrt: true,
+ },
+ x86: {
+ no_libcrt: true,
+ },
+ },
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ srcs = ["impl.cpp"],
+ use_libcrt = select({
+ "//build/bazel/platforms/arch:arm": False,
+ "//build/bazel/platforms/arch:x86": False,
+ "//conditions:default": None,
+ }),
+)`}})
+}
+
+func TestCCLibraryNoCrtArchVariantWithDefault(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library_headers { name: "some-headers" }
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ no_libcrt: false,
+ arch: {
+ arm: {
+ no_libcrt: true,
+ },
+ x86: {
+ no_libcrt: true,
+ },
+ },
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ srcs = ["impl.cpp"],
+ use_libcrt = select({
+ "//build/bazel/platforms/arch:arm": False,
+ "//build/bazel/platforms/arch:x86": False,
+ "//conditions:default": True,
+ }),
+)`}})
+}
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 264ba6b..db344de 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -374,3 +374,39 @@
)`},
})
}
+
+func TestCcLibraryHeadersNoCrtIgnored(t *testing.T) {
+ runCcLibraryHeadersTestCase(t, bp2buildTestCase{
+ description: "cc_library_headers test",
+ moduleTypeUnderTest: "cc_library_headers",
+ moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
+ filesystem: map[string]string{
+ "lib-1/lib1a.h": "",
+ "lib-1/lib1b.h": "",
+ "lib-2/lib2a.h": "",
+ "lib-2/lib2b.h": "",
+ "dir-1/dir1a.h": "",
+ "dir-1/dir1b.h": "",
+ "dir-2/dir2a.h": "",
+ "dir-2/dir2b.h": "",
+ "arch_arm64_exported_include_dir/a.h": "",
+ "arch_x86_exported_include_dir/b.h": "",
+ "arch_x86_64_exported_include_dir/c.h": "",
+ },
+ blueprint: soongCcLibraryHeadersPreamble + `
+cc_library_headers {
+ name: "lib-1",
+ export_include_dirs: ["lib-1"],
+ no_libcrt: true,
+}`,
+ expectedBazelTargets: []string{`cc_library_headers(
+ name = "lib-1",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ includes = ["lib-1"],
+)`},
+ })
+}
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index 60f6330..c8105eb 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -51,6 +51,28 @@
return value, []selects{ret}
}
+func getBoolValue(boolAttr bazel.BoolAttribute) (reflect.Value, []selects) {
+ value := reflect.ValueOf(boolAttr.Value)
+ if !boolAttr.HasConfigurableValues() {
+ return value, []selects{}
+ }
+
+ ret := selects{}
+ for _, axis := range boolAttr.SortedConfigurationAxes() {
+ configToBools := boolAttr.ConfigurableValues[axis]
+ for config, bools := range configToBools {
+ selectKey := axis.SelectKey(config)
+ ret[selectKey] = reflect.ValueOf(bools)
+ }
+ }
+ // if there is a select, use the base value as the conditions default value
+ if len(ret) > 0 {
+ ret[bazel.ConditionsDefaultSelectKey] = value
+ value = reflect.Zero(value.Type())
+ }
+
+ return value, []selects{ret}
+}
func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) {
value := reflect.ValueOf(list.Value.Includes)
var ret []selects
@@ -85,22 +107,30 @@
return false, reflect.Zero(reflect.TypeOf([]string{}))
}
+var (
+ emptyBazelList = "[]"
+ bazelNone = "None"
+)
+
// prettyPrintAttribute converts an Attribute to its Bazel syntax. May contain
// select statements.
func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
var value reflect.Value
var configurableAttrs []selects
- var defaultSelectValue string
+ var defaultSelectValue *string
switch list := v.(type) {
case bazel.StringListAttribute:
value, configurableAttrs = getStringListValues(list)
- defaultSelectValue = "[]"
+ defaultSelectValue = &emptyBazelList
case bazel.LabelListAttribute:
value, configurableAttrs = getLabelListValues(list)
- defaultSelectValue = "[]"
+ defaultSelectValue = &emptyBazelList
case bazel.LabelAttribute:
value, configurableAttrs = getLabelValue(list)
- defaultSelectValue = "None"
+ defaultSelectValue = &bazelNone
+ case bazel.BoolAttribute:
+ value, configurableAttrs = getBoolValue(list)
+ defaultSelectValue = &bazelNone
default:
return "", fmt.Errorf("Not a supported Bazel attribute type: %s", v)
}
@@ -116,7 +146,7 @@
ret += s
}
// Convenience function to append selects components to an attribute value.
- appendSelects := func(selectsData selects, defaultValue, s string) (string, error) {
+ appendSelects := func(selectsData selects, defaultValue *string, s string) (string, error) {
selectMap, err := prettyPrintSelectMap(selectsData, defaultValue, indent)
if err != nil {
return "", err
@@ -141,13 +171,11 @@
// prettyPrintSelectMap converts a map of select keys to reflected Values as a generic way
// to construct a select map for any kind of attribute type.
-func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue string, indent int) (string, error) {
+func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue *string, indent int) (string, error) {
if selectMap == nil {
return "", nil
}
- // addConditionsDefault := false
-
var selects string
for _, selectKey := range android.SortedStringKeys(selectMap) {
if selectKey == bazel.ConditionsDefaultSelectKey {
@@ -184,14 +212,14 @@
if err != nil {
return "", err
}
- if s == "" {
- // Print an explicit empty list (the default value) even if the value is
- // empty, to avoid errors about not finding a configuration that matches.
- ret += fmt.Sprintf("%s\"%s\": %s,\n", makeIndent(indent+1), bazel.ConditionsDefaultSelectKey, defaultValue)
- } else {
+ if s != "" {
// Print the custom default value.
ret += s
ret += ",\n"
+ } else if defaultValue != nil {
+ // Print an explicit empty list (the default value) even if the value is
+ // empty, to avoid errors about not finding a configuration that matches.
+ ret += fmt.Sprintf("%s\"%s\": %s,\n", makeIndent(indent+1), bazel.ConditionsDefaultSelectKey, *defaultValue)
}
ret += makeIndent(indent)
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 752d43b..211fe5e 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -489,6 +489,7 @@
dynamicDeps bazel.LabelListAttribute
wholeArchiveDeps bazel.LabelListAttribute
exportedDeps bazel.LabelListAttribute
+ useLibcrt bazel.BoolAttribute
linkopts bazel.StringListAttribute
versionScript bazel.LabelAttribute
}
@@ -512,6 +513,7 @@
var wholeArchiveDeps bazel.LabelListAttribute
var linkopts bazel.StringListAttribute
var versionScript bazel.LabelAttribute
+ var useLibcrt bazel.BoolAttribute
for _, linkerProps := range module.linker.linkerProps() {
if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
@@ -535,6 +537,7 @@
if baseLinkerProps.Version_script != nil {
versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
}
+ useLibcrt.Value = baseLinkerProps.libCrt()
break
}
@@ -559,6 +562,7 @@
if baseLinkerProps.Version_script != nil {
versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
}
+ useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
}
}
}
@@ -624,6 +628,7 @@
dynamicDeps: dynamicDeps,
wholeArchiveDeps: wholeArchiveDeps,
linkopts: linkopts,
+ useLibcrt: useLibcrt,
versionScript: versionScript,
}
}
diff --git a/cc/cc.go b/cc/cc.go
index d22c9da..555cb6c 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1970,9 +1970,13 @@
if minSdkVersion == "" || minSdkVersion == "apex_inherit" {
minSdkVersion = m.SdkVersion()
}
+ apiLevel, err := android.ApiLevelFromUser(ctx, minSdkVersion)
+ if err != nil {
+ ctx.PropertyErrorf("min_sdk_version", err.Error())
+ }
return []blueprint.Variation{
{Mutator: "sdk", Variation: "sdk"},
- {Mutator: "version", Variation: minSdkVersion},
+ {Mutator: "version", Variation: apiLevel.String()},
}
}
return []blueprint.Variation{
diff --git a/cc/library.go b/cc/library.go
index 548dd5d..93bd56c 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -234,6 +234,7 @@
Whole_archive_deps bazel.LabelListAttribute
Includes bazel.StringListAttribute
Linkopts bazel.StringListAttribute
+ Use_libcrt bazel.BoolAttribute
// Attributes pertaining to shared variant.
Shared_srcs bazel.LabelListAttribute
@@ -320,6 +321,7 @@
Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
Includes: exportedIncludes,
Linkopts: linkerAttrs.linkopts,
+ Use_libcrt: linkerAttrs.useLibcrt,
Shared_srcs: sharedAttrs.srcs,
Shared_srcs_c: sharedAttrs.srcs_c,
@@ -2260,6 +2262,7 @@
Whole_archive_deps bazel.LabelListAttribute
Linkopts bazel.StringListAttribute
Linkstatic bool
+ Use_libcrt bazel.BoolAttribute
Includes bazel.StringListAttribute
Hdrs bazel.LabelListAttribute
@@ -2296,6 +2299,7 @@
Linkopts: linkerAttrs.linkopts,
Linkstatic: true,
+ Use_libcrt: linkerAttrs.useLibcrt,
Includes: exportedIncludes,
Cppflags: compilerAttrs.cppFlags,
diff --git a/cc/linker.go b/cc/linker.go
index 1d8c649..895931a 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -200,6 +200,18 @@
Exclude_shared_libs []string `android:"arch_variant"`
}
+func invertBoolPtr(value *bool) *bool {
+ if value == nil {
+ return nil
+ }
+ ret := !(*value)
+ return &ret
+}
+
+func (blp *BaseLinkerProperties) libCrt() *bool {
+ return invertBoolPtr(blp.No_libcrt)
+}
+
func NewBaseLinker(sanitize *sanitize) *baseLinker {
return &baseLinker{sanitize: sanitize}
}
diff --git a/java/rro.go b/java/rro.go
index 2e58c04..0b4d091 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -90,6 +90,22 @@
Theme() string
}
+// RRO's partition logic is different from the partition logic of other modules defined in soong/android/paths.go
+// The default partition for RRO is "/product" and not "/system"
+func rroPartition(ctx android.ModuleContext) string {
+ var partition string
+ if ctx.DeviceSpecific() {
+ partition = ctx.DeviceConfig().OdmPath()
+ } else if ctx.SocSpecific() {
+ partition = ctx.DeviceConfig().VendorPath()
+ } else if ctx.SystemExtSpecific() {
+ partition = ctx.DeviceConfig().SystemExtPath()
+ } else {
+ partition = ctx.DeviceConfig().ProductPath()
+ }
+ return partition
+}
+
func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) {
sdkDep := decodeSdkDep(ctx, android.SdkContext(r))
if sdkDep.hasFrameworkLibs() {
@@ -137,7 +153,8 @@
r.certificate = certificates[0]
r.outputFile = signed
- r.installDir = android.PathForModuleInstall(ctx, "overlay", String(r.properties.Theme))
+ partition := rroPartition(ctx)
+ r.installDir = android.PathForModuleInPartitionInstall(ctx, partition, "overlay", String(r.properties.Theme))
ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile)
}
diff --git a/java/rro_test.go b/java/rro_test.go
index bad60bc..27abbe4 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -177,7 +177,7 @@
// Check device location.
path = android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
- expectedPath = []string{shared.JoinPath("out/target/product/test_device/system/overlay")}
+ expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", config, expectedPath, path)
}
@@ -343,3 +343,57 @@
})
}
}
+
+func TestRuntimeResourceOverlayPartition(t *testing.T) {
+ bp := `
+ runtime_resource_overlay {
+ name: "device_specific",
+ device_specific: true,
+ }
+ runtime_resource_overlay {
+ name: "soc_specific",
+ soc_specific: true,
+ }
+ runtime_resource_overlay {
+ name: "system_ext_specific",
+ system_ext_specific: true,
+ }
+ runtime_resource_overlay {
+ name: "product_specific",
+ product_specific: true,
+ }
+ runtime_resource_overlay {
+ name: "default"
+ }
+ `
+ testCases := []struct {
+ name string
+ expectedPath string
+ }{
+ {
+ name: "device_specific",
+ expectedPath: "out/soong/target/product/test_device/odm/overlay",
+ },
+ {
+ name: "soc_specific",
+ expectedPath: "out/soong/target/product/test_device/vendor/overlay",
+ },
+ {
+ name: "system_ext_specific",
+ expectedPath: "out/soong/target/product/test_device/system_ext/overlay",
+ },
+ {
+ name: "product_specific",
+ expectedPath: "out/soong/target/product/test_device/product/overlay",
+ },
+ {
+ name: "default",
+ expectedPath: "out/soong/target/product/test_device/product/overlay",
+ },
+ }
+ for _, testCase := range testCases {
+ ctx, _ := testJava(t, bp)
+ mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
+ android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
+ }
+}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index ecf2b1a..9492729 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -435,9 +435,6 @@
// a list of top-level directories containing Java stub files to merge show/hide annotations from.
Merge_inclusion_annotations_dirs []string
- // If set to true, the path of dist files is apistubs/core. Defaults to false.
- Core_lib *bool
-
// If set to true then don't create dist rules.
No_dist *bool
@@ -458,7 +455,7 @@
Dist_stem *string
// The subdirectory for the artifacts that are copied to the dist directory. If not specified
- // then defaults to "android". Should be set to "android" for anything that should be published
+ // then defaults to "unknown". Should be set to "android" for anything that should be published
// in the public Android SDK.
Dist_group *string
@@ -1203,11 +1200,7 @@
// The dist path of the stub artifacts
func (module *SdkLibrary) apiDistPath(apiScope *apiScope) string {
- if Bool(module.sdkLibraryProperties.Core_lib) {
- return path.Join("apistubs", "core", apiScope.name)
- } else {
- return path.Join("apistubs", module.distGroup(), apiScope.name)
- }
+ return path.Join("apistubs", module.distGroup(), apiScope.name)
}
// Get the sdk version for use when compiling the stubs library.
@@ -1233,15 +1226,7 @@
// distGroup returns the subdirectory of the dist path of the stub artifacts.
func (module *SdkLibrary) distGroup() string {
- if group := proptools.String(module.sdkLibraryProperties.Dist_group); group != "" {
- return group
- }
- // TODO(b/186723288): Remove this once everything uses dist_group.
- if owner := module.ModuleBase.Owner(); owner != "" {
- return owner
- }
- // TODO(b/186723288): Make this "unknown".
- return "android"
+ return proptools.StringDefault(module.sdkLibraryProperties.Dist_group, "unknown")
}
func (module *SdkLibrary) latestApiFilegroupName(apiScope *apiScope) string {
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 0fe6e72..2520dde 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -844,40 +844,34 @@
PrepareForTestWithJavaBuildComponents,
PrepareForTestWithJavaDefaultModules,
PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis(
+ "sdklib_no_group",
+ "sdklib_group_foo",
+ "sdklib_owner_foo",
+ "foo"),
).RunTestWithBp(t, `
java_sdk_library {
- name: "sdklib_no_owner",
- unsafe_ignore_missing_latest_api: true,
+ name: "sdklib_no_group",
srcs: ["foo.java"],
}
java_sdk_library {
name: "sdklib_group_foo",
- unsafe_ignore_missing_latest_api: true,
srcs: ["foo.java"],
dist_group: "foo",
}
java_sdk_library {
name: "sdklib_owner_foo",
- unsafe_ignore_missing_latest_api: true,
srcs: ["foo.java"],
owner: "foo",
}
java_sdk_library {
name: "sdklib_stem_foo",
- unsafe_ignore_missing_latest_api: true,
srcs: ["foo.java"],
dist_stem: "foo",
}
-
- java_sdk_library {
- name: "sdklib_core_lib",
- unsafe_ignore_missing_latest_api: true,
- srcs: ["foo.java"],
- core_lib: true,
- }
`)
type testCase struct {
@@ -887,9 +881,9 @@
}
testCases := []testCase{
{
- module: "sdklib_no_owner",
- distDir: "apistubs/android/public",
- distStem: "sdklib_no_owner.jar",
+ module: "sdklib_no_group",
+ distDir: "apistubs/unknown/public",
+ distStem: "sdklib_no_group.jar",
},
{
module: "sdklib_group_foo",
@@ -897,20 +891,16 @@
distStem: "sdklib_group_foo.jar",
},
{
+ // Owner doesn't affect distDir after b/186723288.
module: "sdklib_owner_foo",
- distDir: "apistubs/foo/public",
+ distDir: "apistubs/unknown/public",
distStem: "sdklib_owner_foo.jar",
},
{
module: "sdklib_stem_foo",
- distDir: "apistubs/android/public",
+ distDir: "apistubs/unknown/public",
distStem: "foo.jar",
},
- {
- module: "sdklib_core_lib",
- distDir: "apistubs/core/public",
- distStem: "sdklib_core_lib.jar",
- },
}
for _, tt := range testCases {
diff --git a/scripts/build-aml-prebuilts.sh b/scripts/build-aml-prebuilts.sh
index 4b08ac3..8a5513e 100755
--- a/scripts/build-aml-prebuilts.sh
+++ b/scripts/build-aml-prebuilts.sh
@@ -1,14 +1,24 @@
#!/bin/bash -e
-# This is a wrapper around "m" that builds the given modules in multi-arch mode
-# for all architectures supported by Mainline modules. The make (kati) stage is
-# skipped, so the build targets in the arguments can only be Soong modules or
-# intermediate output files - make targets and normal installed paths are not
-# supported.
+# This script is similar to "m" but builds in --soong-only mode, and handles
+# special cases to make that mode work. All arguments are passed on to
+# build/soong/soong_ui.bash.
#
-# This script is typically used with "sdk" or "module_export" modules, which
-# Soong will install in $OUT_DIR/soong/mainline-sdks (cf
-# PathForMainlineSdksInstall in android/paths.go).
+# --soong-only bypasses the kati step and hence the make logic that e.g. doesn't
+# handle more than two device architectures. It is particularly intended for use
+# with TARGET_PRODUCT=mainline_sdk to build 'sdk' and 'module_export' Soong
+# modules in TARGET_ARCH_SUITE=mainline_sdk mode so that they get all four
+# device architectures (artifacts get installed in $OUT_DIR/soong/mainline-sdks
+# - cf PathForMainlineSdksInstall in android/paths.go).
+#
+# TODO(b/174315599): Replace this script completely with a 'soong_ui.bash
+# --soong-only' invocation. For now it is still necessary to set up
+# build_number.txt.
+
+if [ ! -e build/soong/soong_ui.bash ]; then
+ echo "$0 must be run from the top of the tree"
+ exit 1
+fi
export OUT_DIR=${OUT_DIR:-out}
@@ -23,109 +33,19 @@
OUT_DIR=${AML_OUT_DIR}
fi
-if [ ! -e "build/envsetup.sh" ]; then
- echo "$0 must be run from the top of the tree"
- exit 1
-fi
+mkdir -p ${OUT_DIR}/soong
-source build/envsetup.sh
-
-my_get_build_var() {
- # get_build_var will run Soong in normal in-make mode where it creates
- # .soong.kati_enabled. That would clobber our real out directory, so we need
- # to run it in a different one.
- OUT_DIR=${OUT_DIR}/get_build_var get_build_var "$@"
-}
-
-readonly SOONG_OUT=${OUT_DIR}/soong
-mkdir -p ${SOONG_OUT}
+# The --dumpvars-mode invocation will run Soong in normal make mode where it
+# creates .soong.kati_enabled. That would clobber our real out directory, so we
+# need to use a different OUT_DIR.
+vars="$(OUT_DIR=${OUT_DIR}/dumpvars_mode build/soong/soong_ui.bash \
+ --dumpvars-mode --vars=BUILD_NUMBER)"
+# Assign to a variable and eval that, since bash ignores any error status
+# from the command substitution if it's directly on the eval line.
+eval $vars
# Some Soong build rules may require this, and the failure mode if it's missing
# is confusing (b/172548608).
-readonly BUILD_NUMBER="$(my_get_build_var BUILD_NUMBER)"
-echo -n ${BUILD_NUMBER} > ${SOONG_OUT}/build_number.txt
+echo -n ${BUILD_NUMBER} > ${OUT_DIR}/soong/build_number.txt
-readonly PLATFORM_SDK_VERSION="$(my_get_build_var PLATFORM_SDK_VERSION)"
-readonly PLATFORM_VERSION="$(my_get_build_var PLATFORM_VERSION)"
-PLATFORM_VERSION_ALL_CODENAMES="$(my_get_build_var PLATFORM_VERSION_ALL_CODENAMES)"
-
-# PLATFORM_VERSION_ALL_CODENAMES is a comma separated list like O,P. We need to
-# turn this into ["O","P"].
-PLATFORM_VERSION_ALL_CODENAMES="${PLATFORM_VERSION_ALL_CODENAMES/,/'","'}"
-PLATFORM_VERSION_ALL_CODENAMES="[\"${PLATFORM_VERSION_ALL_CODENAMES}\"]"
-
-# Get the list of missing <uses-library> modules and convert it to a JSON array
-# (quote module names, add comma separator and wrap in brackets).
-MISSING_USES_LIBRARIES="$(my_get_build_var INTERNAL_PLATFORM_MISSING_USES_LIBRARIES)"
-MISSING_USES_LIBRARIES="[$(echo $MISSING_USES_LIBRARIES | sed -e 's/\([^ ]\+\)/\"\1\"/g' -e 's/[ ]\+/, /g')]"
-
-# Logic from build/make/core/goma.mk
-if [ "${USE_GOMA}" = true ]; then
- if [ -n "${GOMA_DIR}" ]; then
- goma_dir="${GOMA_DIR}"
- else
- goma_dir="${HOME}/goma"
- fi
- GOMA_CC="${goma_dir}/gomacc"
- export CC_WRAPPER="${CC_WRAPPER}${CC_WRAPPER:+ }${GOMA_CC}"
- export CXX_WRAPPER="${CXX_WRAPPER}${CXX_WRAPPER:+ }${GOMA_CC}"
- export JAVAC_WRAPPER="${JAVAC_WRAPPER}${JAVAC_WRAPPER:+ }${GOMA_CC}"
-else
- USE_GOMA=false
-fi
-
-readonly SOONG_VARS=${SOONG_OUT}/soong.variables
-
-# Aml_abis: true
-# - This flag configures Soong to compile for all architectures required for
-# Mainline modules.
-# CrossHost: linux_bionic
-# CrossHostArch: x86_64
-# - Enable Bionic on host as ART needs prebuilts for it.
-# VendorVars.art_mdoule.source_build
-# - TODO(b/172480615): Change default to false when platform uses ART Module
-# prebuilts by default.
-cat > ${SOONG_VARS}.new << EOF
-{
- "BuildNumberFile": "build_number.txt",
-
- "Platform_version_name": "${PLATFORM_VERSION}",
- "Platform_sdk_version": ${PLATFORM_SDK_VERSION},
- "Platform_sdk_codename": "${PLATFORM_VERSION}",
- "Platform_version_active_codenames": ${PLATFORM_VERSION_ALL_CODENAMES},
-
- "DeviceName": "generic_arm64",
- "HostArch": "x86_64",
- "HostSecondaryArch": "x86",
- "CrossHost": "linux_bionic",
- "CrossHostArch": "x86_64",
- "Aml_abis": true,
-
- "Allow_missing_dependencies": ${SOONG_ALLOW_MISSING_DEPENDENCIES:-false},
- "Unbundled_build": ${TARGET_BUILD_UNBUNDLED:-false},
- "UseGoma": ${USE_GOMA},
-
- "VendorVars": {
- "art_module": {
- "source_build": "${ENABLE_ART_SOURCE_BUILD:-true}"
- }
- },
-
- "MissingUsesLibraries": ${MISSING_USES_LIBRARIES}
-}
-EOF
-
-if [ -f ${SOONG_VARS} ] && cmp -s ${SOONG_VARS} ${SOONG_VARS}.new; then
- # Don't touch soong.variables if we don't have to, to avoid Soong rebuilding
- # the ninja file when it isn't necessary.
- rm ${SOONG_VARS}.new
-else
- mv ${SOONG_VARS}.new ${SOONG_VARS}
-fi
-
-# We use force building LLVM components flag (even though we actually don't
-# compile them) because we don't have bionic host prebuilts
-# for them.
-export FORCE_BUILD_LLVM_COMPONENTS=true
-
-m --skip-make "$@"
+build/soong/soong_ui.bash --make-mode --soong-only "$@"
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index 39c8fba..7d49492 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -93,11 +93,17 @@
done
done
+# We use force building LLVM components flag (even though we actually don't
+# compile them) because we don't have bionic host prebuilts
+# for them.
+export FORCE_BUILD_LLVM_COMPONENTS=true
+
# Create multi-archs SDKs in a different out directory. The multi-arch script
# uses Soong in --skip-make mode which cannot use the same directory as normal
# mode with make.
export OUT_DIR=${OUT_DIR}/aml
-echo_and_run build/soong/scripts/build-aml-prebuilts.sh ${MODULES_SDK_AND_EXPORTS[@]}
+echo_and_run build/soong/scripts/build-aml-prebuilts.sh \
+ TARGET_PRODUCT=mainline_sdk ${MODULES_SDK_AND_EXPORTS[@]}
rm -rf ${DIST_DIR}/mainline-sdks
echo_and_run cp -R ${OUT_DIR}/soong/mainline-sdks ${DIST_DIR}