Merge "Change experiments config fetch log to be a verbose log"
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 33b67ab..27255d1 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -21,6 +21,7 @@
"io/ioutil"
"os"
"os/exec"
+ "path"
"path/filepath"
"runtime"
"strings"
@@ -528,7 +529,7 @@
configNodesSection := ""
labelsByConfig := map[string][]string{}
- for val, _ := range context.requests {
+ for val := range context.requests {
labelString := fmt.Sprintf("\"@%s\"", val.label)
configString := getConfigString(val)
labelsByConfig[configString] = append(labelsByConfig[configString], labelString)
@@ -566,7 +567,7 @@
// request type.
func (context *bazelContext) cqueryStarlarkFileContents() []byte {
requestTypeToCqueryIdEntries := map[cqueryRequest][]string{}
- for val, _ := range context.requests {
+ for val := range context.requests {
cqueryId := getCqueryId(val)
mapEntryString := fmt.Sprintf("%q : True", cqueryId)
requestTypeToCqueryIdEntries[val.requestType] =
@@ -870,53 +871,14 @@
})
}
- // Register bazel-owned build statements (obtained from the aquery invocation).
+ executionRoot := path.Join(ctx.Config().BazelContext.OutputBase(), "execroot", "__main__")
+ bazelOutDir := path.Join(executionRoot, "bazel-out")
for index, buildStatement := range ctx.Config().BazelContext.BuildStatementsToRegister() {
if len(buildStatement.Command) < 1 {
panic(fmt.Sprintf("unhandled build statement: %v", buildStatement))
}
rule := NewRuleBuilder(pctx, ctx)
- cmd := rule.Command()
-
- // cd into Bazel's execution root, which is the action cwd.
- cmd.Text(fmt.Sprintf("cd %s/execroot/__main__ &&", ctx.Config().BazelContext.OutputBase()))
-
- // Remove old outputs, as some actions might not rerun if the outputs are detected.
- if len(buildStatement.OutputPaths) > 0 {
- cmd.Text("rm -f")
- for _, outputPath := range buildStatement.OutputPaths {
- cmd.Text(outputPath)
- }
- cmd.Text("&&")
- }
-
- for _, pair := range buildStatement.Env {
- // Set per-action env variables, if any.
- cmd.Flag(pair.Key + "=" + pair.Value)
- }
-
- // The actual Bazel action.
- cmd.Text(buildStatement.Command)
-
- for _, outputPath := range buildStatement.OutputPaths {
- cmd.ImplicitOutput(PathForBazelOut(ctx, outputPath))
- }
- for _, inputPath := range buildStatement.InputPaths {
- cmd.Implicit(PathForBazelOut(ctx, inputPath))
- }
- for _, inputDepsetHash := range buildStatement.InputDepsetHashes {
- otherDepsetName := bazelDepsetName(inputDepsetHash)
- cmd.Implicit(PathForPhony(ctx, otherDepsetName))
- }
-
- if depfile := buildStatement.Depfile; depfile != nil {
- cmd.ImplicitDepFile(PathForBazelOut(ctx, *depfile))
- }
-
- for _, symlinkPath := range buildStatement.SymlinkPaths {
- cmd.ImplicitSymlinkOutput(PathForBazelOut(ctx, symlinkPath))
- }
-
+ createCommand(rule.Command(), buildStatement, executionRoot, bazelOutDir, ctx)
// This is required to silence warnings pertaining to unexpected timestamps. Particularly,
// some Bazel builtins (such as files in the bazel_tools directory) have far-future
// timestamps. Without restat, Ninja would emit warnings that the input files of a
@@ -928,6 +890,58 @@
}
}
+// Register bazel-owned build statements (obtained from the aquery invocation).
+func createCommand(cmd *RuleBuilderCommand, buildStatement bazel.BuildStatement, executionRoot string, bazelOutDir string, ctx PathContext) {
+ // executionRoot is the action cwd.
+ cmd.Text(fmt.Sprintf("cd '%s' &&", executionRoot))
+
+ // Remove old outputs, as some actions might not rerun if the outputs are detected.
+ if len(buildStatement.OutputPaths) > 0 {
+ cmd.Text("rm -f")
+ for _, outputPath := range buildStatement.OutputPaths {
+ cmd.Text(outputPath)
+ }
+ cmd.Text("&&")
+ }
+
+ for _, pair := range buildStatement.Env {
+ // Set per-action env variables, if any.
+ cmd.Flag(pair.Key + "=" + pair.Value)
+ }
+
+ // The actual Bazel action.
+ cmd.Text(buildStatement.Command)
+
+ for _, outputPath := range buildStatement.OutputPaths {
+ cmd.ImplicitOutput(PathForBazelOut(ctx, outputPath))
+ }
+ for _, inputPath := range buildStatement.InputPaths {
+ cmd.Implicit(PathForBazelOut(ctx, inputPath))
+ }
+ for _, inputDepsetHash := range buildStatement.InputDepsetHashes {
+ otherDepsetName := bazelDepsetName(inputDepsetHash)
+ cmd.Implicit(PathForPhony(ctx, otherDepsetName))
+ }
+
+ if depfile := buildStatement.Depfile; depfile != nil {
+ // The paths in depfile are relative to `executionRoot`.
+ // Hence, they need to be corrected by replacing "bazel-out"
+ // with the full `bazelOutDir`.
+ // Otherwise, implicit outputs and implicit inputs under "bazel-out/"
+ // would be deemed missing.
+ // (Note: The regexp uses a capture group because the version of sed
+ // does not support a look-behind pattern.)
+ replacement := fmt.Sprintf(`&& sed -i'' -E 's@(^|\s|")bazel-out/@\1%s/@g' '%s'`,
+ bazelOutDir, *depfile)
+ cmd.Text(replacement)
+ cmd.ImplicitDepFile(PathForBazelOut(ctx, *depfile))
+ }
+
+ for _, symlinkPath := range buildStatement.SymlinkPaths {
+ cmd.ImplicitSymlinkOutput(PathForBazelOut(ctx, symlinkPath))
+ }
+}
+
func getCqueryId(key cqueryKey) string {
return key.label + "|" + getConfigString(key)
}
diff --git a/android/bazel_handler_test.go b/android/bazel_handler_test.go
index dd9a7ed..935ce4e 100644
--- a/android/bazel_handler_test.go
+++ b/android/bazel_handler_test.go
@@ -57,8 +57,13 @@
}
func TestInvokeBazelPopulatesBuildStatements(t *testing.T) {
- bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
- bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}: `
+ type testCase struct {
+ input string
+ command string
+ }
+
+ var testCases = []testCase{
+ {`
{
"artifacts": [{
"id": 1,
@@ -88,15 +93,60 @@
"label": "two"
}]
}`,
- })
- err := bazelContext.InvokeBazel(testConfig)
- if err != nil {
- t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
+ "cd 'er' && rm -f one && touch foo",
+ }, {`
+{
+ "artifacts": [{
+ "id": 1,
+ "pathFragmentId": 10
+ }, {
+ "id": 2,
+ "pathFragmentId": 20
+ }],
+ "actions": [{
+ "targetId": 100,
+ "actionKey": "x",
+ "mnemonic": "x",
+ "arguments": ["bogus", "command"],
+ "outputIds": [1, 2],
+ "primaryOutputId": 1
+ }],
+ "pathFragments": [{
+ "id": 10,
+ "label": "one",
+ "parentId": 30
+ }, {
+ "id": 20,
+ "label": "one.d",
+ "parentId": 30
+ }, {
+ "id": 30,
+ "label": "parent"
+ }]
+}`,
+ `cd 'er' && rm -f parent/one && bogus command && sed -i'' -E 's@(^|\s|")bazel-out/@\1bo/@g' 'parent/one.d'`,
+ },
}
- got := bazelContext.BuildStatementsToRegister()
- if want := 1; len(got) != want {
- t.Errorf("Expected %d registered build statements, got %#v", want, got)
+ for _, testCase := range testCases {
+ bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
+ bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}: testCase.input})
+
+ err := bazelContext.InvokeBazel(testConfig)
+ if err != nil {
+ t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
+ }
+
+ got := bazelContext.BuildStatementsToRegister()
+ if want := 1; len(got) != want {
+ t.Errorf("expected %d registered build statements, but got %#v", want, got)
+ }
+
+ cmd := RuleBuilderCommand{}
+ createCommand(&cmd, got[0], "er", "bo", PathContextForTesting(TestConfig("out", nil, "", nil)))
+ if actual := cmd.buf.String(); testCase.command != actual {
+ t.Errorf("expected: [%s], actual: [%s]", testCase.command, actual)
+ }
}
}
diff --git a/bazel/aquery_test.go b/bazel/aquery_test.go
index cf51b39..8ba8b5a 100644
--- a/bazel/aquery_test.go
+++ b/bazel/aquery_test.go
@@ -897,7 +897,7 @@
func assertFlattenedDepsets(t *testing.T, actualDepsets []AqueryDepset, expectedDepsetFiles [][]string) {
t.Helper()
if len(actualDepsets) != len(expectedDepsetFiles) {
- t.Errorf("Expected %s depsets, but got %s depsets", expectedDepsetFiles, actualDepsets)
+ t.Errorf("Expected %d depsets, but got %d depsets", len(expectedDepsetFiles), len(actualDepsets))
}
for i, actualDepset := range actualDepsets {
actualFlattenedInputs := flattenDepsets([]string{actualDepset.ContentHash}, actualDepsets)
diff --git a/cc/library.go b/cc/library.go
index 0fa01d7..c445a42 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -925,7 +925,6 @@
if ctx.Darwin() {
f = append(f,
"-dynamiclib",
- "-single_module",
"-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
)
if ctx.Arch().ArchType == android.X86 {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index e0779c6..ff56058 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -430,7 +430,7 @@
}
// Enable Memtag for all components in the include paths (for Aarch64 only)
- if ctx.Arch().ArchType == android.Arm64 {
+ if ctx.Arch().ArchType == android.Arm64 && ctx.toolchain().Bionic() {
if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
if s.Memtag_heap == nil {
s.Memtag_heap = proptools.BoolPtr(true)
@@ -460,17 +460,17 @@
}
// HWASan requires AArch64 hardware feature (top-byte-ignore).
- if ctx.Arch().ArchType != android.Arm64 {
+ if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() {
s.Hwaddress = nil
}
// SCS is only implemented on AArch64.
- if ctx.Arch().ArchType != android.Arm64 {
+ if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() {
s.Scs = nil
}
// Memtag_heap is only implemented on AArch64.
- if ctx.Arch().ArchType != android.Arm64 {
+ if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() {
s.Memtag_heap = nil
}
diff --git a/java/app.go b/java/app.go
index c5d88e9..8ff5d91 100755
--- a/java/app.go
+++ b/java/app.go
@@ -583,6 +583,16 @@
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+ var noticeAssetPath android.WritablePath
+ if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
+ // The rule to create the notice file can't be generated yet, as the final output path
+ // for the apk isn't known yet. Add the path where the notice file will be generated to the
+ // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
+ // be generated later.
+ noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
+ a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
+ }
+
// Process all building blocks, from AAPT to certificates.
a.aaptBuildActions(ctx)
@@ -654,7 +664,8 @@
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
}
- if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
+ if a.aapt.noticeFile.Valid() {
+ // Generating the notice file rule has to be here after a.outputFile is known.
noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
android.BuildNoticeHtmlOutputFromLicenseMetadata(
ctx, noticeFile, "", "",
@@ -663,13 +674,11 @@
android.PathForModuleInstall(ctx).String() + "/",
a.outputFile.String(),
})
- noticeAssetPath := android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
builder := android.NewRuleBuilder(pctx, ctx)
builder.Command().Text("cp").
Input(noticeFile).
Output(noticeAssetPath)
builder.Build("notice_dir", "Building notice dir")
- a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
}
for _, split := range a.aapt.splits {
diff --git a/provenance/provenance_singleton.go b/provenance/provenance_singleton.go
index d1cbd8f..fbb6212 100644
--- a/provenance/provenance_singleton.go
+++ b/provenance/provenance_singleton.go
@@ -35,10 +35,10 @@
mergeProvenanceMetaData = pctx.AndroidStaticRule("mergeProvenanceMetaData",
blueprint.RuleParams{
- Command: `rm -rf $out $out.temp && ` +
+ Command: `rm -rf $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`,
+ `for file in $in; do echo '' >> $out; echo 'metadata {' | cat - $$file | grep -Ev "^#.*|^$$" >> $out; echo '}' >> $out; done`,
})
)