Merge "Support using api-versions.xml from another module"
diff --git a/androidmk/parser/make_strings.go b/androidmk/parser/make_strings.go
index 416e430..8afbe7e 100644
--- a/androidmk/parser/make_strings.go
+++ b/androidmk/parser/make_strings.go
@@ -234,10 +234,10 @@
if n != 0 {
split := splitFunc(s, n)
if n != -1 {
- if len(split) > n {
+ if len(split) > n || len(split) == 0 {
panic("oops!")
} else {
- n -= len(split)
+ n -= len(split) - 1
}
}
curMs.appendString(split[0])
diff --git a/androidmk/parser/make_strings_test.go b/androidmk/parser/make_strings_test.go
index e243ece..7e842a5 100644
--- a/androidmk/parser/make_strings_test.go
+++ b/androidmk/parser/make_strings_test.go
@@ -75,6 +75,16 @@
genMakeString(""),
},
},
+ {
+ // "x$(var1)y bar"
+ in: genMakeString("x", "var1", "y bar"),
+ sep: " ",
+ n: 2,
+ expected: []*MakeString{
+ genMakeString("x", "var1", "y"),
+ genMakeString("bar"),
+ },
+ },
}
func TestMakeStringSplitN(t *testing.T) {
diff --git a/cc/Android.bp b/cc/Android.bp
index 60d329e..ce94467 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -91,6 +91,7 @@
],
testSrcs: [
"afdo_test.go",
+ "binary_test.go",
"cc_test.go",
"compiler_test.go",
"gen_test.go",
diff --git a/cc/binary_test.go b/cc/binary_test.go
index 1b8b4a8..cba5974 100644
--- a/cc/binary_test.go
+++ b/cc/binary_test.go
@@ -65,7 +65,7 @@
android.AssertStringListContains(t, "missing dependency on linker_scripts",
binFoo.Implicits.Strings(), "bar.ld")
android.AssertStringDoesContain(t, "missing flag for linker_scripts",
- libfoo.Args["ldFlags"], "-Wl,--script,foo.ld")
+ binFoo.Args["ldFlags"], "-Wl,--script,foo.ld")
android.AssertStringDoesContain(t, "missing flag for linker_scripts",
- libfoo.Args["ldFlags"], "-Wl,--script,bar.ld")
+ binFoo.Args["ldFlags"], "-Wl,--script,bar.ld")
}
diff --git a/cc/config/global.go b/cc/config/global.go
index 3caf327..dc6310c 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -286,8 +286,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r450784d"
- ClangDefaultShortVersion = "14.0.6"
+ ClangDefaultVersion = "clang-r450784e"
+ ClangDefaultShortVersion = "14.0.7"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index fb9ac49..1f90843 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -46,6 +46,7 @@
"-misc-no-recursion",
"-misc-non-private-member-variables-in-classes",
"-misc-unused-parameters",
+ "-performance-no-int-to-ptr",
// the following groups are excluded by -*
// -altera-*
// -cppcoreguidelines-*
diff --git a/cmd/path_interposer/main.go b/cmd/path_interposer/main.go
index a4fe3e4..8b9de52 100644
--- a/cmd/path_interposer/main.go
+++ b/cmd/path_interposer/main.go
@@ -12,6 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// This tool tries to prohibit access to tools on the system on which the build
+// is run.
+//
+// The rationale is that if the build uses a binary that is not shipped in the
+// source tree, it is unknowable which version of that binary will be installed
+// and therefore the output of the build will be unpredictable. Therefore, we
+// should make every effort to use only tools under our control.
+//
+// This is currently implemented by a "sandbox" that sets $PATH to a specific,
+// single directory and creates a symlink for every binary in $PATH in it. That
+// symlink will point to path_interposer, which then uses an embedded
+// configuration to determine whether to allow access to the binary (in which
+// case it calls the original executable) or not (in which case it fails). It
+// can also optionally log invocations.
+//
+// This, of course, does not help if one invokes the tool in question with its
+// full path.
package main
import (
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 1eae63f..e59146b 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -1270,7 +1270,28 @@
// Handle only the case where the first (or only) word is constant
words := ref.SplitN(" ", 2)
if !words[0].Const() {
- return ctx.newBadExpr(node, "reference is too complex: %s", refDump)
+ if len(words) == 1 {
+ expr := ctx.parseMakeString(node, ref)
+ return &callExpr{
+ object: &identifierExpr{"cfg"},
+ name: "get",
+ args: []starlarkExpr{
+ expr,
+ &callExpr{
+ object: &identifierExpr{"g"},
+ name: "get",
+ args: []starlarkExpr{
+ expr,
+ &stringLiteralExpr{literal: ""},
+ },
+ returnType: starlarkTypeUnknown,
+ },
+ },
+ returnType: starlarkTypeUnknown,
+ }
+ } else {
+ return ctx.newBadExpr(node, "reference is too complex: %s", refDump)
+ }
}
if name, _, ok := ctx.maybeParseFunctionCall(node, ref); ok {
@@ -1574,11 +1595,21 @@
}
}
- return &foreachExpr{
+ var result starlarkExpr = &foreachExpr{
varName: loopVarName,
list: list,
action: action,
}
+
+ if action.typ() == starlarkTypeList {
+ result = &callExpr{
+ name: baseName + ".flatten_2d_list",
+ args: []starlarkExpr{result},
+ returnType: starlarkTypeList,
+ }
+ }
+
+ return result
}
func transformNode(node starlarkNode, transformer func(expr starlarkExpr) starlarkExpr) {
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 7f236bb..a09764c 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -579,7 +579,7 @@
pass
if rblf.expand_wildcard("foo*.mk"):
pass
- if rblf.expand_wildcard("foo*.mk bar*.mk") == ["foo1.mk", "foo2.mk", "barxyz.mk"]:
+ if rblf.expand_wildcard("foo*.mk bar*.mk") == ["foo1.mk", "foo2.mk", "barxyz.mk"]:
pass
`,
},
@@ -1363,6 +1363,8 @@
BOOT_KERNEL_MODULES_LIST := foo.ko
BOOT_KERNEL_MODULES_LIST += bar.ko
BOOT_KERNEL_MODULES_FILTER_2 := $(foreach m,$(BOOT_KERNEL_MODULES_LIST),%/$(m))
+NESTED_LISTS := $(foreach m,$(SOME_VAR),$(BOOT_KERNEL_MODULES_LIST))
+NESTED_LISTS_2 := $(foreach x,$(SOME_VAR),$(foreach y,$(x),prefix$(y)))
FOREACH_WITH_IF := $(foreach module,\
$(BOOT_KERNEL_MODULES_LIST),\
@@ -1382,6 +1384,8 @@
g["BOOT_KERNEL_MODULES_LIST"] = ["foo.ko"]
g["BOOT_KERNEL_MODULES_LIST"] += ["bar.ko"]
g["BOOT_KERNEL_MODULES_FILTER_2"] = ["%%/%s" % m for m in g["BOOT_KERNEL_MODULES_LIST"]]
+ g["NESTED_LISTS"] = rblf.flatten_2d_list([g["BOOT_KERNEL_MODULES_LIST"] for m in rblf.words(g.get("SOME_VAR", ""))])
+ g["NESTED_LISTS_2"] = rblf.flatten_2d_list([["prefix%s" % y for y in rblf.words(x)] for x in rblf.words(g.get("SOME_VAR", ""))])
g["FOREACH_WITH_IF"] = [("" if rblf.filter(module, "foo.ko") else rblf.mkerror("product.mk", "module \"%s\" has an error!" % module)) for module in g["BOOT_KERNEL_MODULES_LIST"]]
# Same as above, but not assigning it to a variable allows it to be converted to statements
for module in g["BOOT_KERNEL_MODULES_LIST"]:
@@ -1574,10 +1578,10 @@
for x in rblf.words(g.get("MY_LIST_VAR", "")):
_entry = {
"foo/font.mk": ("foo/font", _font_init),
- }.get("foo/%s.mk" % _x)
+ }.get("foo/%s.mk" % x)
(_varmod, _varmod_init) = _entry if _entry else (None, None)
if not _varmod_init:
- rblf.mkerror("product.mk", "Cannot find %s" % ("foo/%s.mk" % _x))
+ rblf.mkerror("product.mk", "Cannot find %s" % ("foo/%s.mk" % x))
_varmod_init(g, handle)
`,
},
@@ -1595,6 +1599,27 @@
g["MY_VAR"] = "foo"
`,
},
+ {
+ desc: "Complicated variable references",
+ mkname: "product.mk",
+ in: `
+MY_VAR := foo
+MY_VAR_2 := MY_VAR
+MY_VAR_3 := $($(MY_VAR_2))
+MY_VAR_4 := $(foo bar)
+MY_VAR_5 := $($(MY_VAR_2) bar)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["MY_VAR"] = "foo"
+ g["MY_VAR_2"] = "MY_VAR"
+ g["MY_VAR_3"] = (cfg).get(g["MY_VAR_2"], (g).get(g["MY_VAR_2"], ""))
+ g["MY_VAR_4"] = rblf.mk2rbc_error("product.mk:5", "cannot handle invoking foo")
+ g["MY_VAR_5"] = rblf.mk2rbc_error("product.mk:6", "reference is too complex: $(MY_VAR_2) bar")
+`,
+ },
}
var known_variables = []struct {
diff --git a/provenance/provenance_singleton.go b/provenance/provenance_singleton.go
index e49f3d4..d1cbd8f 100644
--- a/provenance/provenance_singleton.go
+++ b/provenance/provenance_singleton.go
@@ -36,7 +36,8 @@
mergeProvenanceMetaData = pctx.AndroidStaticRule("mergeProvenanceMetaData",
blueprint.RuleParams{
Command: `rm -rf $out $out.temp && ` +
- `echo -e "# proto-file: build/soong/provenance/proto/provenance_metadata.proto\n# proto-message: ProvenanceMetaDataList" > $out && ` +
+ `echo "# proto-file: build/soong/provenance/proto/provenance_metadata.proto" > $out && ` +
+ `echo "# proto-message: ProvenanceMetaDataList" >> $out && ` +
`touch $out.temp && cat $out.temp $in | grep -v "^#.*" >> $out && rm -rf $out.temp`,
})
)
diff --git a/provenance/tools/gen_provenance_metadata.py b/provenance/tools/gen_provenance_metadata.py
index b33f911..f3f4d1f 100644
--- a/provenance/tools/gen_provenance_metadata.py
+++ b/provenance/tools/gen_provenance_metadata.py
@@ -16,6 +16,7 @@
import argparse
import hashlib
+import os.path
import sys
import google.protobuf.text_format as text_format
@@ -51,6 +52,11 @@
h.update(artifact_file.read())
provenance_metadata.artifact_sha256 = h.hexdigest()
+ Log("Check if there is attestation for the artifact")
+ attestation_file_name = args.artifact_path + ".intoto.jsonl"
+ if os.path.isfile(attestation_file_name):
+ provenance_metadata.attestation_path = attestation_file_name
+
text_proto = [
"# proto-file: build/soong/provenance/proto/provenance_metadata.proto",
"# proto-message: ProvenanceMetaData",
diff --git a/provenance/tools/gen_provenance_metadata_test.py b/provenance/tools/gen_provenance_metadata_test.py
index 2fc04bf..1f69b8f 100644
--- a/provenance/tools/gen_provenance_metadata_test.py
+++ b/provenance/tools/gen_provenance_metadata_test.py
@@ -100,6 +100,11 @@
artifact_file = tempfile.mktemp()
with open(artifact_file,"wt") as f:
f.write(artifact_content)
+
+ attestation_file = artifact_file + ".intoto.jsonl"
+ with open(attestation_file, "wt") as af:
+ af.write("attestation file")
+
metadata_file = tempfile.mktemp()
cmd = ["gen_provenance_metadata"]
cmd.extend(["--module_name", "a"])
@@ -117,9 +122,11 @@
self.assertEqual(provenance_metadata.artifact_path, artifact_file)
self.assertEqual(provenance_metadata.artifact_install_path, "b")
self.assertEqual(provenance_metadata.artifact_sha256, sha256(artifact_content))
+ self.assertEqual(provenance_metadata.attestation_path, attestation_file)
os.remove(artifact_file)
os.remove(metadata_file)
+ os.remove(attestation_file)
if __name__ == '__main__':
unittest.main(verbosity=2)
\ No newline at end of file
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index a99fa1f..9d0c3de 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -796,6 +796,44 @@
.intermediates/myjavalib.stubs.source/android_common/metalava/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
.intermediates/myjavalib.stubs.source/android_common/metalava/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
`),
+ checkInfoContents(`
+[
+ {
+ "@type": "sdk",
+ "@name": "mysdk",
+ "java_header_libs": [
+ "exported-system-module",
+ "system-module"
+ ],
+ "java_sdk_libs": [
+ "myjavalib"
+ ],
+ "java_system_modules": [
+ "my-system-modules"
+ ]
+ },
+ {
+ "@type": "java_library",
+ "@name": "exported-system-module"
+ },
+ {
+ "@type": "java_system_modules",
+ "@name": "my-system-modules",
+ "@deps": [
+ "exported-system-module",
+ "system-module"
+ ]
+ },
+ {
+ "@type": "java_sdk_library",
+ "@name": "myjavalib"
+ },
+ {
+ "@type": "java_library",
+ "@name": "system-module"
+ }
+]
+`),
)
}
diff --git a/sdk/sdk.go b/sdk/sdk.go
index c8c7b79..b37eaad 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -75,6 +75,8 @@
snapshotFile android.OptionalPath
+ infoFile android.OptionalPath
+
// The builder, preserved for testing.
builderForTests *snapshotBuilder
}
@@ -191,27 +193,32 @@
}
// Generate the snapshot from the member info.
- p := s.buildSnapshot(ctx, sdkVariants)
- zip := ctx.InstallFile(android.PathForMainlineSdksInstall(ctx), p.Base(), p)
- s.snapshotFile = android.OptionalPathForPath(zip)
+ s.buildSnapshot(ctx, sdkVariants)
}
}
func (s *sdk) AndroidMkEntries() []android.AndroidMkEntries {
- if !s.snapshotFile.Valid() {
+ if !s.snapshotFile.Valid() != !s.infoFile.Valid() {
+ panic("Snapshot (%q) and info file (%q) should both be set or neither should be set.")
+ } else if !s.snapshotFile.Valid() {
return []android.AndroidMkEntries{}
}
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "FAKE",
OutputFile: s.snapshotFile,
- DistFiles: android.MakeDefaultDistFiles(s.snapshotFile.Path()),
+ DistFiles: android.MakeDefaultDistFiles(s.snapshotFile.Path(), s.infoFile.Path()),
Include: "$(BUILD_PHONY_PACKAGE)",
ExtraFooters: []android.AndroidMkExtraFootersFunc{
func(w io.Writer, name, prefix, moduleDir string) {
// Allow the sdk to be built by simply passing its name on the command line.
fmt.Fprintln(w, ".PHONY:", s.Name())
fmt.Fprintln(w, s.Name()+":", s.snapshotFile.String())
+
+ // Allow the sdk info to be built by simply passing its name on the command line.
+ infoTarget := s.Name() + ".info"
+ fmt.Fprintln(w, ".PHONY:", infoTarget)
+ fmt.Fprintln(w, infoTarget+":", s.infoFile.String())
},
},
}}
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 40de150..ccbeb8d 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -263,7 +263,10 @@
result := testSdkWithFs(t, sdk, nil)
CheckSnapshot(t, result, "mysdk", "",
- checkAllOtherCopyRules(`.intermediates/mysdk/common_os/mysdk-current.zip -> mysdk-current.zip`))
+ checkAllOtherCopyRules(`
+.intermediates/mysdk/common_os/mysdk-current.info -> mysdk-current.info
+.intermediates/mysdk/common_os/mysdk-current.zip -> mysdk-current.zip
+`))
}
type EmbeddedPropertiesStruct struct {
diff --git a/sdk/testing.go b/sdk/testing.go
index 062f200..b0f5fdc 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -142,6 +142,7 @@
androidBpContents: sdk.GetAndroidBpContentsForTests(),
androidUnversionedBpContents: sdk.GetUnversionedAndroidBpContentsForTests(),
androidVersionedBpContents: sdk.GetVersionedAndroidBpContentsForTests(),
+ infoContents: sdk.GetInfoContentsForTests(),
snapshotTestCustomizations: map[snapshotTest]*snapshotTestCustomization{},
targetBuildRelease: sdk.builderForTests.targetBuildRelease,
}
@@ -402,6 +403,17 @@
}
}
+// Check that the snapshot's info contents are ciorrect.
+//
+// Both the expected and actual string are both trimmed before comparing.
+func checkInfoContents(expected string) snapshotBuildInfoChecker {
+ return func(info *snapshotBuildInfo) {
+ info.t.Helper()
+ android.AssertTrimmedStringEquals(info.t, "info contents do not match",
+ expected, info.infoContents)
+ }
+}
+
type resultChecker func(t *testing.T, result *android.TestResult)
// snapshotTestPreparer registers a preparer that will be used to customize the specified
@@ -479,6 +491,9 @@
// The contents of the versioned Android.bp file
androidVersionedBpContents string
+ // The contents of the info file.
+ infoContents string
+
// The paths, relative to the snapshot root, of all files and directories copied into the
// snapshot.
snapshotContents []string
diff --git a/sdk/update.go b/sdk/update.go
index 5db604b..71bd042 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -15,6 +15,8 @@
package sdk
import (
+ "bytes"
+ "encoding/json"
"fmt"
"reflect"
"sort"
@@ -219,9 +221,19 @@
exportedComponentsInfo = ctx.OtherModuleProvider(child, android.ExportedComponentsInfoProvider).(android.ExportedComponentsInfo)
}
+ var container android.SdkAware
+ if parent != ctx.Module() {
+ container = parent.(android.SdkAware)
+ }
+
export := memberTag.ExportMember()
s.memberVariantDeps = append(s.memberVariantDeps, sdkMemberVariantDep{
- s, memberType, child.(android.SdkAware), export, exportedComponentsInfo,
+ sdkVariant: s,
+ memberType: memberType,
+ variant: child.(android.SdkAware),
+ container: container,
+ export: export,
+ exportedComponentsInfo: exportedComponentsInfo,
})
// Recurse down into the member's dependencies as it may have dependencies that need to be
@@ -311,7 +323,7 @@
// buildSnapshot is the main function in this source file. It creates rules to copy
// the contents (header files, stub libraries, etc) into the zip file.
-func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) android.OutputPath {
+func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) {
// Aggregate all the sdkMemberVariantDep instances from all the sdk variants.
hasLicenses := false
@@ -370,9 +382,9 @@
// Unversioned modules are not required in that case because the numbered version will be a
// finalized version of the snapshot that is intended to be kept separate from the
generateUnversioned := version == soongSdkSnapshotVersionUnversioned || version == soongSdkSnapshotVersionCurrent
- snapshotZipFileSuffix := ""
+ snapshotFileSuffix := ""
if generateVersioned {
- snapshotZipFileSuffix = "-" + version
+ snapshotFileSuffix = "-" + version
}
currentBuildRelease := latestBuildRelease()
@@ -489,7 +501,7 @@
filesToZip := builder.filesToZip
// zip them all
- zipPath := fmt.Sprintf("%s%s.zip", ctx.ModuleName(), snapshotZipFileSuffix)
+ zipPath := fmt.Sprintf("%s%s.zip", ctx.ModuleName(), snapshotFileSuffix)
outputZipFile := android.PathForModuleOut(ctx, zipPath).OutputPath
outputDesc := "Building snapshot for " + ctx.ModuleName()
@@ -502,7 +514,7 @@
zipFile = outputZipFile
desc = outputDesc
} else {
- intermediatePath := fmt.Sprintf("%s%s.unmerged.zip", ctx.ModuleName(), snapshotZipFileSuffix)
+ intermediatePath := fmt.Sprintf("%s%s.unmerged.zip", ctx.ModuleName(), snapshotFileSuffix)
zipFile = android.PathForModuleOut(ctx, intermediatePath).OutputPath
desc = "Building intermediate snapshot for " + ctx.ModuleName()
}
@@ -527,7 +539,120 @@
})
}
- return outputZipFile
+ modules := s.generateInfoData(ctx, memberVariantDeps)
+
+ // Output the modules information as pretty printed JSON.
+ info := newGeneratedFile(ctx, fmt.Sprintf("%s%s.info", ctx.ModuleName(), snapshotFileSuffix))
+ output, err := json.MarshalIndent(modules, "", " ")
+ if err != nil {
+ ctx.ModuleErrorf("error generating %q: %s", info, err)
+ }
+ builder.infoContents = string(output)
+ info.generatedContents.UnindentedPrintf("%s", output)
+ info.build(pctx, ctx, nil)
+ infoPath := info.path
+ installedInfo := ctx.InstallFile(android.PathForMainlineSdksInstall(ctx), infoPath.Base(), infoPath)
+ s.infoFile = android.OptionalPathForPath(installedInfo)
+
+ // Install the zip, making sure that the info file has been installed as well.
+ installedZip := ctx.InstallFile(android.PathForMainlineSdksInstall(ctx), outputZipFile.Base(), outputZipFile, installedInfo)
+ s.snapshotFile = android.OptionalPathForPath(installedZip)
+}
+
+type moduleInfo struct {
+ // The type of the module, e.g. java_sdk_library
+ moduleType string
+ // The name of the module.
+ name string
+ // A list of additional dependencies of the module.
+ deps []string
+ // Additional dynamic properties.
+ dynamic map[string]interface{}
+}
+
+func (m *moduleInfo) MarshalJSON() ([]byte, error) {
+ buffer := bytes.Buffer{}
+
+ separator := ""
+ writeObjectPair := func(key string, value interface{}) {
+ buffer.WriteString(fmt.Sprintf("%s%q: ", separator, key))
+ b, err := json.Marshal(value)
+ if err != nil {
+ panic(err)
+ }
+ buffer.Write(b)
+ separator = ","
+ }
+
+ buffer.WriteString("{")
+ writeObjectPair("@type", m.moduleType)
+ writeObjectPair("@name", m.name)
+ if m.deps != nil {
+ writeObjectPair("@deps", m.deps)
+ }
+ for _, k := range android.SortedStringKeys(m.dynamic) {
+ v := m.dynamic[k]
+ writeObjectPair(k, v)
+ }
+ buffer.WriteString("}")
+ return buffer.Bytes(), nil
+}
+
+var _ json.Marshaler = (*moduleInfo)(nil)
+
+// generateInfoData creates a list of moduleInfo structures that will be marshalled into JSON.
+func (s *sdk) generateInfoData(ctx android.ModuleContext, memberVariantDeps []sdkMemberVariantDep) interface{} {
+ modules := []*moduleInfo{}
+ sdkInfo := moduleInfo{
+ moduleType: "sdk",
+ name: ctx.ModuleName(),
+ dynamic: map[string]interface{}{},
+ }
+ modules = append(modules, &sdkInfo)
+
+ name2Info := map[string]*moduleInfo{}
+ getModuleInfo := func(module android.Module) *moduleInfo {
+ name := module.Name()
+ info := name2Info[name]
+ if info == nil {
+ moduleType := ctx.OtherModuleType(module)
+ // Remove any suffix added when creating modules dynamically.
+ moduleType = strings.Split(moduleType, "__")[0]
+ info = &moduleInfo{
+ moduleType: moduleType,
+ name: name,
+ }
+ name2Info[name] = info
+ }
+ return info
+ }
+
+ for _, memberVariantDep := range memberVariantDeps {
+ propertyName := memberVariantDep.memberType.SdkPropertyName()
+ var list []string
+ if v, ok := sdkInfo.dynamic[propertyName]; ok {
+ list = v.([]string)
+ }
+
+ memberName := memberVariantDep.variant.Name()
+ list = append(list, memberName)
+ sdkInfo.dynamic[propertyName] = android.SortedUniqueStrings(list)
+
+ if memberVariantDep.container != nil {
+ containerInfo := getModuleInfo(memberVariantDep.container)
+ containerInfo.deps = android.SortedUniqueStrings(append(containerInfo.deps, memberName))
+ }
+
+ // Make sure that the module info is created for each module.
+ getModuleInfo(memberVariantDep.variant)
+ }
+
+ for _, memberName := range android.SortedStringKeys(name2Info) {
+ info := name2Info[memberName]
+ modules = append(modules, info)
+ }
+
+ return modules
}
// filterOutComponents removes any item from the deps list that is a component of another item in
@@ -1033,6 +1158,10 @@
return contents.content.String()
}
+func (s *sdk) GetInfoContentsForTests() string {
+ return s.builderForTests.infoContents
+}
+
func (s *sdk) GetUnversionedAndroidBpContentsForTests() string {
contents := &generatedContents{}
generateFilteredBpContents(contents, s.builderForTests.bpFile, func(module *bpModule) bool {
@@ -1087,6 +1216,8 @@
// The target build release for which the snapshot is to be generated.
targetBuildRelease *buildRelease
+
+ infoContents string
}
func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
@@ -1322,6 +1453,11 @@
// The variant that is added to the sdk.
variant android.SdkAware
+ // The optional container of this member, i.e. the module that is depended upon by the sdk
+ // (possibly transitively) and whose dependency on this module is why it was added to the sdk.
+ // Is nil if this a direct dependency of the sdk.
+ container android.SdkAware
+
// True if the member should be exported, i.e. accessible, from outside the sdk.
export bool
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 831a80f..b3092ea 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -31,18 +31,25 @@
LinuxOnlyPrebuilt bool
}
+// These binaries can be run from $PATH, nonhermetically. There should be as
+// few as possible of these, since this means that the build depends on tools
+// that are not shipped in the source tree and whose behavior is therefore
+// unpredictable.
var Allowed = PathConfig{
Symlink: true,
Log: false,
Error: false,
}
+// This tool is specifically disallowed and calling it will result in an
+// "executable no found" error.
var Forbidden = PathConfig{
Symlink: false,
Log: true,
Error: true,
}
+// This tool is allowed, but access to it will be logged.
var Log = PathConfig{
Symlink: true,
Log: true,
@@ -52,13 +59,16 @@
// The configuration used if the tool is not listed in the config below.
// Currently this will create the symlink, but log and error when it's used. In
// the future, I expect the symlink to be removed, and this will be equivalent
-// to Forbidden.
+// to Forbidden. This applies to every tool not specifically mentioned in the
+// configuration.
var Missing = PathConfig{
Symlink: true,
Log: true,
Error: true,
}
+// This is used for binaries for which we have prebuilt versions, but only for
+// Linux. Thus, their execution from $PATH is only allowed on Mac OS.
var LinuxOnlyPrebuilt = PathConfig{
Symlink: false,
Log: true,
@@ -73,6 +83,8 @@
return Missing
}
+// This list specifies whether a particular binary from $PATH is allowed to be
+// run during the build. For more documentation, see path_interposer.go .
var Configuration = map[string]PathConfig{
"bash": Allowed,
"dd": Allowed,