Merge "Do not replace the direct edge between rdeps and java_sdk_library" into main
diff --git a/bin/soongdbg b/bin/soongdbg
new file mode 100755
index 0000000..132a0f0
--- /dev/null
+++ b/bin/soongdbg
@@ -0,0 +1,313 @@
+#!/usr/bin/env python3
+
+import argparse
+import fnmatch
+import json
+import os
+import pathlib
+import types
+import sys
+
+
+class Graph:
+ def __init__(self, modules):
+ def get_or_make_node(dictionary, id, module):
+ node = dictionary.get(id)
+ if node:
+ if module and not node.module:
+ node.module = module
+ return node
+ node = Node(id, module)
+ dictionary[id] = node
+ return node
+ self.nodes = dict()
+ for module in modules.values():
+ node = get_or_make_node(self.nodes, module.id, module)
+ for d in module.deps:
+ dep = get_or_make_node(self.nodes, d.id, None)
+ node.deps.add(dep)
+ dep.rdeps.add(node)
+
+ def find_paths(self, id1, id2):
+ # Throws KeyError if one of the names isn't found
+ def recurse(node1, node2, visited):
+ result = set()
+ for dep in node1.rdeps:
+ if dep == node2:
+ result.add(node2)
+ if dep not in visited:
+ visited.add(dep)
+ found = recurse(dep, node2, visited)
+ if found:
+ result |= found
+ result.add(dep)
+ return result
+ node1 = self.nodes[id1]
+ node2 = self.nodes[id2]
+ # Take either direction
+ p = recurse(node1, node2, set())
+ if p:
+ p.add(node1)
+ return p
+ p = recurse(node2, node1, set())
+ p.add(node2)
+ return p
+
+
+class Node:
+ def __init__(self, id, module):
+ self.id = id
+ self.module = module
+ self.deps = set()
+ self.rdeps = set()
+
+
+PROVIDERS = [
+ "android/soong/java.JarJarProviderData",
+ "android/soong/java.BaseJarJarProviderData",
+]
+
+
+def format_node_label(node):
+ if not node.module:
+ return node.id
+ if node.module.debug:
+ module_debug = f"<tr><td>{node.module.debug}</td></tr>"
+ else:
+ module_debug = ""
+
+ result = (f"<<table border=\"0\" cellborder=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
+ + f"<tr><td><b>{node.module.name}</b></td></tr>"
+ + module_debug
+ + f"<tr><td>{node.module.type}</td></tr>")
+ for p in node.module.providers:
+ if p.type in PROVIDERS:
+ result += "<tr><td><font color=\"#666666\">" + format_provider(p) + "</font></td></tr>"
+ result += "</table>>"
+ return result
+
+
+def format_source_pos(file, lineno):
+ result = file
+ if lineno:
+ result += f":{lineno}"
+ return result
+
+
+STRIP_TYPE_PREFIXES = [
+ "android/soong/",
+ "github.com/google/",
+]
+
+
+def format_provider(provider):
+ result = ""
+ for prefix in STRIP_TYPE_PREFIXES:
+ if provider.type.startswith(prefix):
+ result = provider.type[len(prefix):]
+ break
+ if not result:
+ result = provider.type
+ if True and provider.debug:
+ result += " (" + provider.debug + ")"
+ return result
+
+
+def load_soong_debug():
+ # Read the json
+ try:
+ with open(SOONG_DEBUG_DATA_FILENAME) as f:
+ info = json.load(f, object_hook=lambda d: types.SimpleNamespace(**d))
+ except IOError:
+ sys.stderr.write(f"error: Unable to open {SOONG_DEBUG_DATA_FILENAME}. Make sure you have"
+ + " built with GENERATE_SOONG_DEBUG.\n")
+ sys.exit(1)
+
+ # Construct IDs, which are name + variant if the
+ name_counts = dict()
+ for m in info.modules:
+ name_counts[m.name] = name_counts.get(m.name, 0) + 1
+ def get_id(m):
+ result = m.name
+ if name_counts[m.name] > 1 and m.variant:
+ result += "@@" + m.variant
+ return result
+ for m in info.modules:
+ m.id = get_id(m)
+ for dep in m.deps:
+ dep.id = get_id(dep)
+
+ return info
+
+
+def load_modules():
+ info = load_soong_debug()
+
+ # Filter out unnamed modules
+ modules = dict()
+ for m in info.modules:
+ if not m.name:
+ continue
+ modules[m.id] = m
+
+ return modules
+
+
+def load_graph():
+ modules=load_modules()
+ return Graph(modules)
+
+
+def module_selection_args(parser):
+ parser.add_argument("modules", nargs="*",
+ help="Modules to match. Can be glob-style wildcards.")
+ parser.add_argument("--provider", nargs="+",
+ help="Match the given providers.")
+ parser.add_argument("--dep", nargs="+",
+ help="Match the given providers.")
+
+
+def load_and_filter_modules(args):
+ # Which modules are printed
+ matchers = []
+ if args.modules:
+ matchers.append(lambda m: [True for pattern in args.modules
+ if fnmatch.fnmatchcase(m.name, pattern)])
+ if args.provider:
+ matchers.append(lambda m: [True for pattern in args.provider
+ if [True for p in m.providers if p.type.endswith(pattern)]])
+ if args.dep:
+ matchers.append(lambda m: [True for pattern in args.dep
+ if [True for d in m.deps if d.id == pattern]])
+
+ if not matchers:
+ sys.stderr.write("error: At least one module matcher must be supplied\n")
+ sys.exit(1)
+
+ info = load_soong_debug()
+ for m in sorted(info.modules, key=lambda m: (m.name, m.variant)):
+ if len([matcher for matcher in matchers if matcher(m)]) == len(matchers):
+ yield m
+
+
+def print_nodes(nodes):
+ print("digraph {")
+ for node in nodes:
+ print(f"\"{node.id}\"[label={format_node_label(node)}];")
+ for dep in node.deps:
+ if dep in nodes:
+ print(f"\"{node.id}\" -> \"{dep.id}\";")
+ print("}")
+
+
+def get_deps(nodes, root):
+ if root in nodes:
+ return
+ nodes.add(root)
+ for dep in root.deps:
+ get_deps(nodes, dep)
+
+
+class BetweenCommand:
+ help = "Print the module graph between two nodes."
+
+ def args(self, parser):
+ parser.add_argument("module", nargs=2,
+ help="The two modules")
+
+ def run(self, args):
+ graph = load_graph()
+ print_nodes(graph.find_paths(args.module[0], args.module[1]))
+
+
+class DepsCommand:
+ help = "Print the module graph of dependencies of one or more modules"
+
+ def args(self, parser):
+ parser.add_argument("module", nargs="+",
+ help="Module to print dependencies of")
+
+ def run(self, args):
+ graph = load_graph()
+ nodes = set()
+ err = False
+ for id in sys.argv[3:]:
+ root = graph.nodes.get(id)
+ if not root:
+ sys.stderr.write(f"error: Can't find root: {id}\n")
+ err = True
+ continue
+ get_deps(nodes, root)
+ if err:
+ sys.exit(1)
+ print_nodes(nodes)
+
+
+class IdCommand:
+ help = "Print the id (name + variant) of matching modules"
+
+ def args(self, parser):
+ module_selection_args(parser)
+
+ def run(self, args):
+ for m in load_and_filter_modules(args):
+ print(m.id)
+
+
+class QueryCommand:
+ help = "Query details about modules"
+
+ def args(self, parser):
+ module_selection_args(parser)
+
+ def run(self, args):
+ for m in load_and_filter_modules(args):
+ print(m.id)
+ print(f" type: {m.type}")
+ print(f" location: {format_source_pos(m.source_file, m.source_line)}")
+ for p in m.providers:
+ print(f" provider: {format_provider(p)}")
+ for d in m.deps:
+ print(f" dep: {d.id}")
+
+
+COMMANDS = {
+ "between": BetweenCommand(),
+ "deps": DepsCommand(),
+ "id": IdCommand(),
+ "query": QueryCommand(),
+}
+
+
+def assert_env(name):
+ val = os.getenv(name)
+ if not val:
+ sys.stderr.write(f"{name} not set. please make sure you've run lunch.")
+ return val
+
+ANDROID_BUILD_TOP = assert_env("ANDROID_BUILD_TOP")
+
+TARGET_PRODUCT = assert_env("TARGET_PRODUCT")
+OUT_DIR = os.getenv("OUT_DIR")
+if not OUT_DIR:
+ OUT_DIR = "out"
+if OUT_DIR[0] != "/":
+ OUT_DIR = pathlib.Path(ANDROID_BUILD_TOP).joinpath(OUT_DIR)
+SOONG_DEBUG_DATA_FILENAME = pathlib.Path(OUT_DIR).joinpath("soong/soong-debug-info.json")
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers(required=True, dest="command")
+ for name in sorted(COMMANDS.keys()):
+ command = COMMANDS[name]
+ subparser = subparsers.add_parser(name, help=command.help)
+ command.args(subparser)
+ args = parser.parse_args()
+ COMMANDS[args.command].run(args)
+ sys.exit(0)
+
+
+if __name__ == "__main__":
+ main()
+
diff --git a/cc/config/global.go b/cc/config/global.go
index 5fed7f1..c562614 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -253,6 +253,14 @@
// http://b/161386391 for -Wno-pointer-to-int-cast
"-Wno-pointer-to-int-cast",
"-Werror=fortify-source",
+ // http://b/315246135 temporarily disabled
+ "-Wno-error=unused-variable",
+ // http://b/315250603 temporarily disabled
+ "-Wno-error=format",
+ // Disabled because it produces many false positives. http://b/323050926
+ "-Wno-missing-field-initializers",
+ // http://b/323050889
+ "-Wno-packed-non-pod",
"-Werror=address-of-temporary",
"-Werror=incompatible-function-pointer-types",
@@ -351,11 +359,16 @@
// enabling since it's a cosmetic issue.
"-Wno-bitwise-instead-of-logical",
- "-Wno-unused-but-set-variable",
+ "-Wno-unused",
+ "-Wno-unused-parameter",
"-Wno-unused-but-set-parameter",
"-Wno-unqualified-std-cast-call",
"-Wno-array-parameter",
"-Wno-gnu-offsetof-extensions",
+ // TODO: Enable this warning http://b/315245071
+ "-Wno-fortify-source",
+ "-Wno-tautological-negation-compare",
+ "-Wno-tautological-undefined-compare",
}
llvmNextExtraCommonGlobalCflags = []string{
@@ -375,8 +388,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r498229b"
- ClangDefaultShortVersion = "17"
+ ClangDefaultVersion = "clang-r510928"
+ ClangDefaultShortVersion = "18"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 4727566..673f305 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -79,6 +79,7 @@
flag.BoolVar(&cmdlineArgs.MultitreeBuild, "multitree-build", false, "this is a multitree build")
flag.BoolVar(&cmdlineArgs.BuildFromSourceStub, "build-from-source-stub", false, "build Java stubs from source files instead of API text files")
flag.BoolVar(&cmdlineArgs.EnsureAllowlistIntegrity, "ensure-allowlist-integrity", false, "verify that allowlisted modules are mixed-built")
+ flag.StringVar(&cmdlineArgs.ModuleDebugFile, "soong_module_debug", "", "soong module debug info file to write")
// Flags that probably shouldn't be flags of soong_build, but we haven't found
// the time to remove them yet
flag.BoolVar(&cmdlineArgs.RunGoTests, "t", false, "build and run go tests during bootstrap")
diff --git a/java/androidmk.go b/java/androidmk.go
index b523594..b7df9bf 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -549,8 +549,8 @@
if BoolDefault(jd.properties.Installable, true) {
entries.SetPath("LOCAL_DROIDDOC_DOC_ZIP", jd.docZip)
}
- if jd.stubsSrcJar != nil {
- entries.SetPath("LOCAL_DROIDDOC_STUBS_SRCJAR", jd.stubsSrcJar)
+ if jd.exportableStubsSrcJar != nil {
+ entries.SetPath("LOCAL_DROIDDOC_STUBS_SRCJAR", jd.exportableStubsSrcJar)
}
},
},
@@ -596,17 +596,17 @@
Include: "$(BUILD_SYSTEM)/soong_droiddoc_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- if dstubs.Javadoc.stubsSrcJar != nil {
- entries.SetPath("LOCAL_DROIDDOC_STUBS_SRCJAR", dstubs.Javadoc.stubsSrcJar)
+ if dstubs.Javadoc.exportableStubsSrcJar != nil {
+ entries.SetPath("LOCAL_DROIDDOC_STUBS_SRCJAR", dstubs.Javadoc.exportableStubsSrcJar)
}
if dstubs.everythingArtifacts.apiVersionsXml != nil {
- entries.SetPath("LOCAL_DROIDDOC_API_VERSIONS_XML", dstubs.everythingArtifacts.apiVersionsXml)
+ entries.SetPath("LOCAL_DROIDDOC_API_VERSIONS_XML", dstubs.exportableArtifacts.apiVersionsXml)
}
if dstubs.everythingArtifacts.annotationsZip != nil {
- entries.SetPath("LOCAL_DROIDDOC_ANNOTATIONS_ZIP", dstubs.everythingArtifacts.annotationsZip)
+ entries.SetPath("LOCAL_DROIDDOC_ANNOTATIONS_ZIP", dstubs.exportableArtifacts.annotationsZip)
}
if dstubs.everythingArtifacts.metadataZip != nil {
- entries.SetPath("LOCAL_DROIDDOC_METADATA_ZIP", dstubs.everythingArtifacts.metadataZip)
+ entries.SetPath("LOCAL_DROIDDOC_METADATA_ZIP", dstubs.exportableArtifacts.metadataZip)
}
},
},
diff --git a/java/droidstubs.go b/java/droidstubs.go
index dc3a0ec..4267545 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -333,66 +333,89 @@
}
}
-func (d *Droidstubs) AnnotationsZip(stubsType StubsType) (android.Path, error) {
+func (d *Droidstubs) AnnotationsZip(stubsType StubsType) (ret android.Path, err error) {
switch stubsType {
case Everything:
- return d.everythingArtifacts.annotationsZip, nil
+ ret, err = d.everythingArtifacts.annotationsZip, nil
case Exportable:
- return d.exportableArtifacts.annotationsZip, nil
+ ret, err = d.exportableArtifacts.annotationsZip, nil
default:
- return nil, fmt.Errorf("annotations zip not supported for the stub type %s", stubsType.String())
+ ret, err = nil, fmt.Errorf("annotations zip not supported for the stub type %s", stubsType.String())
}
+ return ret, err
}
-func (d *Droidstubs) ApiFilePath(stubsType StubsType) (android.Path, error) {
+func (d *Droidstubs) ApiFilePath(stubsType StubsType) (ret android.Path, err error) {
switch stubsType {
case Everything:
- return d.apiFile, nil
+ ret, err = d.apiFile, nil
case Exportable:
- return d.exportableApiFile, nil
+ ret, err = d.exportableApiFile, nil
default:
- return nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
+ ret, err = nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
}
+ if ret == nil && err == nil {
+ err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
+ }
+ return ret, err
}
-func (d *Droidstubs) ApiVersionsXmlFilePath(stubsType StubsType) (android.Path, error) {
+func (d *Droidstubs) ApiVersionsXmlFilePath(stubsType StubsType) (ret android.Path, err error) {
switch stubsType {
case Everything:
- return d.everythingArtifacts.apiVersionsXml, nil
- default:
- return nil, fmt.Errorf("api versions xml file path not supported for the stub type %s", stubsType.String())
- }
-}
-
-func (d *Droidstubs) DocZip(stubsType StubsType) (android.Path, error) {
- switch stubsType {
- case Everything:
- return d.docZip, nil
- default:
- return nil, fmt.Errorf("docs zip not supported for the stub type %s", stubsType.String())
- }
-}
-
-func (d *Droidstubs) RemovedApiFilePath(stubsType StubsType) (android.Path, error) {
- switch stubsType {
- case Everything:
- return d.removedApiFile, nil
+ ret, err = d.everythingArtifacts.apiVersionsXml, nil
case Exportable:
- return d.exportableRemovedApiFile, nil
+ ret, err = d.exportableArtifacts.apiVersionsXml, nil
default:
- return nil, fmt.Errorf("removed api file path not supported for the stub type %s", stubsType.String())
+ ret, err = nil, fmt.Errorf("api versions xml file path not supported for the stub type %s", stubsType.String())
}
+ if ret == nil && err == nil {
+ err = fmt.Errorf("api versions xml file is null for the stub type %s", stubsType.String())
+ }
+ return ret, err
}
-func (d *Droidstubs) StubsSrcJar(stubsType StubsType) (android.Path, error) {
+func (d *Droidstubs) DocZip(stubsType StubsType) (ret android.Path, err error) {
switch stubsType {
case Everything:
- return d.stubsSrcJar, nil
- case Exportable:
- return d.exportableStubsSrcJar, nil
+ ret, err = d.docZip, nil
default:
- return nil, fmt.Errorf("stubs srcjar not supported for the stub type %s", stubsType.String())
+ ret, err = nil, fmt.Errorf("docs zip not supported for the stub type %s", stubsType.String())
}
+ if ret == nil && err == nil {
+ err = fmt.Errorf("docs zip is null for the stub type %s", stubsType.String())
+ }
+ return ret, err
+}
+
+func (d *Droidstubs) RemovedApiFilePath(stubsType StubsType) (ret android.Path, err error) {
+ switch stubsType {
+ case Everything:
+ ret, err = d.removedApiFile, nil
+ case Exportable:
+ ret, err = d.exportableRemovedApiFile, nil
+ default:
+ ret, err = nil, fmt.Errorf("removed api file path not supported for the stub type %s", stubsType.String())
+ }
+ if ret == nil && err == nil {
+ err = fmt.Errorf("removed api file is null for the stub type %s", stubsType.String())
+ }
+ return ret, err
+}
+
+func (d *Droidstubs) StubsSrcJar(stubsType StubsType) (ret android.Path, err error) {
+ switch stubsType {
+ case Everything:
+ ret, err = d.stubsSrcJar, nil
+ case Exportable:
+ ret, err = d.exportableStubsSrcJar, nil
+ default:
+ ret, err = nil, fmt.Errorf("stubs srcjar not supported for the stub type %s", stubsType.String())
+ }
+ if ret == nil && err == nil {
+ err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
+ }
+ return ret, err
}
func (d *Droidstubs) CurrentApiTimestamp() android.Path {
@@ -982,8 +1005,11 @@
stubConfig: params,
}
- d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
- optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
+ if params.generateStubs {
+ d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
+ optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
+ }
+
if params.writeSdkValues {
d.exportableArtifacts.metadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
d.exportableArtifacts.metadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 77ba277..85cc220 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-r498229b"
+ bindgenClangVersion = "clang-r510928"
_ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string {
if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" {
diff --git a/ui/build/config.go b/ui/build/config.go
index 5085c68..e29d239 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -115,6 +115,11 @@
// Data source to write ninja weight list
ninjaWeightListSource NinjaWeightListSource
+
+ // This file is a detailed dump of all soong-defined modules for debugging purposes.
+ // There's quite a bit of overlap with module-info.json and soong module graph. We
+ // could consider merging them.
+ moduleDebugFile string
}
type NinjaWeightListSource uint
@@ -273,6 +278,10 @@
ret.sandboxConfig.SetSrcDirIsRO(srcDirIsWritable == "false")
}
+ if os.Getenv("GENERATE_SOONG_DEBUG") == "true" {
+ ret.moduleDebugFile, _ = filepath.Abs(shared.JoinPath(ret.SoongOutDir(), "soong-debug-info.json"))
+ }
+
ret.environ.Unset(
// We're already using it
"USE_SOONG_UI",
@@ -325,6 +334,9 @@
"ANDROID_DEV_SCRIPTS",
"ANDROID_EMULATOR_PREBUILTS",
"ANDROID_PRE_BUILD_PATHS",
+
+ // We read it here already, don't let others share in the fun
+ "GENERATE_SOONG_DEBUG",
)
if ret.UseGoma() || ret.ForceUseGoma() {
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 65e2c8e..2f25a8c 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -93,6 +93,7 @@
"fuser": Allowed,
"gcert": Allowed,
"gcertstatus": Allowed,
+ "gcloud": Allowed,
"getopt": Allowed,
"git": Allowed,
"hexdump": Allowed,
@@ -101,7 +102,6 @@
"javap": Allowed,
"lsof": Allowed,
"openssl": Allowed,
- "prodcertstatus": Allowed,
"pstree": Allowed,
"rsync": Allowed,
"sh": Allowed,
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 90c3bfc..a201ac5 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -204,6 +204,11 @@
commonArgs = append(commonArgs, "--build-from-source-stub")
}
+ if pb.config.moduleDebugFile != "" {
+ commonArgs = append(commonArgs, "--soong_module_debug")
+ commonArgs = append(commonArgs, pb.config.moduleDebugFile)
+ }
+
commonArgs = append(commonArgs, "-l", filepath.Join(pb.config.FileListDir(), "Android.bp.list"))
invocationEnv := make(map[string]string)
if pb.debugPort != "" {