Merge "Strip annotations from library stubs"
diff --git a/android/apex.go b/android/apex.go
index 555cbb5..5665da2 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -856,9 +856,6 @@
"libeigen": 30,
"liblz4": 30,
"libmdnssd": 30,
- "libneuralnetworks_common": 30,
- "libneuralnetworks_headers": 30,
- "libneuralnetworks": 30,
"libprocpartition": 30,
"libprotobuf-java-lite": 30,
"libprotoutil": 30,
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/apex/apex.go b/apex/apex.go
index 73a3fc2..a95b504 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -19,6 +19,7 @@
import (
"fmt"
"path/filepath"
+ "regexp"
"sort"
"strings"
@@ -976,6 +977,7 @@
// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
// specific variant to modules that support the ApexInfoMutator.
+// It also propagates updatable=true to apps of updatable apexes
func apexInfoMutator(mctx android.TopDownMutatorContext) {
if !mctx.Module().Enabled() {
return
@@ -983,8 +985,8 @@
if a, ok := mctx.Module().(ApexInfoMutator); ok {
a.ApexInfoMutator(mctx)
- return
}
+ enforceAppUpdatability(mctx)
}
// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
@@ -1015,6 +1017,22 @@
}
}
+// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
+func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
+ if !mctx.Module().Enabled() {
+ return
+ }
+ if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
+ // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
+ mctx.VisitDirectDeps(func(module android.Module) {
+ // ignore android_test_app
+ if app, ok := module.(*java.AndroidApp); ok {
+ app.SetUpdatable(true)
+ }
+ })
+ }
+}
+
// TODO: b/215736885 Whittle the denylist
// Transitive deps of certain mainline modules baseline NewApi errors
// Skip these mainline modules for now
@@ -1653,7 +1671,20 @@
var _ androidApp = (*java.AndroidApp)(nil)
var _ androidApp = (*java.AndroidAppImport)(nil)
-const APEX_VERSION_PLACEHOLDER = "__APEX_VERSION_PLACEHOLDER__"
+func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
+ buildId := ctx.Config().BuildId()
+
+ // The build ID is used as a suffix for a filename, so ensure that
+ // the set of characters being used are sanitized.
+ // - any word character: [a-zA-Z0-9_]
+ // - dots: .
+ // - dashes: -
+ validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
+ if !validRegex.MatchString(buildId) {
+ ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
+ }
+ return buildId
+}
func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
appDir := "app"
@@ -1664,7 +1695,7 @@
// TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
// so that PackageManager correctly invalidates the existing installed apk
// in favour of the new APK-in-APEX. See bugs for more information.
- dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+APEX_VERSION_PLACEHOLDER)
+ dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
fileToCopy := aapp.OutputFile()
af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
@@ -1903,7 +1934,7 @@
// suffixed so that PackageManager correctly invalidates the
// existing installed apk in favour of the new APK-in-APEX.
// See bugs for more information.
- appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+APEX_VERSION_PLACEHOLDER)
+ appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
af.certificate = java.PresignedCertificate
filesInfo = append(filesInfo, af)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 4a52115..bcb55af 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -223,6 +223,7 @@
// not because of these tests specifically (it's not used by the tests)
variables.Platform_version_active_codenames = []string{"Q", "Tiramisu"}
variables.Platform_vndk_version = proptools.StringPtr("29")
+ variables.BuildId = proptools.StringPtr("TEST.BUILD_ID")
}),
)
@@ -682,7 +683,7 @@
"etc/myetc",
"javalib/myjar.jar",
"lib64/mylib.so",
- "app/AppFoo@__APEX_VERSION_PLACEHOLDER__/AppFoo.apk",
+ "app/AppFoo@TEST.BUILD_ID/AppFoo.apk",
"overlay/blue/rro.apk",
"etc/bpf/bpf.o",
"etc/bpf/bpf2.o",
@@ -2393,6 +2394,7 @@
key: "myapex.key",
apps: ["AppFoo"],
min_sdk_version: "29",
+ updatable: false,
}
apex_key {
@@ -5682,8 +5684,8 @@
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/app/AppFoo@__APEX_VERSION_PLACEHOLDER__/AppFoo.apk")
- ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv@__APEX_VERSION_PLACEHOLDER__/AppFooPriv.apk")
+ ensureContains(t, copyCmds, "image.apex/app/AppFoo@TEST.BUILD_ID/AppFoo.apk")
+ ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv@TEST.BUILD_ID/AppFooPriv.apk")
appZipRule := ctx.ModuleForTests("AppFoo", "android_common_apex10000").Description("zip jni libs")
// JNI libraries are uncompressed
@@ -5700,6 +5702,36 @@
}
}
+func TestApexWithAppImportBuildId(t *testing.T) {
+ invalidBuildIds := []string{"../", "a b", "a/b", "a/b/../c", "/a"}
+ for _, id := range invalidBuildIds {
+ message := fmt.Sprintf("Unable to use build id %s as filename suffix", id)
+ fixture := android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildId = proptools.StringPtr(id)
+ })
+ testApexError(t, message, `apex {
+ name: "myapex",
+ key: "myapex.key",
+ apps: ["AppFooPrebuilt"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ android_app_import {
+ name: "AppFooPrebuilt",
+ apk: "PrebuiltAppFoo.apk",
+ presigned: true,
+ apex_available: ["myapex"],
+ }
+ `, fixture)
+ }
+}
+
func TestApexWithAppImports(t *testing.T) {
ctx := testApex(t, `
apex {
@@ -5745,8 +5777,8 @@
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt@__APEX_VERSION_PLACEHOLDER__/AppFooPrebuilt.apk")
- ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt@__APEX_VERSION_PLACEHOLDER__/AwesomePrebuiltAppFooPriv.apk")
+ ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt@TEST.BUILD_ID/AppFooPrebuilt.apk")
+ ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt@TEST.BUILD_ID/AwesomePrebuiltAppFooPriv.apk")
}
func TestApexWithAppImportsPrefer(t *testing.T) {
@@ -5787,7 +5819,7 @@
}))
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "app/AppFoo@__APEX_VERSION_PLACEHOLDER__/AppFooPrebuilt.apk",
+ "app/AppFoo@TEST.BUILD_ID/AppFooPrebuilt.apk",
})
}
@@ -5820,7 +5852,7 @@
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo@__APEX_VERSION_PLACEHOLDER__/TesterHelpAppFoo.apk")
+ ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo@TEST.BUILD_ID/TesterHelpAppFoo.apk")
}
func TestApexPropertiesShouldBeDefaultable(t *testing.T) {
@@ -6263,8 +6295,8 @@
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
- ensureNotContains(t, copyCmds, "image.apex/app/app@__APEX_VERSION_PLACEHOLDER__/app.apk")
- ensureContains(t, copyCmds, "image.apex/app/override_app@__APEX_VERSION_PLACEHOLDER__/override_app.apk")
+ ensureNotContains(t, copyCmds, "image.apex/app/app@TEST.BUILD_ID/app.apk")
+ ensureContains(t, copyCmds, "image.apex/app/override_app@TEST.BUILD_ID/override_app.apk")
ensureNotContains(t, copyCmds, "image.apex/etc/bpf/bpf.o")
ensureContains(t, copyCmds, "image.apex/etc/bpf/override_bpf.o")
@@ -7168,7 +7200,7 @@
content := bundleConfigRule.Args["content"]
ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
- ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo@__APEX_VERSION_PLACEHOLDER__/AppFoo.apk"}]}`)
+ ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo@TEST.BUILD_ID/AppFoo.apk"}]}`)
}
func TestAppSetBundle(t *testing.T) {
@@ -7199,9 +7231,9 @@
if len(copyCmds) != 3 {
t.Fatalf("Expected 3 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet@__APEX_VERSION_PLACEHOLDER__$")
- ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet@__APEX_VERSION_PLACEHOLDER__$")
- ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet@__APEX_VERSION_PLACEHOLDER__ .*/AppSet.zip$")
+ ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet@TEST.BUILD_ID$")
+ ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet@TEST.BUILD_ID$")
+ ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet@TEST.BUILD_ID .*/AppSet.zip$")
}
func TestAppSetBundlePrebuilt(t *testing.T) {
@@ -9324,6 +9356,69 @@
}
}
+// updatable apexes should propagate updatable=true to its apps
+func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) {
+ bp := `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ updatable: %v,
+ apps: [
+ "myapp",
+ ],
+ min_sdk_version: "30",
+ }
+ apex_key {
+ name: "myapex.key",
+ }
+ android_app {
+ name: "myapp",
+ updatable: %v,
+ apex_available: [
+ "myapex",
+ ],
+ sdk_version: "current",
+ min_sdk_version: "30",
+ }
+ `
+ testCases := []struct {
+ name string
+ apex_is_updatable_bp bool
+ app_is_updatable_bp bool
+ app_is_updatable_expected bool
+ }{
+ {
+ name: "Non-updatable apex respects updatable property of non-updatable app",
+ apex_is_updatable_bp: false,
+ app_is_updatable_bp: false,
+ app_is_updatable_expected: false,
+ },
+ {
+ name: "Non-updatable apex respects updatable property of updatable app",
+ apex_is_updatable_bp: false,
+ app_is_updatable_bp: true,
+ app_is_updatable_expected: true,
+ },
+ {
+ name: "Updatable apex respects updatable property of updatable app",
+ apex_is_updatable_bp: true,
+ app_is_updatable_bp: true,
+ app_is_updatable_expected: true,
+ },
+ {
+ name: "Updatable apex sets updatable=true on non-updatable app",
+ apex_is_updatable_bp: true,
+ app_is_updatable_bp: false,
+ app_is_updatable_expected: true,
+ },
+ }
+ for _, testCase := range testCases {
+ result := testApex(t, fmt.Sprintf(bp, testCase.apex_is_updatable_bp, testCase.app_is_updatable_bp))
+ myapp := result.ModuleForTests("myapp", "android_common").Module().(*java.AndroidApp)
+ android.AssertBoolEquals(t, testCase.name, testCase.app_is_updatable_expected, myapp.Updatable())
+ }
+}
+
func TestMain(m *testing.M) {
os.Exit(m.Run())
}
diff --git a/apex/builder.go b/apex/builder.go
index d4765d0..abbf8ad 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -107,16 +107,14 @@
`--canned_fs_config ${canned_fs_config} ` +
`--include_build_info ` +
`--payload_type image ` +
- `--key ${key} ` +
- `--apex_version_placeholder ${apex_version_placeholder} ` +
- `${opt_flags} ${image_dir} ${out} `,
+ `--key ${key} ${opt_flags} ${image_dir} ${out} `,
CommandDeps: []string{"${apexer}", "${avbtool}", "${e2fsdroid}", "${merge_zips}",
"${mke2fs}", "${resize2fs}", "${sefcontext_compile}", "${make_f2fs}", "${sload_f2fs}", "${make_erofs}",
"${soong_zip}", "${zipalign}", "${aapt2}", "prebuilts/sdk/current/public/android.jar"},
Rspfile: "${out}.copy_commands",
RspfileContent: "${copy_commands}",
Description: "APEX ${image_dir} => ${out}",
- }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", "manifest", "payload_fs_type", "apex_version_placeholder")
+ }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", "manifest", "payload_fs_type")
zipApexRule = pctx.StaticRule("zipApexRule", blueprint.RuleParams{
Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` +
@@ -124,13 +122,12 @@
`APEXER_TOOL_PATH=${tool_path} ` +
`${apexer} --force --manifest ${manifest} ` +
`--payload_type zip ` +
- `--apex_version_placeholder ${apex_version_placeholder} ` +
`${image_dir} ${out} `,
CommandDeps: []string{"${apexer}", "${merge_zips}", "${soong_zip}", "${zipalign}", "${aapt2}"},
Rspfile: "${out}.copy_commands",
RspfileContent: "${copy_commands}",
Description: "ZipAPEX ${image_dir} => ${out}",
- }, "tool_path", "image_dir", "copy_commands", "manifest", "apex_version_placeholder")
+ }, "tool_path", "image_dir", "copy_commands", "manifest")
apexProtoConvertRule = pctx.AndroidStaticRule("apexProtoConvertRule",
blueprint.RuleParams{
@@ -661,15 +658,14 @@
Output: unsignedOutputFile,
Description: "apex (" + apexType.name() + ")",
Args: map[string]string{
- "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
- "image_dir": imageDir.String(),
- "copy_commands": strings.Join(copyCommands, " && "),
- "manifest": a.manifestPbOut.String(),
- "file_contexts": fileContexts.String(),
- "canned_fs_config": cannedFsConfig.String(),
- "key": a.privateKeyFile.String(),
- "opt_flags": strings.Join(optFlags, " "),
- "apex_version_placeholder": APEX_VERSION_PLACEHOLDER,
+ "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
+ "image_dir": imageDir.String(),
+ "copy_commands": strings.Join(copyCommands, " && "),
+ "manifest": a.manifestPbOut.String(),
+ "file_contexts": fileContexts.String(),
+ "canned_fs_config": cannedFsConfig.String(),
+ "key": a.privateKeyFile.String(),
+ "opt_flags": strings.Join(optFlags, " "),
},
})
@@ -761,11 +757,10 @@
Output: unsignedOutputFile,
Description: "apex (" + apexType.name() + ")",
Args: map[string]string{
- "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
- "image_dir": imageDir.String(),
- "copy_commands": strings.Join(copyCommands, " && "),
- "manifest": a.manifestPbOut.String(),
- "apex_version_placeholder": APEX_VERSION_PLACEHOLDER,
+ "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
+ "image_dir": imageDir.String(),
+ "copy_commands": strings.Join(copyCommands, " && "),
+ "manifest": a.manifestPbOut.String(),
},
})
}
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 8ec3871..cba5974 100644
--- a/cc/binary_test.go
+++ b/cc/binary_test.go
@@ -49,3 +49,23 @@
expectedUnStrippedFile := "outputbase/execroot/__main__/foo"
android.AssertStringEquals(t, "Unstripped output file", expectedUnStrippedFile, unStrippedFilePath.String())
}
+
+func TestBinaryLinkerScripts(t *testing.T) {
+ result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
+ cc_binary {
+ name: "foo",
+ srcs: ["foo.cc"],
+ linker_scripts: ["foo.ld", "bar.ld"],
+ }`)
+
+ binFoo := result.ModuleForTests("foo", "android_arm64_armv8-a").Rule("ld")
+
+ android.AssertStringListContains(t, "missing dependency on linker_scripts",
+ binFoo.Implicits.Strings(), "foo.ld")
+ android.AssertStringListContains(t, "missing dependency on linker_scripts",
+ binFoo.Implicits.Strings(), "bar.ld")
+ android.AssertStringDoesContain(t, "missing flag for linker_scripts",
+ binFoo.Args["ldFlags"], "-Wl,--script,foo.ld")
+ android.AssertStringDoesContain(t, "missing flag for linker_scripts",
+ binFoo.Args["ldFlags"], "-Wl,--script,bar.ld")
+}
diff --git a/cc/check.go b/cc/check.go
index a357a97..3d290a9 100644
--- a/cc/check.go
+++ b/cc/check.go
@@ -87,6 +87,8 @@
ctx.PropertyErrorf(prop, "Bad flag: `%s` is not allowed", flag)
} else if strings.HasPrefix(flag, "-Wl,--version-script") {
ctx.PropertyErrorf(prop, "Bad flag: `%s`, use version_script instead", flag)
+ } else if flag == "-T" || strings.HasPrefix(flag, "--script") {
+ ctx.PropertyErrorf(prop, "Bad flag: `%s`, use linker_scripts instead", flag)
} else if flag == "--coverage" {
ctx.PropertyErrorf(prop, "Bad flag: `%s`, use native_coverage instead", flag)
} else if strings.Contains(flag, " ") {
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 ba1043b..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-*
@@ -122,6 +123,7 @@
{"hardware/qcom", tidyExternalVendor},
{"vendor/", tidyExternalVendor},
{"vendor/google", tidyDefault},
+ {"vendor/google_arc/libs/org.chromium.arc.mojom", tidyExternalVendor},
{"vendor/google_devices", tidyExternalVendor},
}
diff --git a/cc/installer.go b/cc/installer.go
index 2522610..e2c0e7b 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -31,7 +31,7 @@
Install_in_root *bool `android:"arch_variant"`
// Install output directly in {partition}/xbin
- Install_in_xbin *bool `android:"arch_vvariant"`
+ Install_in_xbin *bool `android:"arch_variant"`
}
type installLocation int
diff --git a/cc/linker.go b/cc/linker.go
index bea65d4..f346584 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -227,6 +227,9 @@
// local file name to pass to the linker as --dynamic-list
Dynamic_list *string `android:"path,arch_variant"`
+ // local files to pass to the linker as --script
+ Linker_scripts []string `android:"path,arch_variant"`
+
// list of static libs that should not be used to build this module
Exclude_static_libs []string `android:"arch_variant"`
@@ -602,6 +605,17 @@
flags.LdFlagsDeps = append(flags.LdFlagsDeps, dynamicList.Path())
}
}
+
+ linkerScriptPaths := android.PathsForModuleSrc(ctx, linker.Properties.Linker_scripts)
+ if len(linkerScriptPaths) > 0 && (ctx.Darwin() || ctx.Windows()) {
+ ctx.PropertyErrorf("linker_scripts", "Only supported for ELF files")
+ } else {
+ for _, linkerScriptPath := range linkerScriptPaths {
+ flags.Local.LdFlags = append(flags.Local.LdFlags,
+ "-Wl,--script,"+linkerScriptPath.String())
+ flags.LdFlagsDeps = append(flags.LdFlagsDeps, linkerScriptPath)
+ }
+ }
}
return flags
diff --git a/cc/test.go b/cc/test.go
index ead7877..5703571 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -30,7 +30,8 @@
// if set, build against the gtest library. Defaults to true.
Gtest *bool
- // if set, use the isolated gtest runner. Defaults to false.
+ // if set, use the isolated gtest runner. Defaults to true if gtest is also true and the arch is Windows, false
+ // otherwise.
Isolated *bool
}
@@ -256,6 +257,13 @@
return BoolDefault(test.LinkerProperties.Gtest, true)
}
+func (test *testDecorator) isolated(ctx BaseModuleContext) bool {
+ if !ctx.Windows() {
+ return BoolDefault(test.LinkerProperties.Isolated, false)
+ }
+ return BoolDefault(test.LinkerProperties.Isolated, false)
+}
+
func (test *testDecorator) testBinary() bool {
return true
}
@@ -288,7 +296,7 @@
if test.gtest() {
if ctx.useSdk() && ctx.Device() {
deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk_c++", "libgtest_ndk_c++")
- } else if BoolDefault(test.LinkerProperties.Isolated, false) {
+ } else if test.isolated(ctx) {
deps.StaticLibs = append(deps.StaticLibs, "libgtest_isolated_main")
// The isolated library requires liblog, but adding it
// as a static library means unit tests cannot override
@@ -424,7 +432,7 @@
var options []tradefed.Option
configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.StopServicesSetup", options})
}
- if Bool(test.testDecorator.LinkerProperties.Isolated) {
+ if test.isolated(ctx) {
configs = append(configs, tradefed.Option{Name: "not-shardable", Value: "true"})
}
if test.Properties.Test_options.Run_test_as != nil {
diff --git a/cc/tidy.go b/cc/tidy.go
index 03e967d..ac1521b 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -96,10 +96,15 @@
if !android.SubstringInList(flags.TidyFlags, "-header-filter=") {
defaultDirs := ctx.Config().Getenv("DEFAULT_TIDY_HEADER_DIRS")
headerFilter := "-header-filter="
+ // Default header filter should include only the module directory,
+ // not the out/soong/.../ModuleDir/...
+ // Otherwise, there will be too many warnings from generated files in out/...
+ // If a module wants to see warnings in the generated source files,
+ // it should specify its own -header-filter flag.
if defaultDirs == "" {
- headerFilter += ctx.ModuleDir() + "/"
+ headerFilter += "^" + ctx.ModuleDir() + "/"
} else {
- headerFilter += "\"(" + ctx.ModuleDir() + "/|" + defaultDirs + ")\""
+ headerFilter += "\"(^" + ctx.ModuleDir() + "/|" + defaultDirs + ")\""
}
flags.TidyFlags = append(flags.TidyFlags, headerFilter)
}
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/docs/tidy.md b/docs/tidy.md
index 890c3a0..2eb8234 100644
--- a/docs/tidy.md
+++ b/docs/tidy.md
@@ -31,7 +31,7 @@
The global default can be overwritten by module properties in Android.bp.
-### `tidy` and `tidy_checks`
+### `tidy`, `tidy_checks`, and `ALLOW_LOCAL_TIDY_TRUE`
For example, in
[system/bpf/Android.bp](https://android.googlesource.com/platform/system/bpf/+/refs/heads/master/Android.bp),
@@ -52,8 +52,16 @@
}
```
That means in normal builds, even without `WITH_TIDY=1`,
-the modules that use `bpf_defaults` will run clang-tidy
+the modules that use `bpf_defaults` _should_ run clang-tidy
over C/C++ source files with the given `tidy_checks`.
+
+However since clang-tidy warnings and its runtime cost might
+not be wanted by all people, the default is to ignore the
+`tidy:true` property unless the environment variable
+`ALLOW_LOCAL_TIDY_TRUE` is set to true or 1.
+To run clang-tidy on all modules that should be tested with clang-tidy,
+`ALLOW_LOCAL_TIDY_TRUE` or `WITH_TIDY` should be set to true or 1.
+
Note that `clang-analyzer-security*` is included in `tidy_checks`
but not all `clang-analyzer-*` checks. Check `cert-err34-c` is
disabled, although `cert-*` is selected.
@@ -80,6 +88,9 @@
}
```
+Note that `tidy:false` always disables clang-tidy, no matter
+`ALLOW_LOCAL_TIDY_TRUE` is set or not.
+
### `tidy_checks_as_errors`
The global tidy checks are enabled as warnings.
diff --git a/filesystem/Android.bp b/filesystem/Android.bp
index 38684d3..857dfa7 100644
--- a/filesystem/Android.bp
+++ b/filesystem/Android.bp
@@ -15,6 +15,7 @@
"bootimg.go",
"filesystem.go",
"logical_partition.go",
+ "raw_binary.go",
"system_image.go",
"vbmeta.go",
"testing.go",
diff --git a/filesystem/raw_binary.go b/filesystem/raw_binary.go
new file mode 100644
index 0000000..f726124
--- /dev/null
+++ b/filesystem/raw_binary.go
@@ -0,0 +1,120 @@
+// Copyright (C) 2022 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 filesystem
+
+import (
+ "fmt"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+
+ "android/soong/android"
+)
+
+var (
+ toRawBinary = pctx.AndroidStaticRule("toRawBinary",
+ blueprint.RuleParams{
+ Command: "${objcopy} --output-target=binary ${in} ${out}",
+ CommandDeps: []string{"$objcopy"},
+ },
+ "objcopy")
+)
+
+func init() {
+ pctx.Import("android/soong/cc/config")
+
+ android.RegisterModuleType("raw_binary", rawBinaryFactory)
+}
+
+type rawBinary struct {
+ android.ModuleBase
+
+ properties rawBinaryProperties
+
+ output android.OutputPath
+ installDir android.InstallPath
+}
+
+type rawBinaryProperties struct {
+ // Set the name of the output. Defaults to <module_name>.bin.
+ Stem *string
+
+ // Name of input executable. Can be a name of a target.
+ Src *string `android:"path,arch_variant"`
+}
+
+func rawBinaryFactory() android.Module {
+ module := &rawBinary{}
+ module.AddProperties(&module.properties)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ return module
+}
+
+func (r *rawBinary) DepsMutator(ctx android.BottomUpMutatorContext) {
+ // do nothing
+}
+
+func (r *rawBinary) installFileName() string {
+ return proptools.StringDefault(r.properties.Stem, r.BaseModuleName()+".bin")
+}
+
+func (r *rawBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ inputFile := android.PathForModuleSrc(ctx, proptools.String(r.properties.Src))
+ outputFile := android.PathForModuleOut(ctx, r.installFileName()).OutputPath
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: toRawBinary,
+ Description: "prefix symbols " + outputFile.Base(),
+ Output: outputFile,
+ Input: inputFile,
+ Args: map[string]string{
+ "objcopy": "${config.ClangBin}/llvm-objcopy",
+ },
+ })
+
+ r.output = outputFile
+ r.installDir = android.PathForModuleInstall(ctx, "etc")
+ ctx.InstallFile(r.installDir, r.installFileName(), r.output)
+}
+
+var _ android.AndroidMkEntriesProvider = (*rawBinary)(nil)
+
+// Implements android.AndroidMkEntriesProvider
+func (r *rawBinary) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{android.AndroidMkEntries{
+ Class: "ETC",
+ OutputFile: android.OptionalPathForPath(r.output),
+ }}
+}
+
+var _ Filesystem = (*rawBinary)(nil)
+
+func (r *rawBinary) OutputPath() android.Path {
+ return r.output
+}
+
+func (r *rawBinary) SignedOutputPath() android.Path {
+ return nil
+}
+
+var _ android.OutputFileProducer = (*rawBinary)(nil)
+
+// Implements android.OutputFileProducer
+func (r *rawBinary) OutputFiles(tag string) (android.Paths, error) {
+ if tag == "" {
+ return []android.Path{r.output}, nil
+ }
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+}
diff --git a/java/androidmk.go b/java/androidmk.go
index f6ea6a9..439b1d1 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -542,6 +542,9 @@
if !outputFile.Valid() {
outputFile = android.OptionalPathForPath(dstubs.apiFile)
}
+ if !outputFile.Valid() {
+ outputFile = android.OptionalPathForPath(dstubs.apiVersionsXml)
+ }
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
OutputFile: outputFile,
diff --git a/java/app.go b/java/app.go
index 768d9e9..5f14cef 100755
--- a/java/app.go
+++ b/java/app.go
@@ -299,10 +299,6 @@
// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
// This check is enforced for "updatable" APKs (including APK-in-APEX).
-// b/155209650: until min_sdk_version is properly supported, use sdk_version instead.
-// because, sdk_version is overridden by min_sdk_version (if set as smaller)
-// and sdkLinkType is checked with dependencies so we can be sure that the whole dependency tree
-// will meet the requirements.
func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
// It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
ctx.VisitDirectDeps(func(m android.Module) {
@@ -313,10 +309,10 @@
// The domain of cc.sdk_version is "current" and <number>
// We can rely on android.SdkSpec to convert it to <number> so that "current" is
// handled properly regardless of sdk finalization.
- jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.SdkVersion()).EffectiveVersion(ctx)
+ jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx)
if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
- ctx.OtherModuleErrorf(dep, "sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
- dep.SdkVersion(), minSdkVersion, ctx.ModuleName())
+ ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
+ dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName())
return
}
@@ -842,6 +838,10 @@
return Bool(a.appProperties.Updatable)
}
+func (a *AndroidApp) SetUpdatable(val bool) {
+ a.appProperties.Updatable = &val
+}
+
func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
if overridden {
diff --git a/java/app_test.go b/java/app_test.go
index 8324dff..b83a333 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -427,7 +427,8 @@
name: "libjni",
stl: "none",
system_shared_libs: [],
- sdk_version: "29",
+ sdk_version: "current",
+ min_sdk_version: "29",
}
`
fs := map[string][]byte{
@@ -481,12 +482,13 @@
name: "libjni",
stl: "none",
sdk_version: "current",
+ min_sdk_version: "current",
}
`
- testJavaError(t, `"libjni" .*: sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp)
+ testJavaError(t, `"libjni" .*: min_sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp)
}
-func TestUpdatableApps_ErrorIfDepSdkVersionIsHigher(t *testing.T) {
+func TestUpdatableApps_ErrorIfDepMinSdkVersionIsHigher(t *testing.T) {
bp := cc.GatherRequiredDepsForTest(android.Android) + `
android_app {
name: "foo",
@@ -503,6 +505,7 @@
shared_libs: ["libbar"],
system_shared_libs: [],
sdk_version: "27",
+ min_sdk_version: "27",
}
cc_library {
@@ -510,6 +513,7 @@
stl: "none",
system_shared_libs: [],
sdk_version: "current",
+ min_sdk_version: "current",
}
`
testJavaError(t, `"libjni" .*: links "libbar" built against newer API version "current"`, bp)
diff --git a/java/base.go b/java/base.go
index e60e54e..1e8095b 100644
--- a/java/base.go
+++ b/java/base.go
@@ -748,9 +748,7 @@
// Kotlin files
ctx.AddVariationDependencies(nil, kotlinStdlibTag,
"kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8")
- if len(j.properties.Plugins) > 0 {
- ctx.AddVariationDependencies(nil, kotlinAnnotationsTag, "kotlin-annotations")
- }
+ ctx.AddVariationDependencies(nil, kotlinAnnotationsTag, "kotlin-annotations")
}
// Framework libraries need special handling in static coverage builds: they should not have
@@ -1106,8 +1104,6 @@
flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
flags.classpath = append(flags.classpath, deps.kotlinAnnotations...)
- flags.dexClasspath = append(flags.dexClasspath, deps.kotlinAnnotations...)
-
flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...)
flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...)
@@ -1139,9 +1135,12 @@
// Jar kotlin classes into the final jar after javac
if BoolDefault(j.properties.Static_kotlin_stdlib, true) {
kotlinJars = append(kotlinJars, deps.kotlinStdlib...)
+ kotlinJars = append(kotlinJars, deps.kotlinAnnotations...)
kotlinHeaderJars = append(kotlinHeaderJars, deps.kotlinStdlib...)
+ kotlinHeaderJars = append(kotlinHeaderJars, deps.kotlinAnnotations...)
} else {
flags.dexClasspath = append(flags.dexClasspath, deps.kotlinStdlib...)
+ flags.dexClasspath = append(flags.dexClasspath, deps.kotlinAnnotations...)
}
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 3b1f7c0..115388b 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -135,6 +135,9 @@
// if set to true, Metalava will allow framework SDK to contain API levels annotations.
Api_levels_annotations_enabled *bool
+ // Apply the api levels database created by this module rather than generating one in this droidstubs.
+ Api_levels_module *string
+
// the dirs which Metalava extracts API levels annotations from.
Api_levels_annotations_dirs []string
@@ -234,6 +237,7 @@
var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
+var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"}
func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
d.Javadoc.addDeps(ctx)
@@ -255,6 +259,10 @@
ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
}
}
+
+ if d.properties.Api_levels_module != nil {
+ ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
+ }
}
func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) {
@@ -365,21 +373,35 @@
}
func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
- if !Bool(d.properties.Api_levels_annotations_enabled) {
- return
+ var apiVersions android.Path
+ if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
+ d.apiLevelsGenerationFlags(ctx, cmd)
+ apiVersions = d.apiVersionsXml
+ } else {
+ ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
+ if s, ok := m.(*Droidstubs); ok {
+ apiVersions = s.apiVersionsXml
+ } else {
+ ctx.PropertyErrorf("api_levels_module",
+ "module %q is not a droidstubs module", ctx.OtherModuleName(m))
+ }
+ })
}
+ if apiVersions != nil {
+ cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
+ cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
+ cmd.FlagWithInput("--apply-api-levels ", apiVersions)
+ }
+}
- d.apiVersionsXml = android.PathForModuleOut(ctx, "metalava", "api-versions.xml")
-
+func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
if len(d.properties.Api_levels_annotations_dirs) == 0 {
ctx.PropertyErrorf("api_levels_annotations_dirs",
"has to be non-empty if api levels annotations was enabled!")
}
+ d.apiVersionsXml = android.PathForModuleOut(ctx, "metalava", "api-versions.xml")
cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
- cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
- cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
- cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 10d99f3..9fdfdde 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -46,6 +46,12 @@
api_levels_annotations_enabled: true,
api_levels_jar_filename: "android.other.jar",
}
+
+ droidstubs {
+ name: "stubs-applying-api-versions",
+ srcs: ["bar-doc/a.java"],
+ api_levels_module: "bar-stubs-other",
+ }
`,
map[string][]byte{
"bar-doc/a.java": nil,
@@ -53,26 +59,37 @@
testcases := []struct {
moduleName string
expectedJarFilename string
+ generate_xml bool
high_mem bool
}{
{
moduleName: "bar-stubs",
+ generate_xml: true,
expectedJarFilename: "android.jar",
high_mem: false,
},
{
moduleName: "bar-stubs-other",
+ generate_xml: true,
expectedJarFilename: "android.other.jar",
high_mem: true,
},
+ {
+ moduleName: "stubs-applying-api-versions",
+ generate_xml: false,
+ },
}
for _, c := range testcases {
m := ctx.ModuleForTests(c.moduleName, "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest)
- expected := "--android-jar-pattern ./%/public/" + c.expectedJarFilename
- if actual := String(sboxProto.Commands[0].Command); !strings.Contains(actual, expected) {
- t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, actual)
+ cmdline := String(sboxProto.Commands[0].Command)
+ android.AssertStringContainsEquals(t, "api-versions generation flag", cmdline, "--generate-api-levels", c.generate_xml)
+ if c.expectedJarFilename != "" {
+ expected := "--android-jar-pattern ./%/public/" + c.expectedJarFilename
+ if !strings.Contains(cmdline, expected) {
+ t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, cmdline)
+ }
}
metalava := m.Rule("metalava")
diff --git a/java/kotlin_test.go b/java/kotlin_test.go
index 435d782..491ce29 100644
--- a/java/kotlin_test.go
+++ b/java/kotlin_test.go
@@ -42,6 +42,11 @@
}
`)
+ kotlinStdlib := ctx.ModuleForTests("kotlin-stdlib", "android_common").
+ Output("turbine-combined/kotlin-stdlib.jar").Output
+ kotlinAnnotations := ctx.ModuleForTests("kotlin-annotations", "android_common").
+ Output("turbine-combined/kotlin-annotations.jar").Output
+
fooKotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
fooJavac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
fooJar := ctx.ModuleForTests("foo", "android_common").Output("combined/foo.jar")
@@ -69,6 +74,16 @@
fooJar.Inputs.Strings(), fooKotlincClasses.String())
}
+ if !inList(kotlinStdlib.String(), fooJar.Inputs.Strings()) {
+ t.Errorf("foo jar inputs %v does not contain %v",
+ fooJar.Inputs.Strings(), kotlinStdlib.String())
+ }
+
+ if !inList(kotlinAnnotations.String(), fooJar.Inputs.Strings()) {
+ t.Errorf("foo jar inputs %v does not contain %v",
+ fooJar.Inputs.Strings(), kotlinAnnotations.String())
+ }
+
if !inList(fooKotlincHeaderClasses.String(), fooHeaderJar.Inputs.Strings()) {
t.Errorf("foo header jar inputs %v does not contain %q",
fooHeaderJar.Inputs.Strings(), fooKotlincHeaderClasses.String())
diff --git a/java/lint.go b/java/lint.go
index 426a2af..22c9ec4 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -524,10 +524,18 @@
return
}
- frameworkDocStubs := findModuleOrErr(ctx, "framework-doc-stubs")
- if frameworkDocStubs == nil {
+ apiVersionsDb := findModuleOrErr(ctx, "api_versions_public")
+ if apiVersionsDb == nil {
if !ctx.Config().AllowMissingDependencies() {
- ctx.Errorf("lint: missing framework-doc-stubs")
+ ctx.Errorf("lint: missing module api_versions_public")
+ }
+ return
+ }
+
+ sdkAnnotations := findModuleOrErr(ctx, "sdk-annotations.zip")
+ if sdkAnnotations == nil {
+ if !ctx.Config().AllowMissingDependencies() {
+ ctx.Errorf("lint: missing module sdk-annotations.zip")
}
return
}
@@ -542,13 +550,13 @@
ctx.Build(pctx, android.BuildParams{
Rule: android.CpIfChanged,
- Input: android.OutputFileForModule(ctx, frameworkDocStubs, ".annotations.zip"),
+ Input: android.OutputFileForModule(ctx, sdkAnnotations, ""),
Output: copiedAnnotationsZipPath(ctx),
})
ctx.Build(pctx, android.BuildParams{
Rule: android.CpIfChanged,
- Input: android.OutputFileForModule(ctx, frameworkDocStubs, ".api_versions.xml"),
+ Input: android.OutputFileForModule(ctx, apiVersionsDb, ".api_versions.xml"),
Output: copiedAPIVersionsXmlPath(ctx, "api_versions.xml"),
})
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/scripts/hiddenapi/generate_hiddenapi_lists.py b/scripts/hiddenapi/generate_hiddenapi_lists.py
index 35e0948..6546c7f 100755
--- a/scripts/hiddenapi/generate_hiddenapi_lists.py
+++ b/scripts/hiddenapi/generate_hiddenapi_lists.py
@@ -27,6 +27,7 @@
FLAG_MAX_TARGET_P = 'max-target-p'
FLAG_MAX_TARGET_Q = 'max-target-q'
FLAG_MAX_TARGET_R = 'max-target-r'
+FLAG_MAX_TARGET_S = 'max-target-s'
FLAG_CORE_PLATFORM_API = 'core-platform-api'
FLAG_PUBLIC_API = 'public-api'
FLAG_SYSTEM_API = 'system-api'
@@ -41,6 +42,7 @@
FLAG_MAX_TARGET_P,
FLAG_MAX_TARGET_Q,
FLAG_MAX_TARGET_R,
+ FLAG_MAX_TARGET_S,
]
ALL_FLAGS = FLAGS_API_LIST + [
FLAG_CORE_PLATFORM_API,
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,