Merge changes from topic "aconfig-rename-namespace-to-package"
* changes:
aconfig: include namespace in create-device-config-defaults
aconfig: improve code diffs in tests
aconfig: add namespace field to flag_declaration and parsed_flag
aconfig: allow dots in package fields
aconfig: rename namespace -> package
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index 6ba539c..5dba2d1 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -154,6 +154,10 @@
$(call add_soong_config_var_value,ANDROID,avf_enabled,$(PRODUCT_AVF_ENABLED))
endif
+ifdef PRODUCT_AVF_KERNEL_MODULES_ENABLED
+$(call add_soong_config_var_value,ANDROID,avf_kernel_modules_enabled,$(PRODUCT_AVF_KERNEL_MODULES_ENABLED))
+endif
+
# Enable system_server optimizations by default unless explicitly set or if
# there may be dependent runtime jars.
# TODO(b/240588226): Remove the off-by-default exceptions after handling
diff --git a/core/product.mk b/core/product.mk
index 818aac2..6f54b78 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -389,6 +389,9 @@
# If true, installs a full version of com.android.virt APEX.
_product_single_value_vars += PRODUCT_AVF_ENABLED
+# If true, kernel with modules will be used for Microdroid VMs.
+_product_single_value_vars += PRODUCT_AVF_KERNEL_MODULES_ENABLED
+
# List of .json files to be merged/compiled into vendor/etc/linker.config.pb
_product_list_vars += PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS
diff --git a/tools/compliance/cmd/sbom/sbom.go b/tools/compliance/cmd/sbom/sbom.go
index f61289e..a53741f 100644
--- a/tools/compliance/cmd/sbom/sbom.go
+++ b/tools/compliance/cmd/sbom/sbom.go
@@ -35,7 +35,7 @@
"github.com/google/blueprint/deptools"
"github.com/spdx/tools-golang/builder/builder2v2"
- "github.com/spdx/tools-golang/json"
+ spdx_json "github.com/spdx/tools-golang/json"
"github.com/spdx/tools-golang/spdx/common"
spdx "github.com/spdx/tools-golang/spdx/v2_2"
"github.com/spdx/tools-golang/spdxlib"
@@ -274,7 +274,7 @@
tn *compliance.TargetNode) (*projectmetadata.ProjectMetadata, error) {
pms, err := pmix.MetadataForProjects(tn.Projects()...)
if err != nil {
- return nil, fmt.Errorf("Unable to read projects for %q: %w\n", tn, err)
+ return nil, fmt.Errorf("Unable to read projects for %q: %w\n", tn.Name(), err)
}
if len(pms) == 0 {
return nil, nil
diff --git a/tools/compliance/cmd/sbom/sbom_test.go b/tools/compliance/cmd/sbom/sbom_test.go
index 8a62713..13ba66d 100644
--- a/tools/compliance/cmd/sbom/sbom_test.go
+++ b/tools/compliance/cmd/sbom/sbom_test.go
@@ -25,6 +25,7 @@
"time"
"android/soong/tools/compliance"
+
"github.com/spdx/tools-golang/builder/builder2v2"
"github.com/spdx/tools-golang/spdx/common"
spdx "github.com/spdx/tools-golang/spdx/v2_2"
@@ -2375,8 +2376,8 @@
if doc.DocumentName == "" {
return fmt.Errorf("DocumentName: got nothing, want Document Name")
}
- if fmt.Sprintf("%v", doc.CreationInfo.Creators[1].Creator) != "Google LLC" {
- return fmt.Errorf("Creator: got %v, want 'Google LLC'")
+ if c := fmt.Sprintf("%v", doc.CreationInfo.Creators[1].Creator); c != "Google LLC" {
+ return fmt.Errorf("Creator: got %v, want 'Google LLC'", c)
}
_, err := time.Parse(time.RFC3339, doc.CreationInfo.Created)
if err != nil {
diff --git a/tools/compliance/go.mod b/tools/compliance/go.mod
index 088915a..1928189 100644
--- a/tools/compliance/go.mod
+++ b/tools/compliance/go.mod
@@ -7,8 +7,11 @@
require (
android/soong v0.0.0
github.com/google/blueprint v0.0.0
+ github.com/spdx/tools-golang v0.0.0
)
+replace github.com/spdx/tools-golang v0.0.0 => ../../../../external/spdx-tools
+
require golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
replace android/soong v0.0.0 => ../../../soong
diff --git a/tools/find_static_candidates.py b/tools/find_static_candidates.py
new file mode 100644
index 0000000..7511b36
--- /dev/null
+++ b/tools/find_static_candidates.py
@@ -0,0 +1,232 @@
+#!/usr/bin/env python3
+
+"""Tool to find static libraries that maybe should be shared libraries and shared libraries that maybe should be static libraries.
+
+This tool only looks at the module-info.json for the current target.
+
+Example of "class" types for each of the modules in module-info.json
+ "EXECUTABLES": 2307,
+ "ETC": 9094,
+ "NATIVE_TESTS": 10461,
+ "APPS": 2885,
+ "JAVA_LIBRARIES": 5205,
+ "EXECUTABLES/JAVA_LIBRARIES": 119,
+ "FAKE": 553,
+ "SHARED_LIBRARIES/STATIC_LIBRARIES": 7591,
+ "STATIC_LIBRARIES": 11535,
+ "SHARED_LIBRARIES": 10852,
+ "HEADER_LIBRARIES": 1897,
+ "DYLIB_LIBRARIES": 1262,
+ "RLIB_LIBRARIES": 3413,
+ "ROBOLECTRIC": 39,
+ "PACKAGING": 5,
+ "PROC_MACRO_LIBRARIES": 36,
+ "RENDERSCRIPT_BITCODE": 17,
+ "DYLIB_LIBRARIES/RLIB_LIBRARIES": 8,
+ "ETC/FAKE": 1
+
+None of the "SHARED_LIBRARIES/STATIC_LIBRARIES" are double counted in the
+modules with one class
+RLIB/
+
+All of these classes have shared_libs and/or static_libs
+ "EXECUTABLES",
+ "SHARED_LIBRARIES",
+ "STATIC_LIBRARIES",
+ "SHARED_LIBRARIES/STATIC_LIBRARIES", # cc_library
+ "HEADER_LIBRARIES",
+ "NATIVE_TESTS", # test modules
+ "DYLIB_LIBRARIES", # rust
+ "RLIB_LIBRARIES", # rust
+ "ETC", # rust_bindgen
+"""
+
+from collections import defaultdict
+
+import json, os, argparse
+
+ANDROID_PRODUCT_OUT = os.environ.get("ANDROID_PRODUCT_OUT")
+# If a shared library is used less than MAX_SHARED_INCLUSIONS times in a target,
+# then it will likely save memory by changing it to a static library
+# This move will also use less storage
+MAX_SHARED_INCLUSIONS = 2
+# If a static library is used more than MAX_STATIC_INCLUSIONS times in a target,
+# then it will likely save memory by changing it to a shared library
+# This move will also likely use less storage
+MIN_STATIC_INCLUSIONS = 3
+
+
+def parse_args():
+ parser = argparse.ArgumentParser(
+ description=(
+ "Parse module-info.jso and display information about static and"
+ " shared library dependencies."
+ )
+ )
+ parser.add_argument(
+ "--module", dest="module", help="Print the info for the module."
+ )
+ parser.add_argument(
+ "--shared",
+ dest="print_shared",
+ action=argparse.BooleanOptionalAction,
+ help=(
+ "Print the list of libraries that are shared_libs for fewer than {}"
+ " modules.".format(MAX_SHARED_INCLUSIONS)
+ ),
+ )
+ parser.add_argument(
+ "--static",
+ dest="print_static",
+ action=argparse.BooleanOptionalAction,
+ help=(
+ "Print the list of libraries that are static_libs for more than {}"
+ " modules.".format(MIN_STATIC_INCLUSIONS)
+ ),
+ )
+ parser.add_argument(
+ "--recursive",
+ dest="recursive",
+ action=argparse.BooleanOptionalAction,
+ default=True,
+ help=(
+ "Gather all dependencies of EXECUTABLES recursvily before calculating"
+ " the stats. This eliminates duplicates from multiple libraries"
+ " including the same dependencies in a single binary."
+ ),
+ )
+ parser.add_argument(
+ "--both",
+ dest="both",
+ action=argparse.BooleanOptionalAction,
+ default=False,
+ help=(
+ "Print a list of libraries that are including libraries as both"
+ " static and shared"
+ ),
+ )
+ return parser.parse_args()
+
+
+class TransitiveHelper:
+
+ def __init__(self):
+ # keep a list of already expanded libraries so we don't end up in a cycle
+ self.visited = defaultdict(lambda: defaultdict(set))
+
+ # module is an object from the module-info dictionary
+ # module_info is the dictionary from module-info.json
+ # modify the module's shared_libs and static_libs with all of the transient
+ # dependencies required from all of the explicit dependencies
+ def flattenDeps(self, module, module_info):
+ libs_snapshot = dict(shared_libs = set(module["shared_libs"]), static_libs = set(module["static_libs"]))
+
+ for lib_class in ["shared_libs", "static_libs"]:
+ for lib in libs_snapshot[lib_class]:
+ if not lib or lib not in module_info:
+ continue
+ if lib in self.visited:
+ module[lib_class].update(self.visited[lib][lib_class])
+ else:
+ res = self.flattenDeps(module_info[lib], module_info)
+ module[lib_class].update(res[lib_class])
+ self.visited[lib][lib_class].update(res[lib_class])
+
+ return module
+
+def main():
+ module_info = json.load(open(ANDROID_PRODUCT_OUT + "/module-info.json"))
+ # turn all of the static_libs and shared_libs lists into sets to make them
+ # easier to update
+ for _, module in module_info.items():
+ module["shared_libs"] = set(module["shared_libs"])
+ module["static_libs"] = set(module["static_libs"])
+
+ args = parse_args()
+
+ if args.module:
+ if args.module not in module_info:
+ print("Module {} does not exist".format(args.module))
+ exit(1)
+
+ includedStatically = defaultdict(set)
+ includedSharedly = defaultdict(set)
+ includedBothly = defaultdict(set)
+ transitive = TransitiveHelper()
+ for name, module in module_info.items():
+ if args.recursive:
+ # in this recursive mode we only want to see what is included by the executables
+ if "EXECUTABLES" not in module["class"]:
+ continue
+ module = transitive.flattenDeps(module, module_info)
+ # filter out fuzzers by their dependency on clang
+ if "libclang_rt.fuzzer" in module["static_libs"]:
+ continue
+ else:
+ if "NATIVE_TESTS" in module["class"]:
+ # We don't care about how tests are including libraries
+ continue
+
+ # count all of the shared and static libs included in this module
+ for lib in module["shared_libs"]:
+ includedSharedly[lib].add(name)
+ for lib in module["static_libs"]:
+ includedStatically[lib].add(name)
+
+ intersection = set(module["shared_libs"]).intersection(
+ module["static_libs"]
+ )
+ if intersection:
+ includedBothly[name] = intersection
+
+ if args.print_shared:
+ print(
+ "Shared libraries that are included by fewer than {} modules on a"
+ " device:".format(MAX_SHARED_INCLUSIONS)
+ )
+ for name, libs in includedSharedly.items():
+ if len(libs) < MAX_SHARED_INCLUSIONS:
+ print("{}: {} included by: {}".format(name, len(libs), libs))
+
+ if args.print_static:
+ print(
+ "Libraries that are included statically by more than {} modules on a"
+ " device:".format(MIN_STATIC_INCLUSIONS)
+ )
+ for name, libs in includedStatically.items():
+ if len(libs) > MIN_STATIC_INCLUSIONS:
+ print("{}: {} included by: {}".format(name, len(libs), libs))
+
+ if args.both:
+ allIncludedBothly = set()
+ for name, libs in includedBothly.items():
+ allIncludedBothly.update(libs)
+
+ print(
+ "List of libraries used both statically and shared in the same"
+ " processes:\n {}\n\n".format("\n".join(sorted(allIncludedBothly)))
+ )
+ print(
+ "List of libraries used both statically and shared in any processes:\n {}".format("\n".join(sorted(includedStatically.keys() & includedSharedly.keys()))))
+
+ if args.module:
+ print(json.dumps(module_info[args.module], default=list, indent=2))
+ print(
+ "{} is included in shared_libs {} times by these modules: {}".format(
+ args.module, len(includedSharedly[args.module]),
+ includedSharedly[args.module]
+ )
+ )
+ print(
+ "{} is included in static_libs {} times by these modules: {}".format(
+ args.module, len(includedStatically[args.module]),
+ includedStatically[args.module]
+ )
+ )
+ print("Shared libs included by this module that are used in fewer than {} processes:\n{}".format(
+ MAX_SHARED_INCLUSIONS, [x for x in module_info[args.module]["shared_libs"] if len(includedSharedly[x]) < MAX_SHARED_INCLUSIONS]))
+
+
+
+if __name__ == "__main__":
+ main()