Merge "Bp2build: handle embedded structs as blueprint"
diff --git a/android/androidmk.go b/android/androidmk.go
index 9853d2c..967c550 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -845,7 +845,7 @@
case "*selinux.selinuxContextsModule": // license properties written
case "*sysprop.syspropLibrary": // license properties written
default:
- if ctx.Config().IsEnvTrue("ANDROID_REQUIRE_LICENSES") {
+ if !ctx.Config().IsEnvFalse("ANDROID_REQUIRE_LICENSES") {
return fmt.Errorf("custom make rules not allowed for %q (%q) module %q", ctx.ModuleType(mod), reflect.TypeOf(mod), ctx.ModuleName(mod))
}
}
diff --git a/android/bazel.go b/android/bazel.go
index 373e292..22846e8 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -175,6 +175,7 @@
"system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively,
"system/libbase": Bp2BuildDefaultTrueRecursively,
"system/logging/liblog": Bp2BuildDefaultTrueRecursively,
+ "system/sepolicy/apex": Bp2BuildDefaultTrueRecursively,
"system/timezone/apex": Bp2BuildDefaultTrueRecursively,
"system/timezone/output_data": Bp2BuildDefaultTrueRecursively,
"external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively,
diff --git a/android/config.go b/android/config.go
index 0767e7b..993aaa7 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1531,6 +1531,10 @@
c.config.productVariables.RecoverySnapshotDirsIncluded)
}
+func (c *deviceConfig) HostFakeSnapshotEnabled() bool {
+ return c.config.productVariables.HostFakeSnapshotEnabled
+}
+
func (c *deviceConfig) ShippingApiLevel() ApiLevel {
if c.config.productVariables.ShippingApiLevel == nil {
return NoneApiLevel
@@ -1655,6 +1659,20 @@
return ConfiguredJarList{apexes, jars}
}
+// Append a list of (apex, jar) pairs to the list.
+func (l *ConfiguredJarList) AppendList(other ConfiguredJarList) ConfiguredJarList {
+ apexes := make([]string, 0, l.Len()+other.Len())
+ jars := make([]string, 0, l.Len()+other.Len())
+
+ apexes = append(apexes, l.apexes...)
+ jars = append(jars, l.jars...)
+
+ apexes = append(apexes, other.apexes...)
+ jars = append(jars, other.jars...)
+
+ return ConfiguredJarList{apexes, jars}
+}
+
// RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs.
func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList {
apexes := make([]string, 0, l.Len())
diff --git a/android/defs.go b/android/defs.go
index b3ff376..c8e2e9b 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -188,6 +188,15 @@
buildWriteFileRule(ctx, outputFile, content)
}
+func CatFileRule(ctx BuilderContext, paths Paths, outputFile WritablePath) {
+ ctx.Build(pctx, BuildParams{
+ Rule: Cat,
+ Inputs: paths,
+ Output: outputFile,
+ Description: "combine files to " + outputFile.Base(),
+ })
+}
+
// shellUnescape reverses proptools.ShellEscape
func shellUnescape(s string) string {
// Remove leading and trailing quotes if present
diff --git a/android/licenses.go b/android/licenses.go
index d54f8f4..7ee78c7 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -253,7 +253,7 @@
primaryProperty := module.base().primaryLicensesProperty
if primaryProperty == nil {
- if ctx.Config().IsEnvTrue("ANDROID_REQUIRE_LICENSES") {
+ if !ctx.Config().IsEnvFalse("ANDROID_REQUIRE_LICENSES") {
ctx.ModuleErrorf("module type %q must have an applicable licenses property", ctx.OtherModuleType(module))
}
return nil
diff --git a/android/prebuilt.go b/android/prebuilt.go
index e611502..e189892 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -240,7 +240,7 @@
value = value.Elem()
}
if value.Kind() != reflect.String {
- panic(fmt.Errorf("prebuilt src field %q should be a string or a pointer to one but was %d %q", srcPropertyName, value.Kind(), value))
+ panic(fmt.Errorf("prebuilt src field %q in %T in module %s should be a string or a pointer to one but was %v", srcField, srcProps, module, value))
}
src := value.String()
if src == "" {
diff --git a/android/testing.go b/android/testing.go
index e25e5c5..bd2faa2 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -509,12 +509,11 @@
allVariants = append(allVariants, ctx.ModuleSubDir(m))
}
})
- sort.Strings(allModuleNames)
sort.Strings(allVariants)
if len(allVariants) == 0 {
panic(fmt.Errorf("failed to find module %q. All modules:\n %s",
- name, strings.Join(allModuleNames, "\n ")))
+ name, strings.Join(SortedUniqueStrings(allModuleNames), "\n ")))
} else {
panic(fmt.Errorf("failed to find module %q variant %q. All variants:\n %s",
name, variant, strings.Join(allVariants, "\n ")))
diff --git a/android/variable.go b/android/variable.go
index a1af527..a308d2b 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -333,6 +333,7 @@
VendorSnapshotDirsExcluded []string `json:",omitempty"`
RecoverySnapshotDirsExcluded []string `json:",omitempty"`
RecoverySnapshotDirsIncluded []string `json:",omitempty"`
+ HostFakeSnapshotEnabled bool `json:",omitempty"`
BoardVendorSepolicyDirs []string `json:",omitempty"`
BoardOdmSepolicyDirs []string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index e3edc68..2d153e2 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1569,6 +1569,11 @@
af.jacocoReportClassesFile = module.JacocoReportClassesFile()
af.lintDepSets = module.LintDepSets()
af.customStem = module.Stem() + ".jar"
+ if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
+ for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
+ af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
+ }
+ }
return af
}
diff --git a/apex/builder.go b/apex/builder.go
index 3177ee0..6df40f4 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -17,7 +17,6 @@
import (
"encoding/json"
"fmt"
- "path"
"path/filepath"
"runtime"
"sort"
@@ -256,14 +255,24 @@
// labeled as system_file.
func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) android.OutputPath {
var fileContexts android.Path
+ var fileContextsDir string
if a.properties.File_contexts == nil {
fileContexts = android.PathForSource(ctx, "system/sepolicy/apex", ctx.ModuleName()+"-file_contexts")
} else {
+ if m, t := android.SrcIsModuleWithTag(*a.properties.File_contexts); m != "" {
+ otherModule := android.GetModuleFromPathDep(ctx, m, t)
+ fileContextsDir = ctx.OtherModuleDir(otherModule)
+ }
fileContexts = android.PathForModuleSrc(ctx, *a.properties.File_contexts)
}
+ if fileContextsDir == "" {
+ fileContextsDir = filepath.Dir(fileContexts.String())
+ }
+ fileContextsDir += string(filepath.Separator)
+
if a.Platform() {
- if matched, err := path.Match("system/sepolicy/**/*", fileContexts.String()); err != nil || !matched {
- ctx.PropertyErrorf("file_contexts", "should be under system/sepolicy, but %q", fileContexts)
+ if !strings.HasPrefix(fileContextsDir, "system/sepolicy/") {
+ ctx.PropertyErrorf("file_contexts", "should be under system/sepolicy, but found in %q", fileContextsDir)
}
}
if !android.ExistentPathForSource(ctx, fileContexts.String()).Valid() {
diff --git a/bazel/properties.go b/bazel/properties.go
index 1a846ba..ed4e9fc 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -743,6 +743,31 @@
return keys
}
+// DeduplicateAxesFromBase ensures no duplication of items between the no-configuration value and
+// configuration-specific values. For example, if we would convert this StringListAttribute as:
+// ["a", "b", "c"] + select({
+// "//condition:one": ["a", "d"],
+// "//conditions:default": [],
+// })
+// after this function, we would convert this StringListAttribute as:
+// ["a", "b", "c"] + select({
+// "//condition:one": ["d"],
+// "//conditions:default": [],
+// })
+func (sla *StringListAttribute) DeduplicateAxesFromBase() {
+ base := sla.Value
+ for axis, configToList := range sla.ConfigurableValues {
+ for config, list := range configToList {
+ remaining := SubtractStrings(list, base)
+ if len(remaining) == 0 {
+ delete(sla.ConfigurableValues[axis], config)
+ } else {
+ sla.ConfigurableValues[axis][config] = remaining
+ }
+ }
+ }
+}
+
// TryVariableSubstitution, replace string substitution formatting within each string in slice with
// Starlark string.format compatible tag for productVariable.
func TryVariableSubstitutions(slice []string, productVariable string) ([]string, bool) {
diff --git a/bazel/properties_test.go b/bazel/properties_test.go
index 9464245..85596e2 100644
--- a/bazel/properties_test.go
+++ b/bazel/properties_test.go
@@ -293,3 +293,74 @@
}
}
}
+
+func TestDeduplicateAxesFromBase(t *testing.T) {
+ attr := StringListAttribute{
+ Value: []string{
+ "all_include",
+ "arm_include",
+ "android_include",
+ "linux_x86_include",
+ },
+ ConfigurableValues: configurableStringLists{
+ ArchConfigurationAxis: stringListSelectValues{
+ "arm": []string{"arm_include"},
+ "x86": []string{"x86_include"},
+ },
+ OsConfigurationAxis: stringListSelectValues{
+ "android": []string{"android_include"},
+ "linux": []string{"linux_include"},
+ },
+ OsArchConfigurationAxis: stringListSelectValues{
+ "linux_x86": {"linux_x86_include"},
+ },
+ ProductVariableConfigurationAxis("a"): stringListSelectValues{
+ "a": []string{"not_in_value"},
+ },
+ },
+ }
+
+ attr.DeduplicateAxesFromBase()
+
+ expectedBaseIncludes := []string{
+ "all_include",
+ "arm_include",
+ "android_include",
+ "linux_x86_include",
+ }
+ if !reflect.DeepEqual(expectedBaseIncludes, attr.Value) {
+ t.Errorf("Expected Value includes %q, got %q", attr.Value, expectedBaseIncludes)
+ }
+ expectedConfiguredIncludes := configurableStringLists{
+ ArchConfigurationAxis: stringListSelectValues{
+ "x86": []string{"x86_include"},
+ },
+ OsConfigurationAxis: stringListSelectValues{
+ "linux": []string{"linux_include"},
+ },
+ OsArchConfigurationAxis: stringListSelectValues{},
+ ProductVariableConfigurationAxis("a"): stringListSelectValues{
+ "a": []string{"not_in_value"},
+ },
+ }
+ for _, axis := range attr.SortedConfigurationAxes() {
+ if _, ok := expectedConfiguredIncludes[axis]; !ok {
+ t.Errorf("Found unexpected axis %s", axis)
+ continue
+ }
+ expectedForAxis := expectedConfiguredIncludes[axis]
+ gotForAxis := attr.ConfigurableValues[axis]
+ if len(expectedForAxis) != len(gotForAxis) {
+ t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
+ }
+ for config, value := range gotForAxis {
+ if expected, ok := expectedForAxis[config]; ok {
+ if !reflect.DeepEqual(expected, value) {
+ t.Errorf("For %s, expected: %#v, got %#v", axis, expected, value)
+ }
+ } else {
+ t.Errorf("Got unexpected config %q for %s", config, axis)
+ }
+ }
+ }
+}
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index c840016..371593b 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: "",
}`
)
@@ -113,17 +113,14 @@
srcs: ["bionic.cpp"]
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "foo-lib",
- copts = [
- "-Wall",
- "-I.",
- "-I$(BINDIR)/.",
- ],
+ copts = ["-Wall"],
+ export_includes = ["foo-dir"],
implementation_deps = [":some-headers"],
- includes = ["foo-dir"],
linkopts = ["-Wl,--exclude-libs=bar.a"] + select({
"//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=baz.a"],
"//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=qux.a"],
@@ -186,6 +183,7 @@
ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
@@ -195,8 +193,6 @@
"-Wextra",
"-Wunused",
"-Werror",
- "-I.",
- "-I$(BINDIR)/.",
],
implementation_deps = [":libc_headers"],
linkopts = [
@@ -259,13 +255,11 @@
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "fake-libarm-optimized-routines-math",
- copts = [
- "-Iexternal",
- "-I$(BINDIR)/external",
- ] + select({
+ copts = select({
"//build/bazel/platforms/arch:arm64": ["-DHAVE_FAST_FMA=1"],
"//conditions:default": [],
}),
+ local_includes = ["."],
srcs_c = ["math/cosf.c"],
)`},
})
@@ -277,12 +271,12 @@
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- dir: "foo/bar",
filesystem: map[string]string{
- "foo/bar/both.cpp": "",
- "foo/bar/sharedonly.cpp": "",
- "foo/bar/staticonly.cpp": "",
- "foo/bar/Android.bp": `
+ "both.cpp": "",
+ "sharedonly.cpp": "",
+ "staticonly.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
cc_library {
name: "a",
srcs: ["both.cpp"],
@@ -304,36 +298,57 @@
static_libs: ["static_dep_for_shared"],
whole_static_libs: ["whole_static_lib_for_shared"],
},
- bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}
-cc_library_static { name: "static_dep_for_shared" }
+cc_library_static {
+ name: "static_dep_for_shared",
+ bazel_module: { bp2build_available: false },
+}
-cc_library_static { name: "static_dep_for_static" }
+cc_library_static {
+ name: "static_dep_for_static",
+ bazel_module: { bp2build_available: false },
+}
-cc_library_static { name: "static_dep_for_both" }
+cc_library_static {
+ name: "static_dep_for_both",
+ bazel_module: { bp2build_available: false },
+}
-cc_library_static { name: "whole_static_lib_for_shared" }
+cc_library_static {
+ name: "whole_static_lib_for_shared",
+ bazel_module: { bp2build_available: false },
+}
-cc_library_static { name: "whole_static_lib_for_static" }
+cc_library_static {
+ name: "whole_static_lib_for_static",
+ bazel_module: { bp2build_available: false },
+}
-cc_library_static { name: "whole_static_lib_for_both" }
+cc_library_static {
+ name: "whole_static_lib_for_both",
+ bazel_module: { bp2build_available: false },
+}
-cc_library { name: "shared_dep_for_shared" }
+cc_library {
+ name: "shared_dep_for_shared",
+ bazel_module: { bp2build_available: false },
+}
-cc_library { name: "shared_dep_for_static" }
+cc_library {
+ name: "shared_dep_for_static",
+ bazel_module: { bp2build_available: false },
+}
-cc_library { name: "shared_dep_for_both" }
+cc_library {
+ name: "shared_dep_for_both",
+ bazel_module: { bp2build_available: false },
+}
`,
- },
- blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = [
- "bothflag",
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
+ copts = ["bothflag"],
dynamic_deps = [":shared_dep_for_both"],
implementation_deps = [":static_dep_for_both"],
shared = {
@@ -374,6 +389,7 @@
whole_static_libs: ["whole_static_lib_for_shared"],
},
bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}
cc_prebuilt_library_static { name: "whole_static_lib_for_shared" }
@@ -386,10 +402,6 @@
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
shared = {
"whole_archive_deps": [":whole_static_lib_for_shared_alwayslink"],
},
@@ -480,12 +492,9 @@
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = [
- "bothflag",
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
+ copts = ["bothflag"],
implementation_deps = [":static_dep_for_both"],
+ local_includes = ["."],
shared = {
"copts": ["sharedflag"] + select({
"//build/bazel/platforms/arch:arm": ["-DARM_SHARED"],
@@ -574,24 +583,24 @@
":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 },
}
@@ -621,14 +630,7 @@
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- asflags = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
+ local_includes = ["."],
shared = {
"srcs": [
":shared_filegroup_cpp_srcs",
@@ -693,16 +695,13 @@
srcs: ["a.cpp"],
version_script: "v.map",
bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}
`,
},
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
srcs = ["a.cpp"],
version_script = "v.map",
)`},
@@ -718,29 +717,26 @@
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 },
+ include_build_directory: false,
+}
`,
},
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
srcs = ["a.cpp"],
version_script = select({
"//build/bazel/platforms/arch:arm": "arm.map",
@@ -757,35 +753,21 @@
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `
+ blueprint: soongCcLibraryPreamble + `
cc_library {
name: "mylib",
- bazel_module: { bp2build_available: true },
+ bazel_module: { bp2build_available: false },
}
cc_library {
name: "a",
shared_libs: ["mylib",],
- bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}
`,
- },
- blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
dynamic_deps = [":mylib"],
-)`, `cc_library(
- name = "mylib",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
)`},
})
}
@@ -796,14 +778,12 @@
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `
+ blueprint: soongCcLibraryPreamble + `
cc_library {
name: "a",
srcs: ["a.cpp"],
pack_relocations: false,
- bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}
cc_library {
@@ -811,10 +791,10 @@
srcs: ["b.cpp"],
arch: {
x86_64: {
- pack_relocations: false,
- },
+ pack_relocations: false,
+ },
},
- bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}
cc_library {
@@ -822,27 +802,17 @@
srcs: ["c.cpp"],
target: {
darwin: {
- pack_relocations: false,
- },
+ pack_relocations: false,
+ },
},
- bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}`,
- },
- blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
linkopts = ["-Wl,--pack-dyn-relocs=none"],
srcs = ["a.cpp"],
)`, `cc_library(
name = "b",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
linkopts = select({
"//build/bazel/platforms/arch:x86_64": ["-Wl,--pack-dyn-relocs=none"],
"//conditions:default": [],
@@ -850,10 +820,6 @@
srcs = ["b.cpp"],
)`, `cc_library(
name = "c",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
linkopts = select({
"//build/bazel/platforms/os:darwin": ["-Wl,--pack-dyn-relocs=none"],
"//conditions:default": [],
@@ -869,24 +835,18 @@
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `
+ blueprint: soongCcLibraryPreamble + `
cc_library {
name: "a",
cflags: ["-include header.h",],
- bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}
`,
- },
- blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
copts = [
"-include",
"header.h",
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
],
)`},
})
@@ -898,40 +858,30 @@
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `cc_library {
+ blueprint: soongCcLibraryPreamble + `cc_library {
name: "a",
srcs: ["a.cpp"],
- cflags: [
- "-Wall",
- ],
+ cflags: ["-Wall"],
cppflags: [
"-fsigned-char",
"-pedantic",
- ],
+ ],
arch: {
arm64: {
cppflags: ["-DARM64=1"],
+ },
},
- },
target: {
android: {
cppflags: ["-DANDROID=1"],
+ },
},
- },
- bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}
`,
- },
- blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = [
- "-Wall",
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
+ copts = ["-Wall"],
cppflags = [
"-fsigned-char",
"-pedantic",
@@ -953,32 +903,23 @@
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- 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",
- },
- },
-
- bazel_module: { bp2build_available: true },
- }
+ blueprint: soongCcLibraryPreamble + `
+cc_library {
+ name: "a",
+ srcs: ["a.cpp"],
+ target: {
+ android_arm: {
+ version_script: "android_arm.map",
+ },
+ linux_bionic_arm64: {
+ version_script: "linux_bionic_arm64.map",
+ },
+ },
+ include_build_directory: false,
+}
`,
- },
- blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
srcs = ["a.cpp"],
version_script = select({
"//build/bazel/platforms/os_arch:android_arm": "android_arm.map",
@@ -1031,6 +972,7 @@
],
},
},
+ include_build_directory: false,
}
cc_library {
@@ -1071,10 +1013,6 @@
expectedBazelTargets: []string{
`cc_library(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
dynamic_deps = select({
"//build/bazel/platforms/arch:arm": [],
"//conditions:default": [":arm_shared_lib_excludes"],
@@ -1117,14 +1055,11 @@
name: "foo-lib",
srcs: ["impl.cpp"],
no_libcrt: true,
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "foo-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
srcs = ["impl.cpp"],
use_libcrt = False,
)`}})
@@ -1144,14 +1079,11 @@
name: "foo-lib",
srcs: ["impl.cpp"],
no_libcrt: false,
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "foo-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
srcs = ["impl.cpp"],
use_libcrt = True,
)`}})
@@ -1166,7 +1098,6 @@
"impl.cpp": "",
},
blueprint: soongCcLibraryPreamble + `
-cc_library_headers { name: "some-headers" }
cc_library {
name: "foo-lib",
srcs: ["impl.cpp"],
@@ -1178,14 +1109,11 @@
no_libcrt: true,
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "foo-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
srcs = ["impl.cpp"],
use_libcrt = select({
"//build/bazel/platforms/arch:arm": False,
@@ -1204,7 +1132,6 @@
"impl.cpp": "",
},
blueprint: soongCcLibraryPreamble + `
-cc_library_headers { name: "some-headers" }
cc_library {
name: "foo-lib",
srcs: ["impl.cpp"],
@@ -1217,14 +1144,11 @@
no_libcrt: true,
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "foo-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
srcs = ["impl.cpp"],
use_libcrt = select({
"//build/bazel/platforms/arch:arm": False,
@@ -1240,102 +1164,74 @@
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `
+ blueprint: soongCcLibraryPreamble + `
cc_library {
name: "nothing",
- bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}
cc_library {
name: "keep_symbols",
- bazel_module: { bp2build_available: true },
strip: {
- keep_symbols: true,
- }
+ keep_symbols: true,
+ },
+ include_build_directory: false,
}
cc_library {
name: "keep_symbols_and_debug_frame",
- bazel_module: { bp2build_available: true },
strip: {
- keep_symbols_and_debug_frame: true,
- }
+ keep_symbols_and_debug_frame: true,
+ },
+ include_build_directory: false,
}
cc_library {
name: "none",
- bazel_module: { bp2build_available: true },
strip: {
- none: true,
- }
+ none: true,
+ },
+ include_build_directory: false,
}
cc_library {
name: "keep_symbols_list",
- bazel_module: { bp2build_available: true },
strip: {
- keep_symbols_list: ["symbol"],
- }
+ keep_symbols_list: ["symbol"],
+ },
+ include_build_directory: false,
}
cc_library {
name: "all",
- bazel_module: { bp2build_available: true },
strip: {
- all: true,
- }
+ all: true,
+ },
+ include_build_directory: false,
}
`,
- },
- blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "all",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
strip = {
"all": True,
},
)`, `cc_library(
name = "keep_symbols",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
strip = {
"keep_symbols": True,
},
)`, `cc_library(
name = "keep_symbols_and_debug_frame",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
strip = {
"keep_symbols_and_debug_frame": True,
},
)`, `cc_library(
name = "keep_symbols_list",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
strip = {
"keep_symbols_list": ["symbol"],
},
)`, `cc_library(
name = "none",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
strip = {
"none": True,
},
)`, `cc_library(
name = "nothing",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
)`},
})
}
@@ -1346,12 +1242,9 @@
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `
+ blueprint: soongCcLibraryPreamble + `
cc_library {
name: "multi-arch",
- bazel_module: { bp2build_available: true },
target: {
darwin: {
strip: {
@@ -1370,17 +1263,12 @@
keep_symbols: true,
},
},
- }
+ },
+ include_build_directory: false,
}
`,
- },
- blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "multi-arch",
- copts = [
- "-Ifoo/bar",
- "-I$(BINDIR)/foo/bar",
- ],
strip = {
"keep_symbols": select({
"//build/bazel/platforms/arch:arm64": True,
@@ -1411,15 +1299,12 @@
blueprint: soongCcLibraryPreamble + `
cc_library {
name: "root_empty",
- system_shared_libs: [],
+ system_shared_libs: [],
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "root_empty",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
system_dynamic_deps = [],
)`},
})
@@ -1435,16 +1320,13 @@
cc_library {
name: "static_empty",
static: {
- system_shared_libs: [],
- },
+ system_shared_libs: [],
+ },
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "static_empty",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
static = {
"system_dynamic_deps": [],
},
@@ -1462,16 +1344,13 @@
cc_library {
name: "shared_empty",
shared: {
- system_shared_libs: [],
- },
+ system_shared_libs: [],
+ },
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "shared_empty",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
shared = {
"system_dynamic_deps": [],
},
@@ -1494,15 +1373,12 @@
system_shared_libs: [],
}
}
- },
+ },
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "shared_empty",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
shared = {
"system_dynamic_deps": [],
},
@@ -1528,14 +1404,11 @@
system_shared_libs: [],
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "target_linux_bionic_empty",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
system_dynamic_deps = [],
)`},
})
@@ -1555,14 +1428,11 @@
system_shared_libs: [],
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "target_bionic_empty",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
system_dynamic_deps = [],
)`},
})
@@ -1575,39 +1445,30 @@
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
blueprint: soongCcLibraryPreamble + `
-cc_library {name: "libc"}
-cc_library {name: "libm"}
+cc_library {
+ name: "libc",
+ bazel_module: { bp2build_available: false },
+}
+cc_library {
+ name: "libm",
+ bazel_module: { bp2build_available: false },
+}
cc_library {
name: "foo",
system_shared_libs: ["libc"],
shared: {
- system_shared_libs: ["libm"],
+ system_shared_libs: ["libm"],
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library(
name = "foo",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
shared = {
"system_dynamic_deps": [":libm"],
},
system_dynamic_deps = [":libc"],
-)`, `cc_library(
- name = "libc",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
-)`, `cc_library(
- name = "libm",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
)`},
})
}
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index ea2c10a..37d806c 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -25,18 +25,18 @@
// See cc/testing.go for more context
soongCcLibraryHeadersPreamble = `
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: "",
}`
)
@@ -99,11 +99,13 @@
cc_library_headers {
name: "lib-1",
export_include_dirs: ["lib-1"],
+ bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "lib-2",
export_include_dirs: ["lib-2"],
+ bazel_module: { bp2build_available: false },
}
cc_library_headers {
@@ -113,7 +115,7 @@
arch: {
arm64: {
- // We expect dir-1 headers to be dropped, because dir-1 is already in export_include_dirs
+ // We expect dir-1 headers to be dropped, because dir-1 is already in export_include_dirs
export_include_dirs: ["arch_arm64_exported_include_dir", "dir-1"],
},
x86: {
@@ -128,15 +130,7 @@
}`,
expectedBazelTargets: []string{`cc_library_headers(
name = "foo_headers",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- implementation_deps = [
- ":lib-1",
- ":lib-2",
- ],
- includes = [
+ export_includes = [
"dir-1",
"dir-2",
] + select({
@@ -145,25 +139,15 @@
"//build/bazel/platforms/arch:x86_64": ["arch_x86_64_exported_include_dir"],
"//conditions:default": [],
}),
-)`, `cc_library_headers(
- name = "lib-1",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
+ implementation_deps = [
+ ":lib-1",
+ ":lib-2",
],
- includes = ["lib-1"],
-)`, `cc_library_headers(
- name = "lib-2",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- includes = ["lib-2"],
)`},
})
}
-func TestCcLibraryHeadersOSSpecificHeader(t *testing.T) {
+func TestCcLibraryHeadersOsSpecificHeader(t *testing.T) {
runCcLibraryHeadersTestCase(t, bp2buildTestCase{
description: "cc_library_headers test with os-specific header_libs props",
moduleTypeUnderTest: "cc_library_headers",
@@ -171,12 +155,30 @@
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
filesystem: map[string]string{},
blueprint: soongCcLibraryPreamble + `
-cc_library_headers { name: "android-lib" }
-cc_library_headers { name: "base-lib" }
-cc_library_headers { name: "darwin-lib" }
-cc_library_headers { name: "linux-lib" }
-cc_library_headers { name: "linux_bionic-lib" }
-cc_library_headers { name: "windows-lib" }
+cc_library_headers {
+ name: "android-lib",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_headers {
+ name: "base-lib",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_headers {
+ name: "darwin-lib",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_headers {
+ name: "linux-lib",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_headers {
+ name: "linux_bionic-lib",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_headers {
+ name: "windows-lib",
+ bazel_module: { bp2build_available: false },
+}
cc_library_headers {
name: "foo_headers",
header_libs: ["base-lib"],
@@ -187,32 +189,10 @@
linux_glibc: { header_libs: ["linux-lib"] },
windows: { header_libs: ["windows-lib"] },
},
- bazel_module: { bp2build_available: true },
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_headers(
- name = "android-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
-)`, `cc_library_headers(
- name = "base-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
-)`, `cc_library_headers(
- name = "darwin-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
-)`, `cc_library_headers(
name = "foo_headers",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
implementation_deps = [":base-lib"] + select({
"//build/bazel/platforms/os:android": [":android-lib"],
"//build/bazel/platforms/os:darwin": [":darwin-lib"],
@@ -221,24 +201,6 @@
"//build/bazel/platforms/os:windows": [":windows-lib"],
"//conditions:default": [],
}),
-)`, `cc_library_headers(
- name = "linux-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
-)`, `cc_library_headers(
- name = "linux_bionic-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
-)`, `cc_library_headers(
- name = "windows-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
)`},
})
}
@@ -251,32 +213,23 @@
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
filesystem: map[string]string{},
blueprint: soongCcLibraryPreamble + `
-cc_library_headers { name: "android-lib" }
-cc_library_headers { name: "exported-lib" }
+cc_library_headers {
+ name: "android-lib",
+ bazel_module: { bp2build_available: false },
+ }
+cc_library_headers {
+ name: "exported-lib",
+ bazel_module: { bp2build_available: false },
+}
cc_library_headers {
name: "foo_headers",
target: {
android: { header_libs: ["android-lib"], export_header_lib_headers: ["exported-lib"] },
},
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_headers(
- name = "android-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
-)`, `cc_library_headers(
- name = "exported-lib",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
-)`, `cc_library_headers(
name = "foo_headers",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
deps = select({
"//build/bazel/platforms/os:android": [":exported-lib"],
"//conditions:default": [],
@@ -299,14 +252,14 @@
blueprint: soongCcLibraryPreamble + `cc_library_headers {
name: "foo_headers",
export_system_include_dirs: [
- "shared_include_dir",
+ "shared_include_dir",
],
target: {
- android: {
- export_system_include_dirs: [
- "android_include_dir",
+ android: {
+ export_system_include_dirs: [
+ "android_include_dir",
],
- },
+ },
linux_glibc: {
export_system_include_dirs: [
"linux_include_dir",
@@ -320,24 +273,21 @@
},
arch: {
arm: {
- export_system_include_dirs: [
- "arm_include_dir",
+ export_system_include_dirs: [
+ "arm_include_dir",
],
- },
+ },
x86_64: {
export_system_include_dirs: [
"x86_64_include_dir",
],
},
},
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_headers(
name = "foo_headers",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- includes = ["shared_include_dir"] + select({
+ export_system_includes = ["shared_include_dir"] + select({
"//build/bazel/platforms/arch:arm": ["arm_include_dir"],
"//build/bazel/platforms/arch:x86_64": ["x86_64_include_dir"],
"//conditions:default": [],
@@ -375,14 +325,11 @@
name: "lib-1",
export_include_dirs: ["lib-1"],
no_libcrt: true,
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_headers(
name = "lib-1",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- includes = ["lib-1"],
+ export_includes = ["lib-1"],
)`},
})
}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index d9145f6..72034fa 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -26,18 +26,18 @@
// See cc/testing.go for more context
soongCcLibraryStaticPreamble = `
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: "",
}`
)
@@ -112,31 +112,37 @@
cc_library_headers {
name: "header_lib_1",
export_include_dirs: ["header_lib_1"],
+ bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "header_lib_2",
export_include_dirs: ["header_lib_2"],
+ bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_lib_1",
srcs: ["static_lib_1.cc"],
+ bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_lib_2",
srcs: ["static_lib_2.cc"],
+ bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "whole_static_lib_1",
srcs: ["whole_static_lib_1.cc"],
+ bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "whole_static_lib_2",
srcs: ["whole_static_lib_2.cc"],
+ bazel_module: { bp2build_available: false },
}
cc_library_static {
@@ -178,19 +184,17 @@
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
+ absolute_includes = [
+ "include_dir_1",
+ "include_dir_2",
+ ],
copts = [
"-Dflag1",
"-Dflag2",
- "-Iinclude_dir_1",
- "-I$(BINDIR)/include_dir_1",
- "-Iinclude_dir_2",
- "-I$(BINDIR)/include_dir_2",
- "-Ilocal_include_dir_1",
- "-I$(BINDIR)/local_include_dir_1",
- "-Ilocal_include_dir_2",
- "-I$(BINDIR)/local_include_dir_2",
- "-I.",
- "-I$(BINDIR)/.",
+ ],
+ export_includes = [
+ "export_include_dir_1",
+ "export_include_dir_2",
],
implementation_deps = [
":header_lib_1",
@@ -198,11 +202,12 @@
":static_lib_1",
":static_lib_2",
],
- includes = [
- "export_include_dir_1",
- "export_include_dir_2",
- ],
linkstatic = True,
+ local_includes = [
+ "local_include_dir_1",
+ "local_include_dir_2",
+ ".",
+ ],
srcs = [
"foo_static1.cc",
"foo_static2.cc",
@@ -211,38 +216,6 @@
":whole_static_lib_1",
":whole_static_lib_2",
],
-)`, `cc_library_static(
- name = "static_lib_1",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
- srcs = ["static_lib_1.cc"],
-)`, `cc_library_static(
- name = "static_lib_2",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
- srcs = ["static_lib_2.cc"],
-)`, `cc_library_static(
- name = "whole_static_lib_1",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
- srcs = ["whole_static_lib_1.cc"],
-)`, `cc_library_static(
- name = "whole_static_lib_2",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
- srcs = ["whole_static_lib_2.cc"],
)`},
})
}
@@ -270,21 +243,16 @@
blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
- srcs: [
- ],
+ srcs: [],
include_dirs: [
- "subpackage",
+ "subpackage",
],
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-Isubpackage",
- "-I$(BINDIR)/subpackage",
- "-I.",
- "-I$(BINDIR)/.",
- ],
+ absolute_includes = ["subpackage"],
linkstatic = True,
+ local_includes = ["."],
)`},
})
}
@@ -305,14 +273,11 @@
cc_library_static {
name: "foo_static",
export_include_dirs: ["subpackage"],
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- includes = ["subpackage"],
+ export_includes = ["subpackage"],
linkstatic = True,
)`},
})
@@ -334,14 +299,11 @@
cc_library_static {
name: "foo_static",
export_system_include_dirs: ["subpackage"],
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- includes = ["subpackage"],
+ export_system_includes = ["subpackage"],
linkstatic = True,
)`},
})
@@ -379,20 +341,17 @@
blueprint: soongCcLibraryStaticPreamble,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-Isubpackage/subsubpackage",
- "-I$(BINDIR)/subpackage/subsubpackage",
- "-Isubpackage2",
- "-I$(BINDIR)/subpackage2",
- "-Isubpackage3/subsubpackage",
- "-I$(BINDIR)/subpackage3/subsubpackage",
- "-Isubpackage/subsubpackage2",
- "-I$(BINDIR)/subpackage/subsubpackage2",
- "-Isubpackage",
- "-I$(BINDIR)/subpackage",
+ absolute_includes = [
+ "subpackage/subsubpackage",
+ "subpackage2",
+ "subpackage3/subsubpackage",
],
- includes = ["./exported_subsubpackage"],
+ export_includes = ["./exported_subsubpackage"],
linkstatic = True,
+ local_includes = [
+ "subsubpackage2",
+ ".",
+ ],
)`},
})
}
@@ -418,13 +377,9 @@
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-Isubpackage",
- "-I$(BINDIR)/subpackage",
- "-Isubpackage2",
- "-I$(BINDIR)/subpackage2",
- ],
+ absolute_includes = ["subpackage"],
linkstatic = True,
+ local_includes = ["subpackage2"],
)`},
})
}
@@ -452,15 +407,12 @@
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-Isubpackage",
- "-I$(BINDIR)/subpackage",
- "-Isubpackage2",
- "-I$(BINDIR)/subpackage2",
- "-I.",
- "-I$(BINDIR)/.",
- ],
+ absolute_includes = ["subpackage"],
linkstatic = True,
+ local_includes = [
+ "subpackage2",
+ ".",
+ ],
)`},
})
}
@@ -473,18 +425,21 @@
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
filesystem: map[string]string{},
blueprint: soongCcLibraryStaticPreamble + `
-cc_library_static { name: "static_dep" }
-cc_library_static { name: "static_dep2" }
+cc_library_static {
+ name: "static_dep",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_static {
+ name: "static_dep2",
+ bazel_module: { bp2build_available: false },
+}
cc_library_static {
name: "foo_static",
arch: { arm64: { static_libs: ["static_dep"], whole_static_libs: ["static_dep2"] } },
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
implementation_deps = select({
"//build/bazel/platforms/arch:arm64": [":static_dep"],
"//conditions:default": [],
@@ -494,20 +449,6 @@
"//build/bazel/platforms/arch:arm64": [":static_dep2"],
"//conditions:default": [],
}),
-)`, `cc_library_static(
- name = "static_dep",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
-)`, `cc_library_static(
- name = "static_dep2",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
)`},
})
}
@@ -520,18 +461,21 @@
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
filesystem: map[string]string{},
blueprint: soongCcLibraryStaticPreamble + `
-cc_library_static { name: "static_dep" }
-cc_library_static { name: "static_dep2" }
+cc_library_static {
+ name: "static_dep",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_static {
+ name: "static_dep2",
+ bazel_module: { bp2build_available: false },
+}
cc_library_static {
name: "foo_static",
target: { android: { static_libs: ["static_dep"], whole_static_libs: ["static_dep2"] } },
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
implementation_deps = select({
"//build/bazel/platforms/os:android": [":static_dep"],
"//conditions:default": [],
@@ -541,20 +485,6 @@
"//build/bazel/platforms/os:android": [":static_dep2"],
"//conditions:default": [],
}),
-)`, `cc_library_static(
- name = "static_dep",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
-)`, `cc_library_static(
- name = "static_dep2",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
)`},
})
}
@@ -567,23 +497,32 @@
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
filesystem: map[string]string{},
blueprint: soongCcLibraryStaticPreamble + `
-cc_library_static { name: "static_dep" }
-cc_library_static { name: "static_dep2" }
-cc_library_static { name: "static_dep3" }
-cc_library_static { name: "static_dep4" }
+cc_library_static {
+ name: "static_dep",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_static {
+ name: "static_dep2",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_static {
+ name: "static_dep3",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_static {
+ name: "static_dep4",
+ bazel_module: { bp2build_available: false },
+}
cc_library_static {
name: "foo_static",
static_libs: ["static_dep"],
whole_static_libs: ["static_dep2"],
target: { android: { static_libs: ["static_dep3"] } },
arch: { arm64: { static_libs: ["static_dep4"] } },
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
implementation_deps = [":static_dep"] + select({
"//build/bazel/platforms/arch:arm64": [":static_dep4"],
"//conditions:default": [],
@@ -593,34 +532,6 @@
}),
linkstatic = True,
whole_archive_deps = [":static_dep2"],
-)`, `cc_library_static(
- name = "static_dep",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
-)`, `cc_library_static(
- name = "static_dep2",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
-)`, `cc_library_static(
- name = "static_dep3",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
-)`, `cc_library_static(
- name = "static_dep4",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
)`},
})
}
@@ -641,13 +552,10 @@
name: "foo_static",
srcs: ["common.c", "foo-*.c"],
exclude_srcs: ["foo-excluded.c"],
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs_c = [
"common.c",
@@ -671,14 +579,11 @@
cc_library_static {
name: "foo_static",
srcs: ["common.c"],
- arch: { arm: { srcs: ["foo-arm.c"] } }
+ arch: { arm: { srcs: ["foo-arm.c"] } },
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": ["foo-arm.c"],
@@ -708,13 +613,10 @@
arch: {
arm: { srcs: ["for-arm.c"], exclude_srcs: ["not-for-arm.c"] },
},
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": ["for-arm.c"],
@@ -746,13 +648,10 @@
arm: { srcs: ["for-arm.c"], exclude_srcs: ["not-for-arm.c"] },
x86: { srcs: ["for-x86.c"], exclude_srcs: ["not-for-x86.c"] },
},
+ include_build_directory: false,
} `,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
@@ -799,14 +698,11 @@
arm64: { srcs: ["for-arm64.c"], exclude_srcs: ["not-for-arm64.c"] },
x86: { srcs: ["for-x86.c"], exclude_srcs: ["not-for-x86.c"] },
x86_64: { srcs: ["for-x86_64.c"], exclude_srcs: ["not-for-x86_64.c"] },
- },
+ },
+ include_build_directory: false,
} `,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
@@ -863,13 +759,10 @@
arch: {
arm: { exclude_srcs: ["foo-no-arm.cc"] },
},
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs = ["common.cc"] + select({
"//build/bazel/platforms/arch:arm": [],
@@ -900,13 +793,10 @@
arm: { exclude_srcs: ["foo-no-arm.cc"] },
x86: { srcs: ["x86-only.cc"] },
},
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs = ["common.cc"] + select({
"//build/bazel/platforms/arch:arm": [],
@@ -928,26 +818,19 @@
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
filesystem: map[string]string{},
blueprint: soongCcLibraryStaticPreamble + `
-cc_library_static { name: "static_dep" }
+cc_library_static {
+ name: "static_dep",
+ bazel_module: { bp2build_available: false },
+}
cc_library_static {
name: "foo_static",
static_libs: ["static_dep", "static_dep"],
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
implementation_deps = [":static_dep"],
linkstatic = True,
-)`, `cc_library_static(
- name = "static_dep",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
- linkstatic = True,
)`},
})
}
@@ -970,13 +853,10 @@
multilib: {
lib32: { srcs: ["for-lib32.c"], exclude_srcs: ["not-for-lib32.c"] },
},
+ include_build_directory: false,
} `,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": ["for-lib32.c"],
@@ -1008,13 +888,10 @@
lib32: { srcs: ["for-lib32.c"], exclude_srcs: ["not-for-lib32.c"] },
lib64: { srcs: ["for-lib64.c"], exclude_srcs: ["not-for-lib64.c"] },
},
+ include_build_directory: false,
} `,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static2",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
@@ -1079,13 +956,10 @@
lib32: { srcs: ["for-lib32.c"], exclude_srcs: ["not-for-lib32.c"] },
lib64: { srcs: ["for-lib64.c"], exclude_srcs: ["not-for-lib64.c"] },
},
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static3",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
@@ -1146,21 +1020,21 @@
"not-for-everything.cpp": "",
"dep/Android.bp": `
genrule {
- name: "generated_src_other_pkg",
- out: ["generated_src_other_pkg.cpp"],
- cmd: "nothing to see here",
+ name: "generated_src_other_pkg",
+ out: ["generated_src_other_pkg.cpp"],
+ cmd: "nothing to see here",
}
genrule {
- name: "generated_hdr_other_pkg",
- out: ["generated_hdr_other_pkg.cpp"],
- cmd: "nothing to see here",
+ name: "generated_hdr_other_pkg",
+ out: ["generated_hdr_other_pkg.cpp"],
+ cmd: "nothing to see here",
}
genrule {
- name: "generated_hdr_other_pkg_x86",
- out: ["generated_hdr_other_pkg_x86.cpp"],
- cmd: "nothing to see here",
+ name: "generated_hdr_other_pkg_x86",
+ out: ["generated_hdr_other_pkg_x86.cpp"],
+ cmd: "nothing to see here",
}`,
},
blueprint: soongCcLibraryStaticPreamble + `
@@ -1196,14 +1070,11 @@
generated_headers: ["generated_hdr_other_pkg_x86"],
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static3",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs = [
"//dep:generated_hdr_other_pkg",
@@ -1256,13 +1127,10 @@
srcs: ["linux_bionic_x86_64_src.c"],
},
},
+ include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs_c = select({
"//build/bazel/platforms/os:android": ["android_src.c"],
@@ -1301,13 +1169,11 @@
cflags: ["-Wbinder32bit"],
},
},
+ include_build_directory: false,
} `,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ] + select({
+ copts = select({
"//build/bazel/product_variables:binder32bit": ["-Wbinder32bit"],
"//conditions:default": [],
}) + select({
@@ -1339,40 +1205,38 @@
cflags: ["-Wmalloc_not_svelte"],
},
},
- arch: {
- arm64: {
- product_variables: {
- malloc_not_svelte: {
- cflags: ["-Warm64_malloc_not_svelte"],
- },
- },
- },
- },
- multilib: {
- lib32: {
- product_variables: {
- malloc_not_svelte: {
- cflags: ["-Wlib32_malloc_not_svelte"],
- },
- },
- },
- },
- target: {
- android: {
- product_variables: {
- malloc_not_svelte: {
- cflags: ["-Wandroid_malloc_not_svelte"],
- },
- },
- }
- },
+ arch: {
+ arm64: {
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Warm64_malloc_not_svelte"],
+ },
+ },
+ },
+ },
+ multilib: {
+ lib32: {
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Wlib32_malloc_not_svelte"],
+ },
+ },
+ },
+ },
+ target: {
+ android: {
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Wandroid_malloc_not_svelte"],
+ },
+ },
+ }
+ },
+ include_build_directory: false,
} `,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ] + select({
+ copts = select({
"//build/bazel/product_variables:malloc_not_svelte": ["-Wmalloc_not_svelte"],
"//conditions:default": [],
}) + select({
@@ -1410,20 +1274,14 @@
asflags: ["-DPLATFORM_SDK_VERSION=%d"],
},
},
+ include_build_directory: false,
} `,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- asflags = [
- "-I.",
- "-I$(BINDIR)/.",
- ] + select({
+ asflags = select({
"//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
"//conditions:default": [],
}),
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
srcs_as = ["common.S"],
)`},
@@ -1439,15 +1297,12 @@
blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "root_empty",
- system_shared_libs: [],
+ system_shared_libs: [],
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library_static(
name = "root_empty",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
system_dynamic_deps = [],
)`},
@@ -1464,20 +1319,17 @@
cc_defaults {
name: "static_empty_defaults",
static: {
- system_shared_libs: [],
- },
+ system_shared_libs: [],
+ },
+ include_build_directory: false,
}
cc_library_static {
name: "static_empty",
- defaults: ["static_empty_defaults"],
+ defaults: ["static_empty_defaults"],
}
`,
expectedBazelTargets: []string{`cc_library_static(
name = "static_empty",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
system_dynamic_deps = [],
)`},
@@ -1498,14 +1350,11 @@
system_shared_libs: [],
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library_static(
name = "target_bionic_empty",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
system_dynamic_deps = [],
)`},
@@ -1530,14 +1379,11 @@
system_shared_libs: [],
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library_static(
name = "target_linux_bionic_empty",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
system_dynamic_deps = [],
)`},
@@ -1560,14 +1406,11 @@
system_shared_libs: ["libc"],
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library_static(
name = "target_bionic",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
system_dynamic_deps = select({
"//build/bazel/platforms/os:bionic": [":libc"],
@@ -1589,20 +1432,17 @@
cc_library_static {
name: "target_linux_bionic",
- system_shared_libs: ["libc"],
+ system_shared_libs: ["libc"],
target: {
linux_bionic: {
system_shared_libs: ["libm"],
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library_static(
name = "target_linux_bionic",
- copts = [
- "-I.",
- "-I$(BINDIR)/.",
- ],
linkstatic = True,
system_dynamic_deps = [":libc"] + select({
"//build/bazel/platforms/os:linux_bionic": [":libm"],
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index 9ac28a5..b0a88ae 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -65,10 +65,10 @@
"-Wno-gcc-compat",
"-Wall",
"-Werror",
- "-Iinclude",
- "-I$(BINDIR)/include",
- "-I.",
- "-I$(BINDIR)/.",
+ ],
+ local_includes = [
+ "include",
+ ".",
],
srcs = ["a/b/c.c"],
)`,
@@ -78,14 +78,12 @@
func TestCcObjectDefaults(t *testing.T) {
runCcObjectTestCase(t, bp2buildTestCase{
- description: "simple cc_object with defaults",
moduleTypeUnderTest: "cc_object",
moduleTypeUnderTestFactory: cc.ObjectFactory,
moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
blueprint: `cc_object {
name: "foo",
system_shared_libs: [],
- local_include_dirs: ["include"],
srcs: [
"a/b/*.h",
"a/b/c.c"
@@ -115,11 +113,8 @@
"-Wall",
"-Werror",
"-fno-addrsig",
- "-Iinclude",
- "-I$(BINDIR)/include",
- "-I.",
- "-I$(BINDIR)/.",
],
+ local_includes = ["."],
srcs = ["a/b/c.c"],
)`,
}})
@@ -140,29 +135,23 @@
system_shared_libs: [],
srcs: ["a/b/c.c"],
objs: ["bar"],
+ include_build_directory: false,
}
cc_object {
name: "bar",
system_shared_libs: [],
srcs: ["x/y/z.c"],
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_object(
name = "bar",
- copts = [
- "-fno-addrsig",
- "-I.",
- "-I$(BINDIR)/.",
- ],
+ copts = ["-fno-addrsig"],
srcs = ["x/y/z.c"],
)`, `cc_object(
name = "foo",
- copts = [
- "-fno-addrsig",
- "-I.",
- "-I$(BINDIR)/.",
- ],
+ copts = ["-fno-addrsig"],
deps = [":bar"],
srcs = ["a/b/c.c"],
)`,
@@ -245,16 +234,13 @@
srcs: ["arch/arm/file.cpp"], // label list
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{
`cc_object(
name = "foo",
- copts = [
- "-fno-addrsig",
- "-I.",
- "-I$(BINDIR)/.",
- ] + select({
+ copts = ["-fno-addrsig"] + select({
"//build/bazel/platforms/arch:x86": ["-fPIC"],
"//conditions:default": [],
}),
@@ -295,16 +281,13 @@
cflags: ["-Wall"],
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{
`cc_object(
name = "foo",
- copts = [
- "-fno-addrsig",
- "-I.",
- "-I$(BINDIR)/.",
- ] + select({
+ copts = ["-fno-addrsig"] + select({
"//build/bazel/platforms/arch:arm": ["-Wall"],
"//build/bazel/platforms/arch:arm64": ["-Wall"],
"//build/bazel/platforms/arch:x86": ["-fPIC"],
@@ -344,16 +327,13 @@
cflags: ["-Wall"],
},
},
+ include_build_directory: false,
}
`,
expectedBazelTargets: []string{
`cc_object(
name = "foo",
- copts = [
- "-fno-addrsig",
- "-I.",
- "-I$(BINDIR)/.",
- ] + select({
+ copts = ["-fno-addrsig"] + select({
"//build/bazel/platforms/os:android": ["-fPIC"],
"//build/bazel/platforms/os:darwin": ["-Wall"],
"//build/bazel/platforms/os:windows": ["-fPIC"],
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 537f01c..7a98fd0 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -216,6 +216,9 @@
srcs bazel.LabelListAttribute
rtti bazel.BoolAttribute
+
+ localIncludes bazel.StringListAttribute
+ absoluteIncludes bazel.StringListAttribute
}
// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
@@ -226,28 +229,8 @@
var conlyFlags bazel.StringListAttribute
var cppFlags bazel.StringListAttribute
var rtti bazel.BoolAttribute
-
- // Creates the -I flags for a directory, while making the directory relative
- // to the exec root for Bazel to work.
- includeFlags := func(dir string) []string {
- // filepath.Join canonicalizes the path, i.e. it takes care of . or .. elements.
- moduleDirRootedPath := filepath.Join(ctx.ModuleDir(), dir)
- return []string{
- "-I" + moduleDirRootedPath,
- // Include the bindir-rooted path (using make variable substitution). This most
- // closely matches Bazel's native include path handling, which allows for dependency
- // on generated headers in these directories.
- // TODO(b/188084383): Handle local include directories in Bazel.
- "-I$(BINDIR)/" + moduleDirRootedPath,
- }
- }
-
- // Parse the list of module-relative include directories (-I).
- parseLocalIncludeDirs := func(baseCompilerProps *BaseCompilerProperties) []string {
- // include_dirs are root-relative, not module-relative.
- includeDirs := bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
- return append(includeDirs, baseCompilerProps.Local_include_dirs...)
- }
+ var localIncludes bazel.StringListAttribute
+ var absoluteIncludes bazel.StringListAttribute
parseCommandLineFlags := func(soongFlags []string) []string {
var result []string
@@ -285,18 +268,14 @@
archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
- for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
- archVariantCopts = append(archVariantCopts, includeFlags(dir)...)
- archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...)
+
+ localIncludeDirs := baseCompilerProps.Local_include_dirs
+ if axis == bazel.NoConfigAxis && includeBuildDirectory(baseCompilerProps.Include_build_directory) {
+ localIncludeDirs = append(localIncludeDirs, ".")
}
- if axis == bazel.NoConfigAxis {
- if includeBuildDirectory(baseCompilerProps.Include_build_directory) {
- flags := includeFlags(".")
- archVariantCopts = append(archVariantCopts, flags...)
- archVariantAsflags = append(archVariantAsflags, flags...)
- }
- }
+ absoluteIncludes.SetSelectValue(axis, config, baseCompilerProps.Include_dirs)
+ localIncludes.SetSelectValue(axis, config, localIncludeDirs)
copts.SetSelectValue(axis, config, archVariantCopts)
asFlags.SetSelectValue(axis, config, archVariantAsflags)
@@ -308,6 +287,8 @@
}
srcs.ResolveExcludes()
+ absoluteIncludes.DeduplicateAxesFromBase()
+ localIncludes.DeduplicateAxesFromBase()
productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
"Cflags": &copts,
@@ -331,14 +312,16 @@
srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
return compilerAttributes{
- copts: copts,
- srcs: srcs,
- asFlags: asFlags,
- asSrcs: asSrcs,
- cSrcs: cSrcs,
- conlyFlags: conlyFlags,
- cppFlags: cppFlags,
- rtti: rtti,
+ copts: copts,
+ srcs: srcs,
+ asFlags: asFlags,
+ asSrcs: asSrcs,
+ cSrcs: cSrcs,
+ conlyFlags: conlyFlags,
+ cppFlags: cppFlags,
+ rtti: rtti,
+ localIncludes: localIncludes,
+ absoluteIncludes: absoluteIncludes,
}
}
@@ -535,12 +518,21 @@
return relativePaths
}
-func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
+// BazelIncludes contains information about -I and -isystem paths from a module converted to Bazel
+// attributes.
+type BazelIncludes struct {
+ Includes bazel.StringListAttribute
+ SystemIncludes bazel.StringListAttribute
+}
+
+func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) BazelIncludes {
libraryDecorator := module.linker.(*libraryDecorator)
return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
}
-func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
+// Bp2buildParseExportedIncludesForPrebuiltLibrary returns a BazelIncludes with Bazel-ified values
+// to export includes from the underlying module's properties.
+func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) BazelIncludes {
prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
libraryDecorator := prebuiltLibraryLinker.libraryDecorator
return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
@@ -548,36 +540,22 @@
// bp2BuildParseExportedIncludes creates a string list attribute contains the
// exported included directories of a module.
-func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) bazel.StringListAttribute {
- // Export_system_include_dirs and export_include_dirs are already module dir
- // relative, so they don't need to be relativized like include_dirs, which
- // are root-relative.
- includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
- includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
- var includeDirsAttribute bazel.StringListAttribute
-
- getVariantIncludeDirs := func(includeDirs []string, flagExporterProperties *FlagExporterProperties, subtract bool) []string {
- variantIncludeDirs := flagExporterProperties.Export_system_include_dirs
- variantIncludeDirs = append(variantIncludeDirs, flagExporterProperties.Export_include_dirs...)
-
- if subtract {
- // To avoid duplicate includes when base includes + arch includes are combined
- // TODO: Add something similar to ResolveExcludes() in bazel/properties.go
- variantIncludeDirs = bazel.SubtractStrings(variantIncludeDirs, includeDirs)
- }
- return variantIncludeDirs
- }
-
+func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) BazelIncludes {
+ exported := BazelIncludes{}
for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
for config, props := range configToProps {
if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
- archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties, axis != bazel.NoConfigAxis)
- if len(archVariantIncludeDirs) > 0 {
- includeDirsAttribute.SetSelectValue(axis, config, archVariantIncludeDirs)
+ if len(flagExporterProperties.Export_include_dirs) > 0 {
+ exported.Includes.SetSelectValue(axis, config, flagExporterProperties.Export_include_dirs)
+ }
+ if len(flagExporterProperties.Export_system_include_dirs) > 0 {
+ exported.SystemIncludes.SetSelectValue(axis, config, flagExporterProperties.Export_system_include_dirs)
}
}
}
}
+ exported.Includes.DeduplicateAxesFromBase()
+ exported.SystemIncludes.DeduplicateAxesFromBase()
- return includeDirsAttribute
+ return exported
}
diff --git a/cc/builder.go b/cc/builder.go
index a8219d7..6a4d940 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -198,13 +198,14 @@
// Rule for invoking clang-tidy (a clang-based linter).
clangTidy, clangTidyRE = pctx.RemoteStaticRules("clangTidy",
blueprint.RuleParams{
- Command: "rm -f $out && $reTemplate${config.ClangBin}/clang-tidy $tidyFlags $in -- $cFlags && touch $out",
+ Command: "rm -f $out && $tidyVars $reTemplate${config.ClangBin}/clang-tidy $tidyFlags $in -- $cFlags && touch $out",
CommandDeps: []string{"${config.ClangBin}/clang-tidy"},
},
&remoteexec.REParams{
- Labels: map[string]string{"type": "lint", "tool": "clang-tidy", "lang": "cpp"},
- ExecStrategy: "${config.REClangTidyExecStrategy}",
- Inputs: []string{"$in"},
+ Labels: map[string]string{"type": "lint", "tool": "clang-tidy", "lang": "cpp"},
+ ExecStrategy: "${config.REClangTidyExecStrategy}",
+ Inputs: []string{"$in"},
+ EnvironmentVariables: []string{"TIDY_TIMEOUT"},
// Although clang-tidy has an option to "fix" source files, that feature is hardly useable
// under parallel compilation and RBE. So we assume no OutputFiles here.
// The clang-tidy fix option is best run locally in single thread.
@@ -212,7 +213,7 @@
// (1) New timestamps trigger clang and clang-tidy compilations again.
// (2) Changing source files caused concurrent clang or clang-tidy jobs to crash.
Platform: map[string]string{remoteexec.PoolKey: "${config.REClangTidyPool}"},
- }, []string{"cFlags", "tidyFlags"}, []string{})
+ }, []string{"cFlags", "tidyFlags", "tidyVars"}, []string{})
_ = pctx.SourcePathVariable("yasmCmd", "prebuilts/misc/${config.HostPrebuiltTag}/yasm/yasm")
@@ -442,8 +443,13 @@
// Source files are one-to-one with tidy, coverage, or kythe files, if enabled.
objFiles := make(android.Paths, len(srcFiles))
var tidyFiles android.Paths
+ var tidyVars string
if flags.tidy {
tidyFiles = make(android.Paths, 0, len(srcFiles))
+ tidyTimeout := ctx.Config().Getenv("TIDY_TIMEOUT")
+ if len(tidyTimeout) > 0 {
+ tidyVars += "TIDY_TIMEOUT=" + tidyTimeout
+ }
}
var coverageFiles android.Paths
if flags.gcovCoverage {
@@ -647,6 +653,7 @@
Args: map[string]string{
"cFlags": moduleToolingFlags,
"tidyFlags": config.TidyFlagsForSrcFile(srcFile, flags.tidyFlags),
+ "tidyVars": tidyVars,
},
})
}
diff --git a/cc/cc.go b/cc/cc.go
index b0c0299..300bd98 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -31,6 +31,7 @@
"android/soong/cc/config"
"android/soong/fuzz"
"android/soong/genrule"
+ "android/soong/snapshot"
)
func init() {
@@ -3401,6 +3402,8 @@
return c.IsStubs() || c.Target().NativeBridge == android.NativeBridgeEnabled
}
+var _ snapshot.RelativeInstallPath = (*Module)(nil)
+
//
// Defaults
//
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 53a7306..3caa688 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -31,23 +31,15 @@
"-fno-tree-sra",
"-fprefetch-loop-arrays",
"-funswitch-loops",
- "-Werror=unused-but-set-parameter",
- "-Werror=unused-but-set-variable",
"-Wmaybe-uninitialized",
"-Wno-error=clobbered",
"-Wno-error=maybe-uninitialized",
- "-Wno-error=unused-but-set-parameter",
- "-Wno-error=unused-but-set-variable",
"-Wno-extended-offsetof",
"-Wno-free-nonheap-object",
"-Wno-literal-suffix",
"-Wno-maybe-uninitialized",
"-Wno-old-style-declaration",
- "-Wno-unused-but-set-parameter",
- "-Wno-unused-but-set-variable",
"-Wno-unused-local-typedefs",
- "-Wunused-but-set-parameter",
- "-Wunused-but-set-variable",
"-fdiagnostics-color",
// http://b/153759688
"-fuse-init-array",
diff --git a/cc/config/global.go b/cc/config/global.go
index 9773345..5f41f9e 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -230,6 +230,9 @@
"-Wno-string-concatenation", // http://b/175068488
// New warnings to be fixed after clang-r428724
"-Wno-align-mismatch", // http://b/193679946
+ // New warnings to be fixed after clang-r433403
+ "-Wno-error=unused-but-set-variable", // http://b/197240255
+ "-Wno-error=unused-but-set-parameter", // http://b/197240255
}
// Extra cflags for external third-party projects to disable warnings that
@@ -255,6 +258,9 @@
// http://b/165945989
"-Wno-psabi",
+
+ // http://b/199369603
+ "-Wno-null-pointer-subtraction",
}
IllegalFlags = []string{
@@ -268,8 +274,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r428724"
- ClangDefaultShortVersion = "13.0.1"
+ ClangDefaultVersion = "clang-r433403"
+ ClangDefaultShortVersion = "13.0.2"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index 8682502..fdc246c 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -39,6 +39,7 @@
"misc-*",
"performance-*",
"portability-*",
+ "-bugprone-easily-swappable-parameters",
"-bugprone-narrowing-conversions",
"-google-readability*",
"-google-runtime-references",
diff --git a/cc/library.go b/cc/library.go
index 92d9771..f568247 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -228,16 +228,19 @@
Conlyflags bazel.StringListAttribute
Asflags bazel.StringListAttribute
- Hdrs bazel.LabelListAttribute
- Deps bazel.LabelListAttribute
- Implementation_deps bazel.LabelListAttribute
- Dynamic_deps bazel.LabelListAttribute
- Whole_archive_deps bazel.LabelListAttribute
- System_dynamic_deps bazel.LabelListAttribute
- Includes bazel.StringListAttribute
- Linkopts bazel.StringListAttribute
- Use_libcrt bazel.BoolAttribute
- Rtti bazel.BoolAttribute
+ Hdrs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Implementation_deps bazel.LabelListAttribute
+ Dynamic_deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
+ System_dynamic_deps bazel.LabelListAttribute
+ Export_includes bazel.StringListAttribute
+ Export_system_includes bazel.StringListAttribute
+ Local_includes bazel.StringListAttribute
+ Absolute_includes bazel.StringListAttribute
+ Linkopts bazel.StringListAttribute
+ Use_libcrt bazel.BoolAttribute
+ Rtti bazel.BoolAttribute
// This is shared only.
Version_script bazel.LabelAttribute
@@ -299,15 +302,18 @@
Conlyflags: compilerAttrs.conlyFlags,
Asflags: asFlags,
- Implementation_deps: linkerAttrs.deps,
- Deps: linkerAttrs.exportedDeps,
- Dynamic_deps: linkerAttrs.dynamicDeps,
- Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
- System_dynamic_deps: linkerAttrs.systemDynamicDeps,
- Includes: exportedIncludes,
- Linkopts: linkerAttrs.linkopts,
- Use_libcrt: linkerAttrs.useLibcrt,
- Rtti: compilerAttrs.rtti,
+ Implementation_deps: linkerAttrs.deps,
+ Deps: linkerAttrs.exportedDeps,
+ Dynamic_deps: linkerAttrs.dynamicDeps,
+ Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
+ System_dynamic_deps: linkerAttrs.systemDynamicDeps,
+ Export_includes: exportedIncludes.Includes,
+ Export_system_includes: exportedIncludes.SystemIncludes,
+ Local_includes: compilerAttrs.localIncludes,
+ Absolute_includes: compilerAttrs.absoluteIncludes,
+ Linkopts: linkerAttrs.linkopts,
+ Use_libcrt: linkerAttrs.useLibcrt,
+ Rtti: compilerAttrs.rtti,
Version_script: linkerAttrs.versionScript,
@@ -2318,19 +2324,22 @@
}
type bazelCcLibraryStaticAttributes struct {
- Copts bazel.StringListAttribute
- Srcs bazel.LabelListAttribute
- Implementation_deps bazel.LabelListAttribute
- Deps bazel.LabelListAttribute
- Whole_archive_deps bazel.LabelListAttribute
- Dynamic_deps bazel.LabelListAttribute
- System_dynamic_deps bazel.LabelListAttribute
- Linkopts bazel.StringListAttribute
- Linkstatic bool
- Use_libcrt bazel.BoolAttribute
- Rtti bazel.BoolAttribute
- Includes bazel.StringListAttribute
- Hdrs bazel.LabelListAttribute
+ Copts bazel.StringListAttribute
+ Srcs bazel.LabelListAttribute
+ Implementation_deps bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
+ Dynamic_deps bazel.LabelListAttribute
+ System_dynamic_deps bazel.LabelListAttribute
+ Linkopts bazel.StringListAttribute
+ Linkstatic bool
+ Use_libcrt bazel.BoolAttribute
+ Rtti bazel.BoolAttribute
+ Export_includes bazel.StringListAttribute
+ Export_system_includes bazel.StringListAttribute
+ Local_includes bazel.StringListAttribute
+ Absolute_includes bazel.StringListAttribute
+ Hdrs bazel.LabelListAttribute
Cppflags bazel.StringListAttribute
Srcs_c bazel.LabelListAttribute
@@ -2375,11 +2384,14 @@
Dynamic_deps: linkerAttrs.dynamicDeps,
System_dynamic_deps: linkerAttrs.systemDynamicDeps,
- Linkopts: linkerAttrs.linkopts,
- Linkstatic: true,
- Use_libcrt: linkerAttrs.useLibcrt,
- Rtti: compilerAttrs.rtti,
- Includes: exportedIncludes,
+ Linkopts: linkerAttrs.linkopts,
+ Linkstatic: true,
+ Use_libcrt: linkerAttrs.useLibcrt,
+ Rtti: compilerAttrs.rtti,
+ Export_includes: exportedIncludes.Includes,
+ Export_system_includes: exportedIncludes.SystemIncludes,
+ Local_includes: compilerAttrs.localIncludes,
+ Absolute_includes: compilerAttrs.absoluteIncludes,
Cppflags: compilerAttrs.cppFlags,
Srcs_c: compilerAttrs.cSrcs,
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 44a7a71..14b90c1 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -103,12 +103,12 @@
}
type bazelCcLibraryHeadersAttributes struct {
- Copts bazel.StringListAttribute
- Hdrs bazel.LabelListAttribute
- Includes bazel.StringListAttribute
- Deps bazel.LabelListAttribute
- Implementation_deps bazel.LabelListAttribute
- System_dynamic_deps bazel.LabelListAttribute
+ Hdrs bazel.LabelListAttribute
+ Export_includes bazel.StringListAttribute
+ Export_system_includes bazel.StringListAttribute
+ Deps bazel.LabelListAttribute
+ Implementation_deps bazel.LabelListAttribute
+ System_dynamic_deps bazel.LabelListAttribute
}
func CcLibraryHeadersBp2Build(ctx android.TopDownMutatorContext) {
@@ -127,15 +127,14 @@
}
exportedIncludes := bp2BuildParseExportedIncludes(ctx, module)
- compilerAttrs := bp2BuildParseCompilerProps(ctx, module)
linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
attrs := &bazelCcLibraryHeadersAttributes{
- Copts: compilerAttrs.copts,
- Includes: exportedIncludes,
- Implementation_deps: linkerAttrs.deps,
- Deps: linkerAttrs.exportedDeps,
- System_dynamic_deps: linkerAttrs.systemDynamicDeps,
+ Export_includes: exportedIncludes.Includes,
+ Export_system_includes: exportedIncludes.SystemIncludes,
+ Implementation_deps: linkerAttrs.deps,
+ Deps: linkerAttrs.exportedDeps,
+ System_dynamic_deps: linkerAttrs.systemDynamicDeps,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/object.go b/cc/object.go
index 606e368..99b257a 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -122,12 +122,14 @@
// For bp2build conversion.
type bazelObjectAttributes struct {
- Srcs bazel.LabelListAttribute
- Srcs_as bazel.LabelListAttribute
- Hdrs bazel.LabelListAttribute
- Deps bazel.LabelListAttribute
- Copts bazel.StringListAttribute
- Asflags bazel.StringListAttribute
+ Srcs bazel.LabelListAttribute
+ Srcs_as bazel.LabelListAttribute
+ Hdrs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Copts bazel.StringListAttribute
+ Asflags bazel.StringListAttribute
+ Local_includes bazel.StringListAttribute
+ Absolute_includes bazel.StringListAttribute
}
// ObjectBp2Build is the bp2build converter from cc_object modules to the
@@ -170,11 +172,13 @@
}
attrs := &bazelObjectAttributes{
- Srcs: srcs,
- Srcs_as: compilerAttrs.asSrcs,
- Deps: deps,
- Copts: compilerAttrs.copts,
- Asflags: asFlags,
+ Srcs: srcs,
+ Srcs_as: compilerAttrs.asSrcs,
+ Deps: deps,
+ Copts: compilerAttrs.copts,
+ Asflags: asFlags,
+ Local_includes: compilerAttrs.localIncludes,
+ Absolute_includes: compilerAttrs.absoluteIncludes,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/test.go b/cc/test.go
index 047a69e..3934784 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -357,8 +357,7 @@
}
func (test *testBinary) install(ctx ModuleContext, file android.Path) {
- // TODO: (b/167308193) Switch to /data/local/tests/unrestricted as the default install base.
- testInstallBase := "/data/local/tmp"
+ testInstallBase := "/data/local/tests/unrestricted"
if ctx.inVendor() || ctx.useVndk() {
testInstallBase = "/data/local/tests/vendor"
}
diff --git a/cc/tidy.go b/cc/tidy.go
index fefa7f0..53ff156 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -148,6 +148,9 @@
tidyChecks = tidyChecks + ",-bugprone-branch-clone"
// http://b/193716442
tidyChecks = tidyChecks + ",-bugprone-implicit-widening-of-multiplication-result"
+ // Too many existing functions trigger this rule, and fixing it requires large code
+ // refactoring. The cost of maintaining this tidy rule outweighs the benefit it brings.
+ tidyChecks = tidyChecks + ",-bugprone-easily-swappable-parameters"
flags.TidyFlags = append(flags.TidyFlags, tidyChecks)
if ctx.Config().IsEnvTrue("WITH_TIDY") {
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index ba4d79f..8a17e2e 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -132,12 +132,9 @@
return false
}
-// This is to be saved as .json files, which is for development/vendor_snapshot/update.py.
-// These flags become Android.bp snapshot module properties.
+// Extend the snapshot.SnapshotJsonFlags to include cc specific fields.
type snapshotJsonFlags struct {
- ModuleName string `json:",omitempty"`
- RelativeInstallPath string `json:",omitempty"`
-
+ snapshot.SnapshotJsonFlags
// library flags
ExportedDirs []string `json:",omitempty"`
ExportedSystemDirs []string `json:",omitempty"`
@@ -154,7 +151,6 @@
SharedLibs []string `json:",omitempty"`
StaticLibs []string `json:",omitempty"`
RuntimeLibs []string `json:",omitempty"`
- Required []string `json:",omitempty"`
// extra config files
InitRc []string `json:",omitempty"`
diff --git a/cmd/pom2bp/pom2bp.go b/cmd/pom2bp/pom2bp.go
index d31489e..fe567a9 100644
--- a/cmd/pom2bp/pom2bp.go
+++ b/cmd/pom2bp/pom2bp.go
@@ -93,6 +93,8 @@
var extraLibs = make(ExtraDeps)
+var optionalUsesLibs = make(ExtraDeps)
+
type Exclude map[string]bool
func (e Exclude) String() string {
@@ -269,6 +271,10 @@
return extraLibs[p.BpName()]
}
+func (p Pom) BpOptionalUsesLibs() []string {
+ return optionalUsesLibs[p.BpName()]
+}
+
// BpDeps obtains dependencies filtered by type and scope. The results of this
// method are formatted as Android.bp targets, e.g. run through MavenToBp rules.
func (p Pom) BpDeps(typeExt string, scopes []string) []string {
@@ -401,6 +407,13 @@
{{- end}}
],
{{- end}}
+ {{- if .BpOptionalUsesLibs}}
+ optional_uses_libs: [
+ {{- range .BpOptionalUsesLibs}}
+ "{{.}}",
+ {{- end}}
+ ],
+ {{- end}}
{{- else if not .IsHostOnly}}
min_sdk_version: "{{.DefaultMinSdkVersion}}",
{{- end}}
@@ -488,6 +501,13 @@
{{- end}}
],
{{- end}}
+ {{- if .BpOptionalUsesLibs}}
+ optional_uses_libs: [
+ {{- range .BpOptionalUsesLibs}}
+ "{{.}}",
+ {{- end}}
+ ],
+ {{- end}}
java_version: "1.7",
}
`))
@@ -587,7 +607,7 @@
The tool will extract the necessary information from *.pom files to create an Android.bp whose
aar libraries can be linked against when using AAPT2.
-Usage: %s [--rewrite <regex>=<replace>] [-exclude <module>] [--extra-static-libs <module>=<module>[,<module>]] [--extra-libs <module>=<module>[,<module>]] [<dir>] [-regen <file>]
+Usage: %s [--rewrite <regex>=<replace>] [--exclude <module>] [--extra-static-libs <module>=<module>[,<module>]] [--extra-libs <module>=<module>[,<module>]] [--optional-uses-libs <module>=<module>[,<module>]] [<dir>] [-regen <file>]
-rewrite <regex>=<replace>
rewrite can be used to specify mappings between Maven projects and Android.bp modules. The -rewrite
@@ -605,6 +625,11 @@
Some Android.bp modules have transitive runtime dependencies that must be specified when they
are depended upon (like androidx.test.rules requires android.test.base).
This may be specified multiple times to declare these dependencies.
+ -optional-uses-libs <module>=<module>[,<module>]
+ Some Android.bp modules have optional dependencies (typically specified with <uses-library> in
+ the module's AndroidManifest.xml) that must be specified when they are depended upon (like
+ androidx.window:window optionally requires androidx.window:window-extensions).
+ This may be specified multiple times to declare these dependencies.
-sdk-version <version>
Sets sdk_version: "<version>" for all modules.
-default-min-sdk-version
@@ -629,6 +654,7 @@
flag.Var(&excludes, "exclude", "Exclude module")
flag.Var(&extraStaticLibs, "extra-static-libs", "Extra static dependencies needed when depending on a module")
flag.Var(&extraLibs, "extra-libs", "Extra runtime dependencies needed when depending on a module")
+ flag.Var(&optionalUsesLibs, "optional-uses-libs", "Extra optional dependencies needed when depending on a module")
flag.Var(&rewriteNames, "rewrite", "Regex(es) to rewrite artifact names")
flag.Var(&hostModuleNames, "host", "Specifies that the corresponding module (specified in the form 'module.group:module.artifact') is a host module")
flag.Var(&hostAndDeviceModuleNames, "host-and-device", "Specifies that the corresponding module (specified in the form 'module.group:module.artifact') is both a host and device module.")
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 1401c75..7733c1b 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -110,17 +110,12 @@
return true
}
- // Don't preopt system server jars that are updatable.
- if global.ApexSystemServerJars.ContainsJar(module.Name) {
- return true
- }
-
// If OnlyPreoptBootImageAndSystemServer=true and module is not in boot class path skip
// Also preopt system server jars since selinux prevents system server from loading anything from
// /data. If we don't do this they will need to be extracted which is not favorable for RAM usage
// or performance. If PreoptExtractedApk is true, we ignore the only preopt boot image options.
if global.OnlyPreoptBootImageAndSystemServer && !global.BootJars.ContainsJar(module.Name) &&
- !global.SystemServerJars.ContainsJar(module.Name) && !module.PreoptExtractedApk {
+ !AllSystemServerJars(ctx, global).ContainsJar(module.Name) && !module.PreoptExtractedApk {
return true
}
@@ -201,6 +196,14 @@
return profilePath
}
+// Returns the dex location of a system server java library.
+func GetSystemServerDexLocation(global *GlobalConfig, lib string) string {
+ if apex := global.ApexSystemServerJars.ApexOfJar(lib); apex != "" {
+ return fmt.Sprintf("/apex/%s/javalib/%s.jar", apex, lib)
+ }
+ return fmt.Sprintf("/system/framework/%s.jar", lib)
+}
+
func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig,
module *ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath,
appImage bool, generateDM bool) {
@@ -216,6 +219,13 @@
}
toOdexPath := func(path string) string {
+ if global.ApexSystemServerJars.ContainsJar(module.Name) {
+ return filepath.Join(
+ "/system/framework/oat",
+ arch.String(),
+ strings.ReplaceAll(path[1:], "/", "@")+"@classes.odex")
+ }
+
return filepath.Join(
filepath.Dir(path),
"oat",
@@ -234,20 +244,21 @@
invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
- systemServerJars := NonApexSystemServerJars(ctx, global)
+ systemServerJars := AllSystemServerJars(ctx, global)
rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String()))
rule.Command().FlagWithOutput("rm -f ", odexPath)
- if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 {
+ if jarIndex := systemServerJars.IndexOfJar(module.Name); jarIndex >= 0 {
// System server jars should be dexpreopted together: class loader context of each jar
// should include all preceding jars on the system server classpath.
var clcHost android.Paths
var clcTarget []string
- for _, lib := range systemServerJars[:jarIndex] {
+ for i := 0; i < jarIndex; i++ {
+ lib := systemServerJars.Jar(i)
clcHost = append(clcHost, SystemServerDexJarHostPath(ctx, lib))
- clcTarget = append(clcTarget, filepath.Join("/system/framework", lib+".jar"))
+ clcTarget = append(clcTarget, GetSystemServerDexLocation(global, lib))
}
// Copy the system server jar to a predefined location where dex2oat will find it.
@@ -362,7 +373,7 @@
if !android.PrefixInList(preoptFlags, "--compiler-filter=") {
var compilerFilter string
- if global.SystemServerJars.ContainsJar(module.Name) {
+ if systemServerJars.ContainsJar(module.Name) {
// Jars of system server, use the product option if it is set, speed otherwise.
if global.SystemServerCompilerFilter != "" {
compilerFilter = global.SystemServerCompilerFilter
@@ -416,7 +427,7 @@
// PRODUCT_SYSTEM_SERVER_DEBUG_INFO overrides WITH_DEXPREOPT_DEBUG_INFO.
// PRODUCT_OTHER_JAVA_DEBUG_INFO overrides WITH_DEXPREOPT_DEBUG_INFO.
- if global.SystemServerJars.ContainsJar(module.Name) {
+ if systemServerJars.ContainsJar(module.Name) {
if global.AlwaysSystemServerDebugInfo {
debugInfo = true
} else if global.NeverSystemServerDebugInfo {
@@ -518,14 +529,15 @@
}
}
-var nonApexSystemServerJarsKey = android.NewOnceKey("nonApexSystemServerJars")
+var allSystemServerJarsKey = android.NewOnceKey("allSystemServerJars")
// TODO: eliminate the superficial global config parameter by moving global config definition
// from java subpackage to dexpreopt.
-func NonApexSystemServerJars(ctx android.PathContext, global *GlobalConfig) []string {
- return ctx.Config().Once(nonApexSystemServerJarsKey, func() interface{} {
- return android.RemoveListFromList(global.SystemServerJars.CopyOfJars(), global.ApexSystemServerJars.CopyOfJars())
- }).([]string)
+func AllSystemServerJars(ctx android.PathContext, global *GlobalConfig) *android.ConfiguredJarList {
+ return ctx.Config().Once(allSystemServerJarsKey, func() interface{} {
+ allSystemServerJars := global.SystemServerJars.AppendList(global.ApexSystemServerJars)
+ return &allSystemServerJars
+ }).(*android.ConfiguredJarList)
}
// A predefined location for the system server dex jars. This is needed in order to generate
@@ -551,12 +563,12 @@
mctx, isModule := ctx.(android.ModuleContext)
if isModule {
config := GetGlobalConfig(ctx)
- jars := NonApexSystemServerJars(ctx, config)
+ jars := AllSystemServerJars(ctx, config)
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
- depIndex := android.IndexList(dep.Name(), jars)
+ depIndex := jars.IndexOfJar(dep.Name())
if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
- jar := jars[jarIndex]
- dep := jars[depIndex]
+ jar := jars.Jar(jarIndex)
+ dep := jars.Jar(depIndex)
mctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+
" '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+
" references from '%s' to '%s'.\n", jar, dep, jar, dep)
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 4ee61b6..798d776 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -33,17 +33,35 @@
}
func testModuleConfig(ctx android.PathContext, name, partition string) *ModuleConfig {
+ return createTestModuleConfig(
+ name,
+ fmt.Sprintf("/%s/app/test/%s.apk", partition, name),
+ android.PathForOutput(ctx, fmt.Sprintf("%s/%s.apk", name, name)),
+ android.PathForOutput(ctx, fmt.Sprintf("%s/dex/%s.jar", name, name)),
+ android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
+}
+
+func testApexModuleConfig(ctx android.PathContext, name, apexName string) *ModuleConfig {
+ return createTestModuleConfig(
+ name,
+ fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, name),
+ android.PathForOutput(ctx, fmt.Sprintf("%s/dexpreopt/%s.jar", name, name)),
+ android.PathForOutput(ctx, fmt.Sprintf("%s/aligned/%s.jar", name, name)),
+ android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
+}
+
+func createTestModuleConfig(name, dexLocation string, buildPath, dexPath, enforceUsesLibrariesStatusFile android.OutputPath) *ModuleConfig {
return &ModuleConfig{
Name: name,
- DexLocation: fmt.Sprintf("/%s/app/test/%s.apk", partition, name),
- BuildPath: android.PathForOutput(ctx, fmt.Sprintf("%s/%s.apk", name, name)),
- DexPath: android.PathForOutput(ctx, fmt.Sprintf("%s/dex/%s.jar", name, name)),
+ DexLocation: dexLocation,
+ BuildPath: buildPath,
+ DexPath: dexPath,
UncompressedDex: false,
HasApkLibraries: false,
PreoptFlags: nil,
ProfileClassListing: android.OptionalPath{},
ProfileIsTextListing: false,
- EnforceUsesLibrariesStatusFile: android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)),
+ EnforceUsesLibrariesStatusFile: enforceUsesLibrariesStatusFile,
EnforceUsesLibraries: false,
ClassLoaderContexts: nil,
Archs: []android.ArchType{android.Arm},
@@ -140,6 +158,29 @@
}
+func TestDexPreoptApexSystemServerJars(t *testing.T) {
+ config := android.TestConfig("out", nil, "", nil)
+ ctx := android.BuilderContextForTesting(config)
+ globalSoong := globalSoongConfigForTests()
+ global := GlobalConfigForTests(ctx)
+ module := testApexModuleConfig(ctx, "service-A", "com.android.apex1")
+
+ global.ApexSystemServerJars = android.CreateTestConfiguredJarList(
+ []string{"com.android.apex1:service-A"})
+
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ wantInstalls := android.RuleBuilderInstalls{
+ {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.odex"},
+ {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.vdex"},
+ }
+
+ android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
+}
+
func TestDexPreoptProfile(t *testing.T) {
config := android.TestConfig("out", nil, "", nil)
ctx := android.BuilderContextForTesting(config)
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 3213e5c..85abf59 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -519,13 +519,6 @@
return module
}
-// Flags to be included in the snapshot
-type snapshotJsonFlags struct {
- ModuleName string `json:",omitempty"`
- Filename string `json:",omitempty"`
- RelativeInstallPath string `json:",omitempty"`
-}
-
// Copy file into the snapshot
func copyFile(ctx android.SingletonContext, path android.Path, out string, fake bool) android.OutputPath {
if fake {
@@ -612,7 +605,7 @@
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "etc", m.BaseModuleName())
snapshotOutputs = append(snapshotOutputs, copyFile(ctx, m.OutputFile(), snapshotLibOut, s.Fake))
- prop := snapshotJsonFlags{}
+ prop := snapshot.SnapshotJsonFlags{}
propOut := snapshotLibOut + ".json"
prop.ModuleName = m.BaseModuleName()
if m.subdirProperties.Relative_install_path != nil {
diff --git a/java/aar.go b/java/aar.go
index afbaea2..13390db 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -486,6 +486,18 @@
exportedStaticPackages android.Paths
}
+var _ android.OutputFileProducer = (*AndroidLibrary)(nil)
+
+// For OutputFileProducer interface
+func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case ".aar":
+ return []android.Path{a.aarFile}, nil
+ default:
+ return a.Library.OutputFiles(tag)
+ }
+}
+
func (a *AndroidLibrary) ExportedProguardFlagFiles() android.Paths {
return a.exportedProguardFlagFiles
}
diff --git a/java/androidmk.go b/java/androidmk.go
index 68ccd82..71370c9 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -61,7 +61,13 @@
var entriesList []android.AndroidMkEntries
if library.hideApexVariantFromMake {
- // For a java library built for an APEX we don't need Make module
+ // For a java library built for an APEX, we don't need a Make module for itself. Otherwise, it
+ // will conflict with the platform variant because they have the same module name in the
+ // makefile. However, we need to add its dexpreopt outputs as sub-modules, if it is preopted.
+ dexpreoptEntries := library.dexpreopter.AndroidMkEntriesForApex()
+ if len(dexpreoptEntries) > 0 {
+ entriesList = append(entriesList, dexpreoptEntries...)
+ }
entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
} else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
// Platform variant. If not available for the platform, we don't need Make module.
diff --git a/java/app.go b/java/app.go
index 5104f07..a62e442 100755
--- a/java/app.go
+++ b/java/app.go
@@ -760,18 +760,18 @@
}
lib := dep.OutputFile()
- path := lib.Path()
- if seenModulePaths[path.String()] {
- return false
- }
- seenModulePaths[path.String()] = true
-
- if checkNativeSdkVersion && dep.SdkVersion() == "" {
- ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
- otherName)
- }
-
if lib.Valid() {
+ path := lib.Path()
+ if seenModulePaths[path.String()] {
+ return false
+ }
+ seenModulePaths[path.String()] = true
+
+ if checkNativeSdkVersion && dep.SdkVersion() == "" {
+ ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
+ otherName)
+ }
+
jniLibs = append(jniLibs, jniLib{
name: ctx.OtherModuleName(module),
path: path,
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 0faae36..cdd42ed 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -15,13 +15,46 @@
package java
import (
+ "path/filepath"
+ "strings"
+
"android/soong/android"
"android/soong/dexpreopt"
)
-type dexpreopterInterface interface {
+type DexpreopterInterface interface {
IsInstallable() bool // Structs that embed dexpreopter must implement this.
dexpreoptDisabled(ctx android.BaseModuleContext) bool
+ DexpreoptBuiltInstalledForApex() []dexpreopterInstall
+ AndroidMkEntriesForApex() []android.AndroidMkEntries
+}
+
+type dexpreopterInstall struct {
+ // A unique name to distinguish an output from others for the same java library module. Usually in
+ // the form of `<arch>-<encoded-path>.odex/vdex/art`.
+ name string
+
+ // The name of the input java module.
+ moduleName string
+
+ // The path to the dexpreopt output on host.
+ outputPathOnHost android.Path
+
+ // The directory on the device for the output to install to.
+ installDirOnDevice android.InstallPath
+
+ // The basename (the last segment of the path) for the output to install as.
+ installFileOnDevice string
+}
+
+// The full module name of the output in the makefile.
+func (install *dexpreopterInstall) FullModuleName() string {
+ return install.moduleName + install.SubModuleName()
+}
+
+// The sub-module name of the output in the makefile (the name excluding the java module name).
+func (install *dexpreopterInstall) SubModuleName() string {
+ return "-dexpreopt-" + install.name
}
type dexpreopter struct {
@@ -39,7 +72,9 @@
enforceUsesLibs bool
classLoaderContexts dexpreopt.ClassLoaderContextMap
- builtInstalled string
+ // See the `dexpreopt` function for details.
+ builtInstalled string
+ builtInstalledForApex []dexpreopterInstall
// The config is used for two purposes:
// - Passing dexpreopt information about libraries from Soong to Make. This is needed when
@@ -74,6 +109,17 @@
dexpreopt.DexpreoptRunningInSoong = true
}
+func isApexVariant(ctx android.BaseModuleContext) bool {
+ apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+ return !apexInfo.IsForPlatform()
+}
+
+func moduleName(ctx android.BaseModuleContext) string {
+ // Remove the "prebuilt_" prefix if the module is from a prebuilt because the prefix is not
+ // expected by dexpreopter.
+ return android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
+}
+
func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
global := dexpreopt.GetGlobalConfig(ctx)
@@ -81,7 +127,7 @@
return true
}
- if inList(ctx.ModuleName(), global.DisablePreoptModules) {
+ if inList(moduleName(ctx), global.DisablePreoptModules) {
return true
}
@@ -93,7 +139,7 @@
return true
}
- if !ctx.Module().(dexpreopterInterface).IsInstallable() {
+ if !ctx.Module().(DexpreopterInterface).IsInstallable() {
return true
}
@@ -101,9 +147,17 @@
return true
}
- // Don't preopt APEX variant module
- if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() {
- return true
+ if isApexVariant(ctx) {
+ // Don't preopt APEX variant module unless the module is an APEX system server jar and we are
+ // building the entire system image.
+ if !global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) || ctx.Config().UnbundledBuild() {
+ return true
+ }
+ } else {
+ // Don't preopt the platform variant of an APEX system server jar to avoid conflicts.
+ if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
+ return true
+ }
}
// TODO: contains no java code
@@ -112,17 +166,40 @@
}
func dexpreoptToolDepsMutator(ctx android.BottomUpMutatorContext) {
- if d, ok := ctx.Module().(dexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) {
+ if d, ok := ctx.Module().(DexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) {
return
}
dexpreopt.RegisterToolDeps(ctx)
}
-func odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool {
- return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx))
+func (d *dexpreopter) odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool {
+ return dexpreopt.OdexOnSystemOtherByName(moduleName(ctx), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx))
+}
+
+// Returns the install path of the dex jar of a module.
+//
+// Do not rely on `ApexInfo.ApexVariationName` because it can be something like "apex1000", rather
+// than the `name` in the path `/apex/<name>` as suggested in its comment.
+//
+// This function is on a best-effort basis. It cannot handle the case where an APEX jar is not a
+// system server jar, which is fine because we currently only preopt system server jars for APEXes.
+func (d *dexpreopter) getInstallPath(
+ ctx android.ModuleContext, defaultInstallPath android.InstallPath) android.InstallPath {
+ global := dexpreopt.GetGlobalConfig(ctx)
+ if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
+ dexLocation := dexpreopt.GetSystemServerDexLocation(global, moduleName(ctx))
+ return android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexLocation, "/"))
+ }
+ if !d.dexpreoptDisabled(ctx) && isApexVariant(ctx) &&
+ filepath.Base(defaultInstallPath.PartitionDir()) != "apex" {
+ ctx.ModuleErrorf("unable to get the install path of the dex jar for dexpreopt")
+ }
+ return defaultInstallPath
}
func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.WritablePath) {
+ global := dexpreopt.GetGlobalConfig(ctx)
+
// TODO(b/148690468): The check on d.installPath is to bail out in cases where
// the dexpreopter struct hasn't been fully initialized before we're called,
// e.g. in aar.go. This keeps the behaviour that dexpreopting is effectively
@@ -133,7 +210,7 @@
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
- providesUsesLib := ctx.ModuleName()
+ providesUsesLib := moduleName(ctx)
if ulib, ok := ctx.Module().(ProvidesUsesLib); ok {
name := ulib.ProvidesUsesLib()
if name != nil {
@@ -147,9 +224,8 @@
return
}
- global := dexpreopt.GetGlobalConfig(ctx)
-
- isSystemServerJar := global.SystemServerJars.ContainsJar(ctx.ModuleName())
+ isSystemServerJar := global.SystemServerJars.ContainsJar(moduleName(ctx)) ||
+ global.ApexSystemServerJars.ContainsJar(moduleName(ctx))
bootImage := defaultBootImageConfig(ctx)
if global.UseArtImage {
@@ -199,15 +275,15 @@
profileIsTextListing = true
} else if global.ProfileDir != "" {
profileClassListing = android.ExistentPathForSource(ctx,
- global.ProfileDir, ctx.ModuleName()+".prof")
+ global.ProfileDir, moduleName(ctx)+".prof")
}
}
// Full dexpreopt config, used to create dexpreopt build rules.
dexpreoptConfig := &dexpreopt.ModuleConfig{
- Name: ctx.ModuleName(),
+ Name: moduleName(ctx),
DexLocation: dexLocation,
- BuildPath: android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath,
+ BuildPath: android.PathForModuleOut(ctx, "dexpreopt", moduleName(ctx)+".jar").OutputPath,
DexPath: dexJarFile,
ManifestPath: android.OptionalPathForPath(d.manifestFile),
UncompressedDex: d.uncompressedDex,
@@ -256,5 +332,53 @@
dexpreoptRule.Build("dexpreopt", "dexpreopt")
- d.builtInstalled = dexpreoptRule.Installs().String()
+ if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
+ // APEX variants of java libraries are hidden from Make, so their dexpreopt outputs need special
+ // handling. Currently, for APEX variants of java libraries, only those in the system server
+ // classpath are handled here. Preopting of boot classpath jars in the ART APEX are handled in
+ // java/dexpreopt_bootjars.go, and other APEX jars are not preopted.
+ for _, install := range dexpreoptRule.Installs() {
+ // Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT.
+ installDir := strings.TrimPrefix(filepath.Dir(install.To), "/")
+ installBase := filepath.Base(install.To)
+ arch := filepath.Base(installDir)
+ installPath := android.PathForModuleInPartitionInstall(ctx, "", installDir)
+ // The installs will be handled by Make as sub-modules of the java library.
+ d.builtInstalledForApex = append(d.builtInstalledForApex, dexpreopterInstall{
+ name: arch + "-" + installBase,
+ moduleName: moduleName(ctx),
+ outputPathOnHost: install.From,
+ installDirOnDevice: installPath,
+ installFileOnDevice: installBase,
+ })
+ }
+ } else {
+ // The installs will be handled by Make as LOCAL_SOONG_BUILT_INSTALLED of the java library
+ // module.
+ d.builtInstalled = dexpreoptRule.Installs().String()
+ }
+}
+
+func (d *dexpreopter) DexpreoptBuiltInstalledForApex() []dexpreopterInstall {
+ return d.builtInstalledForApex
+}
+
+func (d *dexpreopter) AndroidMkEntriesForApex() []android.AndroidMkEntries {
+ var entries []android.AndroidMkEntries
+ for _, install := range d.builtInstalledForApex {
+ install := install
+ entries = append(entries, android.AndroidMkEntries{
+ Class: "ETC",
+ SubName: install.SubModuleName(),
+ OutputFile: android.OptionalPathForPath(install.outputPathOnHost),
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.ToMakePath().String())
+ entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice)
+ entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false")
+ },
+ },
+ })
+ }
+ return entries
}
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index 8dc7b79..1c1070a 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -17,6 +17,7 @@
import (
"fmt"
"runtime"
+ "strings"
"testing"
"android/soong/android"
@@ -24,11 +25,17 @@
"android/soong/dexpreopt"
)
+func init() {
+ RegisterFakeRuntimeApexMutator()
+}
+
func TestDexpreoptEnabled(t *testing.T) {
tests := []struct {
- name string
- bp string
- enabled bool
+ name string
+ bp string
+ moduleName string
+ apexVariant bool
+ enabled bool
}{
{
name: "app",
@@ -148,13 +155,81 @@
}`,
enabled: true,
},
+ {
+ name: "apex variant",
+ bp: `
+ java_library {
+ name: "foo",
+ installable: true,
+ srcs: ["a.java"],
+ apex_available: ["com.android.apex1"],
+ }`,
+ apexVariant: true,
+ enabled: false,
+ },
+ {
+ name: "apex variant of apex system server jar",
+ bp: `
+ java_library {
+ name: "service-foo",
+ installable: true,
+ srcs: ["a.java"],
+ apex_available: ["com.android.apex1"],
+ }`,
+ moduleName: "service-foo",
+ apexVariant: true,
+ enabled: true,
+ },
+ {
+ name: "apex variant of prebuilt apex system server jar",
+ bp: `
+ java_library {
+ name: "prebuilt_service-foo",
+ installable: true,
+ srcs: ["a.java"],
+ apex_available: ["com.android.apex1"],
+ }`,
+ moduleName: "prebuilt_service-foo",
+ apexVariant: true,
+ enabled: true,
+ },
+ {
+ name: "platform variant of apex system server jar",
+ bp: `
+ java_library {
+ name: "service-foo",
+ installable: true,
+ srcs: ["a.java"],
+ apex_available: ["com.android.apex1"],
+ }`,
+ moduleName: "service-foo",
+ apexVariant: false,
+ enabled: false,
+ },
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- ctx, _ := testJava(t, test.bp)
+ preparers := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ PrepareForTestWithFakeApexMutator,
+ dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
+ )
- dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt")
+ result := preparers.RunTestWithBp(t, test.bp)
+ ctx := result.TestContext
+
+ moduleName := "foo"
+ if test.moduleName != "" {
+ moduleName = test.moduleName
+ }
+
+ variant := "android_common"
+ if test.apexVariant {
+ variant += "_apex1000"
+ }
+
+ dexpreopt := ctx.ModuleForTests(moduleName, variant).MaybeRule("dexpreopt")
enabled := dexpreopt.Rule != nil
if enabled != test.enabled {
@@ -220,3 +295,145 @@
testDex2oatToolDep(true, true, true, prebuiltDex2oatPath)
testDex2oatToolDep(false, true, false, prebuiltDex2oatPath)
}
+
+func TestDexpreoptBuiltInstalledForApex(t *testing.T) {
+ preparers := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ PrepareForTestWithFakeApexMutator,
+ dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
+ )
+
+ // An APEX system server jar.
+ result := preparers.RunTestWithBp(t, `
+ java_library {
+ name: "service-foo",
+ installable: true,
+ srcs: ["a.java"],
+ apex_available: ["com.android.apex1"],
+ }`)
+ ctx := result.TestContext
+ module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
+ library := module.Module().(*Library)
+
+ installs := library.dexpreopter.DexpreoptBuiltInstalledForApex()
+
+ android.AssertIntEquals(t, "install count", 2, len(installs))
+
+ android.AssertStringEquals(t, "installs[0] FullModuleName",
+ "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
+ installs[0].FullModuleName())
+
+ android.AssertStringEquals(t, "installs[0] SubModuleName",
+ "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
+ installs[0].SubModuleName())
+
+ android.AssertStringEquals(t, "installs[1] FullModuleName",
+ "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
+ installs[1].FullModuleName())
+
+ android.AssertStringEquals(t, "installs[1] SubModuleName",
+ "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
+ installs[1].SubModuleName())
+
+ // Not an APEX system server jar.
+ result = preparers.RunTestWithBp(t, `
+ java_library {
+ name: "foo",
+ installable: true,
+ srcs: ["a.java"],
+ }`)
+ ctx = result.TestContext
+ module = ctx.ModuleForTests("foo", "android_common")
+ library = module.Module().(*Library)
+
+ installs = library.dexpreopter.DexpreoptBuiltInstalledForApex()
+
+ android.AssertIntEquals(t, "install count", 0, len(installs))
+}
+
+func filterDexpreoptEntriesList(entriesList []android.AndroidMkEntries) []android.AndroidMkEntries {
+ var results []android.AndroidMkEntries
+ for _, entries := range entriesList {
+ if strings.Contains(entries.EntryMap["LOCAL_MODULE"][0], "-dexpreopt-") {
+ results = append(results, entries)
+ }
+ }
+ return results
+}
+
+func verifyEntries(t *testing.T, message string, expectedModule string,
+ expectedPrebuiltModuleFile string, expectedModulePath string, expectedInstalledModuleStem string,
+ entries android.AndroidMkEntries) {
+ android.AssertStringEquals(t, message+" LOCAL_MODULE", expectedModule,
+ entries.EntryMap["LOCAL_MODULE"][0])
+
+ android.AssertStringEquals(t, message+" LOCAL_MODULE_CLASS", "ETC",
+ entries.EntryMap["LOCAL_MODULE_CLASS"][0])
+
+ android.AssertStringDoesContain(t, message+" LOCAL_PREBUILT_MODULE_FILE",
+ entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"][0], expectedPrebuiltModuleFile)
+
+ android.AssertStringDoesContain(t, message+" LOCAL_MODULE_PATH",
+ entries.EntryMap["LOCAL_MODULE_PATH"][0], expectedModulePath)
+
+ android.AssertStringEquals(t, message+" LOCAL_INSTALLED_MODULE_STEM",
+ expectedInstalledModuleStem, entries.EntryMap["LOCAL_INSTALLED_MODULE_STEM"][0])
+
+ android.AssertStringEquals(t, message+" LOCAL_NOT_AVAILABLE_FOR_PLATFORM",
+ "false", entries.EntryMap["LOCAL_NOT_AVAILABLE_FOR_PLATFORM"][0])
+}
+
+func TestAndroidMkEntriesForApex(t *testing.T) {
+ preparers := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ PrepareForTestWithFakeApexMutator,
+ dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
+ )
+
+ // An APEX system server jar.
+ result := preparers.RunTestWithBp(t, `
+ java_library {
+ name: "service-foo",
+ installable: true,
+ srcs: ["a.java"],
+ apex_available: ["com.android.apex1"],
+ }`)
+ ctx := result.TestContext
+ module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
+
+ entriesList := android.AndroidMkEntriesForTest(t, ctx, module.Module())
+ entriesList = filterDexpreoptEntriesList(entriesList)
+
+ android.AssertIntEquals(t, "entries count", 2, len(entriesList))
+
+ verifyEntries(t,
+ "entriesList[0]",
+ "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
+ "/dexpreopt/oat/arm64/javalib.odex",
+ "/system/framework/oat/arm64",
+ "apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
+ entriesList[0])
+
+ verifyEntries(t,
+ "entriesList[1]",
+ "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
+ "/dexpreopt/oat/arm64/javalib.vdex",
+ "/system/framework/oat/arm64",
+ "apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
+ entriesList[1])
+
+ // Not an APEX system server jar.
+ result = preparers.RunTestWithBp(t, `
+ java_library {
+ name: "foo",
+ installable: true,
+ srcs: ["a.java"],
+ }`)
+ ctx = result.TestContext
+ module = ctx.ModuleForTests("foo", "android_common")
+
+ entriesList = android.AndroidMkEntriesForTest(t, ctx, module.Module())
+ entriesList = filterDexpreoptEntriesList(entriesList)
+
+ android.AssertIntEquals(t, "entries count", 0, len(entriesList))
+}
diff --git a/java/java.go b/java/java.go
index 1a052b4..e2665ef 100644
--- a/java/java.go
+++ b/java/java.go
@@ -487,7 +487,7 @@
}
// Store uncompressed dex files that are preopted on /system.
- if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) {
+ if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, dexpreopter.installPath)) {
return true
}
if ctx.Config().UncompressPrivAppDex() &&
@@ -508,7 +508,8 @@
}
j.checkSdkVersions(ctx)
- j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
+ j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
+ ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
if j.dexProperties.Uncompress_dex == nil {
// If the value was not force-set by the user, use reasonable default based on the module.
@@ -1368,7 +1369,8 @@
// Dex compilation
- j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", jarName)
+ j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
+ ctx, android.PathForModuleInstall(ctx, "framework", jarName))
if j.dexProperties.Uncompress_dex == nil {
// If the value was not force-set by the user, use reasonable default based on the module.
j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
@@ -1509,7 +1511,7 @@
return Bool(j.properties.Installable)
}
-var _ dexpreopterInterface = (*Import)(nil)
+var _ DexpreopterInterface = (*Import)(nil)
// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module.
//
@@ -1622,7 +1624,8 @@
j.hideApexVariantFromMake = true
}
- j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
+ j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
+ ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
diff --git a/java/testing.go b/java/testing.go
index 8860b45..d8a77cf 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -431,3 +431,45 @@
output := sourceGlobalCompatConfig.Output(allOutputs[0])
android.AssertPathsRelativeToTopEquals(t, message+": inputs", expectedPaths, output.Implicits)
}
+
+// Register the fake APEX mutator to `android.InitRegistrationContext` as if the real mutator exists
+// at runtime. This must be called in `init()` of a test if the test is going to use the fake APEX
+// mutator. Otherwise, we will be missing the runtime mutator because "soong-apex" is not a
+// dependency, which will cause an inconsistency between testing and runtime mutators.
+func RegisterFakeRuntimeApexMutator() {
+ registerFakeApexMutator(android.InitRegistrationContext)
+}
+
+var PrepareForTestWithFakeApexMutator = android.GroupFixturePreparers(
+ android.FixtureRegisterWithContext(registerFakeApexMutator),
+)
+
+func registerFakeApexMutator(ctx android.RegistrationContext) {
+ ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("apex", fakeApexMutator).Parallel()
+ })
+}
+
+type apexModuleBase interface {
+ ApexAvailable() []string
+}
+
+var _ apexModuleBase = (*Library)(nil)
+var _ apexModuleBase = (*SdkLibrary)(nil)
+
+// A fake APEX mutator that creates a platform variant and an APEX variant for modules with
+// `apex_available`. It helps us avoid a dependency on the real mutator defined in "soong-apex",
+// which will cause a cyclic dependency, and it provides an easy way to create an APEX variant for
+// testing without dealing with all the complexities in the real mutator.
+func fakeApexMutator(mctx android.BottomUpMutatorContext) {
+ switch mctx.Module().(type) {
+ case *Library, *SdkLibrary:
+ if len(mctx.Module().(apexModuleBase).ApexAvailable()) > 0 {
+ modules := mctx.CreateVariations("", "apex1000")
+ apexInfo := android.ApexInfo{
+ ApexVariationName: "apex1000",
+ }
+ mctx.SetVariationProvider(modules[1], android.ApexInfoProvider, apexInfo)
+ }
+ }
+}
diff --git a/python/python.go b/python/python.go
index 83844e6..a35a1ac 100644
--- a/python/python.go
+++ b/python/python.go
@@ -310,13 +310,16 @@
// HostToolPath returns a path if appropriate such that this module can be used as a host tool,
// fulfilling HostToolProvider interface.
func (p *Module) HostToolPath() android.OptionalPath {
- if p.installer == nil {
- // python_library is just meta module, and doesn't have any installer.
- return android.OptionalPath{}
+ if p.installer != nil {
+ if bin, ok := p.installer.(*binaryDecorator); ok {
+ // TODO: This should only be set when building host binaries -- tests built for device would be
+ // setting this incorrectly.
+ return android.OptionalPathForPath(bin.path)
+ }
}
- // TODO: This should only be set when building host binaries -- tests built for device would be
- // setting this incorrectly.
- return android.OptionalPathForPath(p.installer.(*binaryDecorator).path)
+
+ return android.OptionalPath{}
+
}
// OutputFiles returns output files based on given tag, returns an error if tag is unsupported.
diff --git a/rust/bindgen.go b/rust/bindgen.go
index be9e71e..845f258 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -29,7 +29,7 @@
defaultBindgenFlags = []string{""}
// bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures.
- bindgenClangVersion = "clang-r428724"
+ bindgenClangVersion = "clang-r433403"
_ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string {
if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" {
diff --git a/rust/config/global.go b/rust/config/global.go
index e5b334d..b163bb6 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
var pctx = android.NewPackageContext("android/soong/rust/config")
var (
- RustDefaultVersion = "1.54.0"
+ RustDefaultVersion = "1.55.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2018"
Stdlibs = []string{
diff --git a/rust/config/x86_linux_host.go b/rust/config/x86_linux_host.go
index 0aa534f..c10afd8 100644
--- a/rust/config/x86_linux_host.go
+++ b/rust/config/x86_linux_host.go
@@ -26,6 +26,7 @@
"-B${cc_config.ClangBin}",
"-fuse-ld=lld",
"-Wl,--undefined-version",
+ "--sysroot ${cc_config.LinuxGccRoot}/sysroot",
}
linuxX86Rustflags = []string{}
linuxX86Linkflags = []string{}
diff --git a/rust/coverage.go b/rust/coverage.go
index 050b811..8fdfa23 100644
--- a/rust/coverage.go
+++ b/rust/coverage.go
@@ -57,7 +57,18 @@
flags.RustFlags = append(flags.RustFlags,
"-Z instrument-coverage", "-g")
flags.LinkFlags = append(flags.LinkFlags,
- profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open")
+ profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open",
+ // Upstream LLVM change 6d2d3bd0a6 made
+ // -z,start-stop-gc the default. It drops metadata
+ // sections like __llvm_prf_data unless they are marked
+ // SHF_GNU_RETAIN. https://reviews.llvm.org/D97448
+ // marks generated sections, including __llvm_prf_data
+ // as SHF_GNU_RETAIN. However this change is not in
+ // the Rust toolchain. Since we link Rust libs with
+ // new lld, we should use nostart-stop-gc until the
+ // Rust toolchain updates past D97448.
+ "-Wl,-z,nostart-stop-gc",
+ )
deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path())
}
diff --git a/scripts/generate-notice-files.py b/scripts/generate-notice-files.py
index 49011b2..1b4acfa 100755
--- a/scripts/generate-notice-files.py
+++ b/scripts/generate-notice-files.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2012 The Android Open Source Project
#
@@ -30,20 +30,18 @@
import os
import os.path
import re
+import struct
import sys
MD5_BLOCKSIZE = 1024 * 1024
HTML_ESCAPE_TABLE = {
- "&": "&",
- '"': """,
- "'": "'",
- ">": ">",
- "<": "<",
+ b"&": b"&",
+ b'"': b""",
+ b"'": b"'",
+ b">": b">",
+ b"<": b"<",
}
-def hexify(s):
- return ("%02x"*len(s)) % tuple(map(ord, s))
-
def md5sum(filename):
"""Calculate an MD5 of the file given by FILENAME,
and return hex digest as a string.
@@ -57,20 +55,26 @@
break
sum.update(block)
f.close()
- return hexify(sum.digest())
+ return sum.hexdigest()
def html_escape(text):
"""Produce entities within text."""
- return "".join(HTML_ESCAPE_TABLE.get(c,c) for c in text)
+ # Using for i in text doesn't work since i will be an int, not a byte.
+ # There are multiple ways to solve this, but the most performant way
+ # to iterate over a byte array is to use unpack. Using the
+ # for i in range(len(text)) and using that to get a byte using array
+ # slices is twice as slow as this method.
+ return b"".join(HTML_ESCAPE_TABLE.get(i,i) for i in struct.unpack(str(len(text)) + 'c', text))
-HTML_OUTPUT_CSS="""
+HTML_OUTPUT_CSS=b"""
<style type="text/css">
body { padding: 0; font-family: sans-serif; }
.same-license { background-color: #eeeeee; border-top: 20px solid white; padding: 10px; }
.label { font-weight: bold; }
.file-list { margin-left: 1em; color: blue; }
</style>
+
"""
def combine_notice_files_html(file_hash, input_dir, output_filename):
@@ -90,13 +94,13 @@
# Open the output file, and output the header pieces
output_file = open(output_filename, "wb")
- print >> output_file, "<html><head>"
- print >> output_file, HTML_OUTPUT_CSS
- print >> output_file, '</head><body topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0">'
+ output_file.write(b"<html><head>\n")
+ output_file.write(HTML_OUTPUT_CSS)
+ output_file.write(b'</head><body topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0">\n')
# Output our table of contents
- print >> output_file, '<div class="toc">'
- print >> output_file, "<ul>"
+ output_file.write(b'<div class="toc">\n')
+ output_file.write(b"<ul>\n")
# Flatten the list of lists into a single list of filenames
sorted_filenames = sorted(itertools.chain.from_iterable(file_hash))
@@ -104,31 +108,28 @@
# Print out a nice table of contents
for filename in sorted_filenames:
stripped_filename = SRC_DIR_STRIP_RE.sub(r"\1", filename)
- print >> output_file, '<li><a href="#id%d">%s</a></li>' % (id_table.get(filename), stripped_filename)
+ output_file.write(('<li><a href="#id%d">%s</a></li>\n' % (id_table.get(filename), stripped_filename)).encode())
- print >> output_file, "</ul>"
- print >> output_file, "</div><!-- table of contents -->"
+ output_file.write(b"</ul>\n")
+ output_file.write(b"</div><!-- table of contents -->\n")
# Output the individual notice file lists
- print >>output_file, '<table cellpadding="0" cellspacing="0" border="0">'
+ output_file.write(b'<table cellpadding="0" cellspacing="0" border="0">\n')
for value in file_hash:
- print >> output_file, '<tr id="id%d"><td class="same-license">' % id_table.get(value[0])
- print >> output_file, '<div class="label">Notices for file(s):</div>'
- print >> output_file, '<div class="file-list">'
+ output_file.write(('<tr id="id%d"><td class="same-license">\n' % id_table.get(value[0])).encode())
+ output_file.write(b'<div class="label">Notices for file(s):</div>\n')
+ output_file.write(b'<div class="file-list">\n')
for filename in value:
- print >> output_file, "%s <br/>" % (SRC_DIR_STRIP_RE.sub(r"\1", filename))
- print >> output_file, "</div><!-- file-list -->"
- print >> output_file
- print >> output_file, '<pre class="license-text">'
- print >> output_file, html_escape(open(value[0]).read())
- print >> output_file, "</pre><!-- license-text -->"
- print >> output_file, "</td></tr><!-- same-license -->"
- print >> output_file
- print >> output_file
- print >> output_file
+ output_file.write(("%s <br/>\n" % (SRC_DIR_STRIP_RE.sub(r"\1", filename))).encode())
+ output_file.write(b"</div><!-- file-list -->\n\n")
+ output_file.write(b'<pre class="license-text">\n')
+ with open(value[0], "rb") as notice_file:
+ output_file.write(html_escape(notice_file.read()))
+ output_file.write(b"\n</pre><!-- license-text -->\n")
+ output_file.write(b"</td></tr><!-- same-license -->\n\n\n\n")
# Finish off the file output
- print >> output_file, "</table>"
- print >> output_file, "</body></html>"
+ output_file.write(b"</table>\n")
+ output_file.write(b"</body></html>\n")
output_file.close()
def combine_notice_files_text(file_hash, input_dir, output_filename, file_title):
@@ -136,14 +137,18 @@
SRC_DIR_STRIP_RE = re.compile(input_dir + "(/.*).txt")
output_file = open(output_filename, "wb")
- print >> output_file, file_title
+ output_file.write(file_title.encode())
+ output_file.write(b"\n")
for value in file_hash:
- print >> output_file, "============================================================"
- print >> output_file, "Notices for file(s):"
- for filename in value:
- print >> output_file, SRC_DIR_STRIP_RE.sub(r"\1", filename)
- print >> output_file, "------------------------------------------------------------"
- print >> output_file, open(value[0]).read()
+ output_file.write(b"============================================================\n")
+ output_file.write(b"Notices for file(s):\n")
+ for filename in value:
+ output_file.write(SRC_DIR_STRIP_RE.sub(r"\1", filename).encode())
+ output_file.write(b"\n")
+ output_file.write(b"------------------------------------------------------------\n")
+ with open(value[0], "rb") as notice_file:
+ output_file.write(notice_file.read())
+ output_file.write(b"\n")
output_file.close()
def combine_notice_files_xml(files_with_same_hash, input_dir, output_filename):
@@ -154,26 +159,24 @@
# Set up a filename to row id table (anchors inside tables don't work in
# most browsers, but href's to table row ids do)
id_table = {}
- for file_key in files_with_same_hash.keys():
- for filename in files_with_same_hash[file_key]:
+ for file_key, files in files_with_same_hash.items():
+ for filename in files:
id_table[filename] = file_key
# Open the output file, and output the header pieces
output_file = open(output_filename, "wb")
- print >> output_file, '<?xml version="1.0" encoding="utf-8"?>'
- print >> output_file, "<licenses>"
+ output_file.write(b'<?xml version="1.0" encoding="utf-8"?>\n')
+ output_file.write(b"<licenses>\n")
# Flatten the list of lists into a single list of filenames
- sorted_filenames = sorted(id_table.keys())
+ sorted_filenames = sorted(list(id_table))
# Print out a nice table of contents
for filename in sorted_filenames:
stripped_filename = SRC_DIR_STRIP_RE.sub(r"\1", filename)
- print >> output_file, '<file-name contentId="%s">%s</file-name>' % (id_table.get(filename), stripped_filename)
-
- print >> output_file
- print >> output_file
+ output_file.write(('<file-name contentId="%s">%s</file-name>\n' % (id_table.get(filename), stripped_filename)).encode())
+ output_file.write(b"\n\n")
processed_file_keys = []
# Output the individual notice file lists
@@ -183,11 +186,13 @@
continue
processed_file_keys.append(file_key)
- print >> output_file, '<file-content contentId="%s"><![CDATA[%s]]></file-content>' % (file_key, html_escape(open(filename).read()))
- print >> output_file
+ output_file.write(('<file-content contentId="%s"><![CDATA[' % file_key).encode())
+ with open(filename, "rb") as notice_file:
+ output_file.write(html_escape(notice_file.read()))
+ output_file.write(b"]]></file-content>\n\n")
# Finish off the file output
- print >> output_file, "</licenses>"
+ output_file.write(b"</licenses>\n")
output_file.close()
def get_args():
@@ -253,7 +258,7 @@
file_md5sum = md5sum(filename)
files_with_same_hash[file_md5sum].append(filename)
- filesets = [sorted(files_with_same_hash[md5]) for md5 in sorted(files_with_same_hash.keys())]
+ filesets = [sorted(files_with_same_hash[md5]) for md5 in sorted(list(files_with_same_hash))]
combine_notice_files_text(filesets, input_dir, txt_output_file, file_title)
diff --git a/scripts/get_clang_version.py b/scripts/get_clang_version.py
index 17bc88b..64d922a 100755
--- a/scripts/get_clang_version.py
+++ b/scripts/get_clang_version.py
@@ -21,8 +21,12 @@
ANDROID_BUILD_TOP = os.environ.get("ANDROID_BUILD_TOP", ".")
+LLVM_PREBUILTS_VERSION = os.environ.get("LLVM_PREBUILTS_VERSION")
def get_clang_prebuilts_version(global_go):
+ if LLVM_PREBUILTS_VERSION:
+ return LLVM_PREBUILTS_VERSION
+
# TODO(b/187231324): Get clang version from the json file once it is no longer
# hard-coded in global.go
if global_go is None:
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index c6e98c7..db66ae2 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -26,6 +26,7 @@
"android/soong/android"
"android/soong/bazel"
"android/soong/cc"
+ "android/soong/snapshot"
"android/soong/tradefed"
)
@@ -195,6 +196,9 @@
return proptools.String(s.properties.Sub_dir)
}
+func (s *ShBinary) RelativeInstallPath() string {
+ return s.SubDir()
+}
func (s *ShBinary) Installable() bool {
return s.properties.Installable == nil || proptools.Bool(s.properties.Installable)
}
@@ -548,3 +552,5 @@
}
var Bool = proptools.Bool
+
+var _ snapshot.RelativeInstallPath = (*ShBinary)(nil)
diff --git a/snapshot/Android.bp b/snapshot/Android.bp
index f17ac53..3354993 100644
--- a/snapshot/Android.bp
+++ b/snapshot/Android.bp
@@ -11,12 +11,20 @@
"soong",
"soong-android",
],
+ // Source file name convention is to include _snapshot as a
+ // file suffix for files that are generating snapshots.
srcs: [
+ "host_fake_snapshot.go",
+ "host_snapshot.go",
"recovery_snapshot.go",
"snapshot.go",
"snapshot_base.go",
"util.go",
"vendor_snapshot.go",
],
+ testSrcs: [
+ "host_test.go",
+ "test.go",
+ ],
pluginFor: ["soong_build"],
}
diff --git a/snapshot/host_fake_snapshot.go b/snapshot/host_fake_snapshot.go
new file mode 100644
index 0000000..6b4e12b
--- /dev/null
+++ b/snapshot/host_fake_snapshot.go
@@ -0,0 +1,149 @@
+// Copyright 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package snapshot
+
+import (
+ "encoding/json"
+ "path/filepath"
+
+ "android/soong/android"
+)
+
+// The host_snapshot module creates a snapshot of host tools to be used
+// in a minimal source tree. In order to create the host_snapshot the
+// user must explicitly list the modules to be included. The
+// host-fake-snapshot, defined in this file, is a utility to help determine
+// which host modules are being used in the minimal source tree.
+//
+// The host-fake-snapshot is designed to run in a full source tree and
+// will result in a snapshot that contains an empty file for each host
+// tool found in the tree. The fake snapshot is only used to determine
+// the host modules that the minimal source tree depends on, hence the
+// snapshot uses an empty file for each module and saves on having to
+// actually build any tool to generate the snapshot. The fake snapshot
+// is compatible with an actual host_snapshot and is installed into a
+// minimal source tree via the development/vendor_snapshot/update.py
+// script.
+//
+// After generating the fake snapshot and installing into the minimal
+// source tree, the dependent modules are determined via the
+// development/vendor_snapshot/update.py script (see script for more
+// information). These modules are then used to define the actual
+// host_snapshot to be used. This is a similar process to the other
+// snapshots (vendor, recovery,...)
+//
+// Example
+//
+// Full source tree:
+// 1/ Generate fake host snapshot
+//
+// Minimal source tree:
+// 2/ Install the fake host snapshot
+// 3/ List the host modules used from the snapshot
+// 4/ Remove fake host snapshot
+//
+// Full source tree:
+// 4/ Create host_snapshot with modules identified in step 3
+//
+// Minimal source tree:
+// 5/ Install host snapshot
+// 6/ Build
+//
+// The host-fake-snapshot is a singleton module, that will be built
+// if HOST_FAKE_SNAPSHOT_ENABLE=true.
+
+func init() {
+ registerHostSnapshotComponents(android.InitRegistrationContext)
+}
+
+func registerHostSnapshotComponents(ctx android.RegistrationContext) {
+ ctx.RegisterSingletonType("host-fake-snapshot", HostToolsFakeAndroidSingleton)
+}
+
+type hostFakeSingleton struct {
+ snapshotDir string
+ zipFile android.OptionalPath
+}
+
+func (c *hostFakeSingleton) init() {
+ c.snapshotDir = "host-fake-snapshot"
+
+}
+func HostToolsFakeAndroidSingleton() android.Singleton {
+ singleton := &hostFakeSingleton{}
+ singleton.init()
+ return singleton
+}
+
+func (c *hostFakeSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ if !ctx.DeviceConfig().HostFakeSnapshotEnabled() {
+ return
+ }
+ // Find all host binary modules add 'fake' versions to snapshot
+ var outputs android.Paths
+ seen := make(map[string]bool)
+ var jsonData []SnapshotJsonFlags
+ ctx.VisitAllModules(func(module android.Module) {
+ if module.Target().Os != ctx.Config().BuildOSTarget.Os {
+ return
+ }
+ if module.Target().Arch.ArchType != ctx.Config().BuildOSTarget.Arch.ArchType {
+ return
+ }
+
+ if android.IsModulePrebuilt(module) {
+ return
+ }
+
+ if !module.Enabled() || module.IsHideFromMake() {
+ return
+ }
+ apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
+ if !apexInfo.IsForPlatform() {
+ return
+ }
+ path := hostBinToolPath(module)
+ if path.Valid() && path.String() != "" {
+ outFile := filepath.Join(c.snapshotDir, path.String())
+ if !seen[outFile] {
+ seen[outFile] = true
+ outputs = append(outputs, WriteStringToFileRule(ctx, "", outFile))
+ jsonData = append(jsonData, *hostBinJsonDesc(module))
+ }
+ }
+ })
+
+ marsh, err := json.Marshal(jsonData)
+ if err != nil {
+ ctx.Errorf("host fake snapshot json marshal failure: %#v", err)
+ return
+ }
+ outputs = append(outputs, WriteStringToFileRule(ctx, string(marsh), filepath.Join(c.snapshotDir, "host_snapshot.json")))
+ c.zipFile = zipSnapshot(ctx, c.snapshotDir, c.snapshotDir, outputs)
+
+}
+func (c *hostFakeSingleton) MakeVars(ctx android.MakeVarsContext) {
+ if !c.zipFile.Valid() {
+ return
+ }
+ ctx.Phony(
+ "host-fake-snapshot",
+ c.zipFile.Path())
+
+ ctx.DistForGoal(
+ "host-fake-snapshot",
+ c.zipFile.Path())
+
+}
diff --git a/snapshot/host_snapshot.go b/snapshot/host_snapshot.go
new file mode 100644
index 0000000..2a25a00
--- /dev/null
+++ b/snapshot/host_snapshot.go
@@ -0,0 +1,221 @@
+// Copyright 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package snapshot
+
+import (
+ "encoding/json"
+ "fmt"
+ "path/filepath"
+ "sort"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+
+ "android/soong/android"
+)
+
+//
+// The host_snapshot module creates a snapshot of the modules defined in
+// the deps property. The modules within the deps property (host tools)
+// are ones that return a valid path via HostToolPath() of the
+// HostToolProvider. The created snapshot contains the binaries and any
+// transitive PackagingSpecs of the included host tools, along with a JSON
+// meta file.
+//
+// The snapshot is installed into a source tree via
+// development/vendor_snapshot/update.py, the included modules are
+// provided as preferred prebuilts.
+//
+// To determine which tools to include in the host snapshot see
+// host_fake_snapshot.go.
+
+func init() {
+ registerHostBuildComponents(android.InitRegistrationContext)
+}
+
+func registerHostBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("host_snapshot", hostSnapshotFactory)
+}
+
+// Relative installation path
+type RelativeInstallPath interface {
+ RelativeInstallPath() string
+}
+
+type hostSnapshot struct {
+ android.ModuleBase
+ android.PackagingBase
+
+ zipFile android.OptionalPath
+ installDir android.InstallPath
+}
+
+func hostSnapshotFactory() android.Module {
+ module := &hostSnapshot{}
+ initHostToolsModule(module)
+ return module
+}
+func initHostToolsModule(module *hostSnapshot) {
+ android.InitPackageModule(module)
+ android.InitAndroidMultiTargetsArchModule(module, android.HostSupported, android.MultilibCommon)
+}
+
+var dependencyTag = struct {
+ blueprint.BaseDependencyTag
+ android.InstallAlwaysNeededDependencyTag
+ android.PackagingItemAlwaysDepTag
+}{}
+
+func (f *hostSnapshot) DepsMutator(ctx android.BottomUpMutatorContext) {
+ f.AddDeps(ctx, dependencyTag)
+}
+func (f *hostSnapshot) installFileName() string {
+ return f.Name() + ".zip"
+}
+
+// Create zipfile with JSON description, notice files... for dependent modules
+func (f *hostSnapshot) CreateMetaData(ctx android.ModuleContext, fileName string) android.OutputPath {
+ var jsonData []SnapshotJsonFlags
+ var metaPaths android.Paths
+
+ metaZipFile := android.PathForModuleOut(ctx, fileName).OutputPath
+
+ // Create JSON file based on the direct dependencies
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ desc := hostBinJsonDesc(dep)
+ if desc != nil {
+ jsonData = append(jsonData, *desc)
+ }
+ if len(dep.EffectiveLicenseFiles()) > 0 {
+ noticeFile := android.PathForModuleOut(ctx, "NOTICE_FILES", dep.Name()+".txt").OutputPath
+ android.CatFileRule(ctx, dep.EffectiveLicenseFiles(), noticeFile)
+ metaPaths = append(metaPaths, noticeFile)
+ }
+
+ })
+ // Sort notice paths and json data for repeatble build
+ sort.Slice(jsonData, func(i, j int) bool {
+ return (jsonData[i].ModuleName < jsonData[j].ModuleName)
+ })
+ sort.Slice(metaPaths, func(i, j int) bool {
+ return (metaPaths[i].String() < metaPaths[j].String())
+ })
+
+ marsh, err := json.Marshal(jsonData)
+ if err != nil {
+ ctx.ModuleErrorf("host snapshot json marshal failure: %#v", err)
+ return android.OutputPath{}
+ }
+
+ jsonZipFile := android.PathForModuleOut(ctx, "host_snapshot.json").OutputPath
+ metaPaths = append(metaPaths, jsonZipFile)
+ rspFile := android.PathForModuleOut(ctx, "host_snapshot.rsp").OutputPath
+ android.WriteFileRule(ctx, jsonZipFile, string(marsh))
+
+ builder := android.NewRuleBuilder(pctx, ctx)
+
+ builder.Command().
+ BuiltTool("soong_zip").
+ FlagWithArg("-C ", android.PathForModuleOut(ctx).OutputPath.String()).
+ FlagWithOutput("-o ", metaZipFile).
+ FlagWithRspFileInputList("-r ", rspFile, metaPaths)
+ builder.Build("zip_meta", fmt.Sprintf("zipping meta data for %s", ctx.ModuleName()))
+
+ return metaZipFile
+}
+
+// Create the host tool zip file
+func (f *hostSnapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Create a zip file for the binaries, and a zip of the meta data, then merge zips
+ depsZipFile := android.PathForModuleOut(ctx, f.Name()+"_deps.zip").OutputPath
+ modsZipFile := android.PathForModuleOut(ctx, f.Name()+"_mods.zip").OutputPath
+ outputFile := android.PathForModuleOut(ctx, f.installFileName()).OutputPath
+
+ f.installDir = android.PathForModuleInstall(ctx)
+
+ f.CopyDepsToZip(ctx, depsZipFile)
+
+ builder := android.NewRuleBuilder(pctx, ctx)
+ builder.Command().
+ BuiltTool("zip2zip").
+ FlagWithInput("-i ", depsZipFile).
+ FlagWithOutput("-o ", modsZipFile).
+ Text("**/*:" + proptools.ShellEscape(f.installDir.String()))
+
+ metaZipFile := f.CreateMetaData(ctx, f.Name()+"_meta.zip")
+
+ builder.Command().
+ BuiltTool("merge_zips").
+ Output(outputFile).
+ Input(metaZipFile).
+ Input(modsZipFile)
+
+ builder.Build("manifest", fmt.Sprintf("Adding manifest %s", f.installFileName()))
+ zip := ctx.InstallFile(f.installDir, f.installFileName(), outputFile)
+ f.zipFile = android.OptionalPathForPath(zip)
+
+}
+
+// Implements android.AndroidMkEntriesProvider
+func (f *hostSnapshot) AndroidMkEntries() []android.AndroidMkEntries {
+ if !f.zipFile.Valid() {
+ return []android.AndroidMkEntries{}
+ }
+
+ return []android.AndroidMkEntries{android.AndroidMkEntries{
+ Class: "ETC",
+ OutputFile: f.zipFile,
+ DistFiles: android.MakeDefaultDistFiles(f.zipFile.Path()),
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetString("LOCAL_MODULE_PATH", f.installDir.ToMakePath().String())
+ entries.SetString("LOCAL_INSTALLED_MODULE_STEM", f.installFileName())
+ },
+ },
+ }}
+}
+
+// Get host tools path and relative install string helpers
+func hostBinToolPath(m android.Module) android.OptionalPath {
+ if provider, ok := m.(android.HostToolProvider); ok {
+ return provider.HostToolPath()
+ }
+ return android.OptionalPath{}
+
+}
+func hostRelativePathString(m android.Module) string {
+ var outString string
+ if rel, ok := m.(RelativeInstallPath); ok {
+ outString = rel.RelativeInstallPath()
+ }
+ return outString
+}
+
+// Create JSON description for given module, only create descriptions for binary modueles which
+// provide a valid HostToolPath
+func hostBinJsonDesc(m android.Module) *SnapshotJsonFlags {
+ path := hostBinToolPath(m)
+ relPath := hostRelativePathString(m)
+ if path.Valid() && path.String() != "" {
+ return &SnapshotJsonFlags{
+ ModuleName: m.Name(),
+ ModuleStemName: filepath.Base(path.String()),
+ Filename: path.String(),
+ Required: append(m.HostRequiredModuleNames(), m.RequiredModuleNames()...),
+ RelativeInstallPath: relPath,
+ }
+ }
+ return nil
+}
diff --git a/snapshot/host_test.go b/snapshot/host_test.go
new file mode 100644
index 0000000..ab9fedd
--- /dev/null
+++ b/snapshot/host_test.go
@@ -0,0 +1,170 @@
+// Copyright 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package snapshot
+
+import (
+ "path/filepath"
+ "testing"
+
+ "android/soong/android"
+)
+
+// host_snapshot and host-fake-snapshot test functions
+
+type hostTestModule struct {
+ android.ModuleBase
+ props struct {
+ Deps []string
+ }
+}
+
+func hostTestBinOut(bin string) string {
+ return filepath.Join("out", "bin", bin)
+}
+
+func (c *hostTestModule) HostToolPath() android.OptionalPath {
+ return (android.OptionalPathForPath(android.PathForTesting(hostTestBinOut(c.Name()))))
+}
+
+func hostTestModuleFactory() android.Module {
+ m := &hostTestModule{}
+ m.AddProperties(&m.props)
+ android.InitAndroidArchModule(m, android.HostSupported, android.MultilibFirst)
+ return m
+}
+func (m *hostTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ builtFile := android.PathForModuleOut(ctx, m.Name())
+ dir := ctx.Target().Arch.ArchType.Multilib
+ installDir := android.PathForModuleInstall(ctx, dir)
+ ctx.InstallFile(installDir, m.Name(), builtFile)
+}
+
+// Common blueprint used for testing
+var hostTestBp = `
+ license_kind {
+ name: "test_notice",
+ conditions: ["notice"],
+ }
+ license {
+ name: "host_test_license",
+ visibility: ["//visibility:public"],
+ license_kinds: [
+ "test_notice"
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+ }
+ component {
+ name: "foo",
+ deps: ["bar"],
+ }
+ component {
+ name: "bar",
+ licenses: ["host_test_license"],
+ }
+ `
+
+var hostTestModBp = `
+ host_snapshot {
+ name: "test-host-snapshot",
+ deps: [
+ "foo",
+ ],
+ }
+ `
+
+var prepareForHostTest = android.GroupFixturePreparers(
+ android.PrepareForTestWithAndroidBuildComponents,
+ android.PrepareForTestWithLicenses,
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("component", hostTestModuleFactory)
+ }),
+)
+
+// Prepare for host_snapshot test
+var prepareForHostModTest = android.GroupFixturePreparers(
+ prepareForHostTest,
+ android.FixtureWithRootAndroidBp(hostTestBp+hostTestModBp),
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ registerHostBuildComponents(ctx)
+ }),
+)
+
+// Prepare for fake host snapshot test disabled
+var prepareForFakeHostTest = android.GroupFixturePreparers(
+ prepareForHostTest,
+ android.FixtureWithRootAndroidBp(hostTestBp),
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ registerHostSnapshotComponents(ctx)
+ }),
+)
+
+// Prepare for fake host snapshot test enabled
+var prepareForFakeHostTestEnabled = android.GroupFixturePreparers(
+ prepareForFakeHostTest,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.HostFakeSnapshotEnabled = true
+ }),
+)
+
+// Validate that a hostSnapshot object is created containing zip files and JSON file
+// content of zip file is not validated as this is done by PackagingSpecs
+func TestHostSnapshot(t *testing.T) {
+ result := prepareForHostModTest.RunTest(t)
+ t.Helper()
+ ctx := result.TestContext.ModuleForTests("test-host-snapshot", result.Config.BuildOS.String()+"_common")
+ mod := ctx.Module().(*hostSnapshot)
+ if ctx.MaybeOutput("host_snapshot.json").Rule == nil {
+ t.Error("Manifest file not found")
+ }
+ zips := []string{"_deps.zip", "_mods.zip", ".zip"}
+
+ for _, zip := range zips {
+ zFile := mod.Name() + zip
+ if ctx.MaybeOutput(zFile).Rule == nil {
+ t.Error("Zip file ", zFile, "not found")
+ }
+
+ }
+}
+
+// Validate fake host snapshot contains binary modules as well as the JSON meta file
+func TestFakeHostSnapshotEnable(t *testing.T) {
+ result := prepareForFakeHostTestEnabled.RunTest(t)
+ t.Helper()
+ bins := []string{"foo", "bar"}
+ ctx := result.TestContext.SingletonForTests("host-fake-snapshot")
+ if ctx.MaybeOutput(filepath.Join("host-fake-snapshot", "host_snapshot.json")).Rule == nil {
+ t.Error("Manifest file not found")
+ }
+ for _, bin := range bins {
+ if ctx.MaybeOutput(filepath.Join("host-fake-snapshot", hostTestBinOut(bin))).Rule == nil {
+ t.Error("Binary file ", bin, "not found")
+ }
+
+ }
+}
+
+// Validate not fake host snapshot if HostFakeSnapshotEnabled has not been set to true
+func TestFakeHostSnapshotDisable(t *testing.T) {
+ result := prepareForFakeHostTest.RunTest(t)
+ t.Helper()
+ ctx := result.TestContext.SingletonForTests("host-fake-snapshot")
+ if len(ctx.AllOutputs()) != 0 {
+ t.Error("Fake host snapshot not empty when disabled")
+ }
+
+}
diff --git a/snapshot/snapshot_base.go b/snapshot/snapshot_base.go
index de93f3e..79d3cf6 100644
--- a/snapshot/snapshot_base.go
+++ b/snapshot/snapshot_base.go
@@ -102,3 +102,19 @@
return isDirectoryExcluded(filepath.Dir(dir), excludedMap, includedMap)
}
}
+
+// This is to be saved as .json files, which is for development/vendor_snapshot/update.py.
+// These flags become Android.bp snapshot module properties.
+//
+// Attributes are optional and will be populated based on each module's need.
+// Common attributes are defined here, languages may extend this struct to add
+// additional attributes.
+type SnapshotJsonFlags struct {
+ ModuleName string `json:",omitempty"`
+ RelativeInstallPath string `json:",omitempty"`
+ Filename string `json:",omitempty"`
+ ModuleStemName string `json:",omitempty"`
+
+ // dependencies
+ Required []string `json:",omitempty"`
+}
diff --git a/snapshot/test.go b/snapshot/test.go
new file mode 100644
index 0000000..346af2b
--- /dev/null
+++ b/snapshot/test.go
@@ -0,0 +1,24 @@
+// Copyright 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package snapshot
+
+import (
+ "os"
+ "testing"
+)
+
+func TestMain(m *testing.M) {
+ os.Exit(m.Run())
+}
diff --git a/snapshot/util.go b/snapshot/util.go
index 2297dfc..f447052 100644
--- a/snapshot/util.go
+++ b/snapshot/util.go
@@ -34,3 +34,22 @@
})
return outPath
}
+
+// zip snapshot
+func zipSnapshot(ctx android.SingletonContext, dir string, baseName string, snapshotOutputs android.Paths) android.OptionalPath {
+ zipPath := android.PathForOutput(
+ ctx, dir, baseName+".zip")
+
+ zipRule := android.NewRuleBuilder(pctx, ctx)
+ rspFile := android.PathForOutput(
+ ctx, dir, baseName+"_list.rsp")
+
+ zipRule.Command().
+ BuiltTool("soong_zip").
+ FlagWithOutput("-o ", zipPath).
+ FlagWithArg("-C ", android.PathForOutput(ctx, dir).String()).
+ FlagWithRspFileInputList("-r ", rspFile, snapshotOutputs)
+
+ zipRule.Build(zipPath.String(), baseName+" snapshot "+zipPath.String())
+ return android.OptionalPathForPath(zipPath)
+}
diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go
index 65b91bc..a3a1aaf 100644
--- a/ui/build/cleanbuild.go
+++ b/ui/build/cleanbuild.go
@@ -250,7 +250,10 @@
newFile = filepath.Join(basePath, newFile)
oldFile := newFile + ".previous"
- if _, err := os.Stat(newFile); err != nil {
+ if _, err := os.Stat(newFile); os.IsNotExist(err) {
+ // If the file doesn't exist, assume no installed files exist either
+ return
+ } else if err != nil {
ctx.Fatalf("Expected %q to be readable", newFile)
}