diff options
author | Artur Satayev <satayev@google.com> | 2020-05-14 15:15:01 +0100 |
---|---|---|
committer | Artur Satayev <satayev@google.com> | 2020-06-23 22:29:43 +0100 |
commit | a4405fa3dea15bc71534f6391d36f1a8a65a7844 (patch) | |
tree | b66a392a3dbcd1aeee447eff81824b1a72ba4700 /apex/apex_singleton.go | |
parent | 5bc5e4602d3c7ee31c3dbb7f2a0ae94339dea4bd (diff) |
Track allowed transitive deps in any updatable module.
To compare allowed_deps.txt vs head, run:
:; m -j out/soong/apex/depsinfo/filtered-updatable-flatlists.txt.check
To update source allowed_deps.txt, run:
:; build/soong/scripts/update-apex-allowed-deps.sh
Bug: 149622332
Test: m
Change-Id: I56771ba3fea748de8e9c58c80758670572f7af53
(cherry picked from commit 8d6085d38934dc43f17b47c2961727766e87bfa2)
Diffstat (limited to 'apex/apex_singleton.go')
-rw-r--r-- | apex/apex_singleton.go | 113 |
1 files changed, 97 insertions, 16 deletions
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go index 83a56a2b5..f96491f88 100644 --- a/apex/apex_singleton.go +++ b/apex/apex_singleton.go @@ -17,9 +17,8 @@ package apex import ( - "github.com/google/blueprint" - "android/soong/android" + "github.com/google/blueprint" ) func init() { @@ -27,39 +26,121 @@ func init() { } type apexDepsInfoSingleton struct { - // Output file with all flatlists from updatable modules' deps-info combined - updatableFlatListsPath android.OutputPath + allowedApexDepsInfoCheckResult android.OutputPath } func apexDepsInfoSingletonFactory() android.Singleton { return &apexDepsInfoSingleton{} } -var combineFilesRule = pctx.AndroidStaticRule("combineFilesRule", - blueprint.RuleParams{ +var ( + mergeApexDepsInfoFilesRule = pctx.AndroidStaticRule("mergeApexDepsInfoFilesRule", blueprint.RuleParams{ Command: "cat $out.rsp | xargs cat > $out", Rspfile: "$out.rsp", RspfileContent: "$in", - }, + }) + + // Filter out apex dependencies that are external or safe to ignore for build determinism. + filterApexDepsRule = pctx.AndroidStaticRule("filterApexDepsRule", blueprint.RuleParams{ + Command: "cat ${in}" + + // Only track non-external dependencies, i.e. those that end up in the binary... + " | grep -v '(external)'" + + // ...and those that are safe in any apex but can be different per product. + " | grep -v 'libgcc_stripped'" + + " | grep -v 'libunwind_llvm'" + + " | grep -v 'ndk_crtbegin_so.19'" + + " | grep -v 'ndk_crtbegin_so.21'" + + " | grep -v 'ndk_crtbegin_so.27'" + + " | grep -v 'ndk_crtend_so.19'" + + " | grep -v 'ndk_crtend_so.21'" + + " | grep -v 'ndk_crtend_so.27'" + + " | grep -v 'ndk_libunwind'" + + " | grep -v 'prebuilt_libclang_rt.builtins-aarch64-android'" + + " | grep -v 'prebuilt_libclang_rt.builtins-arm-android'" + + " | grep -v 'prebuilt_libclang_rt.builtins-i686-android'" + + " | grep -v 'prebuilt_libclang_rt.builtins-x86_64-android'" + + " | grep -v 'libclang_rt.hwasan-aarch64-android.llndk'" + + " > ${out}", + }) + + diffAllowedApexDepsInfoRule = pctx.AndroidStaticRule("diffAllowedApexDepsInfoRule", blueprint.RuleParams{ + // Diff two given lists while ignoring comments in the allowed deps file + Description: "Diff ${allowed_flatlists} and ${merged_flatlists}", + Command: ` + if grep -v '^#' ${allowed_flatlists} | diff -B ${merged_flatlists} -; then + touch ${out}; + else + echo -e "\n******************************"; + echo "ERROR: go/apex-allowed-deps-error"; + echo "******************************"; + echo "Detected changes to allowed dependencies in updatable modules."; + echo "To fix and update build/soong/apex/allowed_deps.txt, please run:"; + echo "$$ (croot && build/soong/scripts/update-apex-allowed-deps.sh)"; + echo "Members of mainline-modularization@google.com will review the changes."; + echo -e "******************************\n"; + exit 1; + fi;`, + }, "allowed_flatlists", "merged_flatlists") ) func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) { - updatableFlatLists := android.Paths{} + modulePaths := map[string]android.Path{} ctx.VisitAllModules(func(module android.Module) { if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok { - if path := binaryInfo.FlatListPath(); path != nil { - if binaryInfo.Updatable() { - updatableFlatLists = append(updatableFlatLists, path) + if !binaryInfo.Updatable() { + return + } + if path := binaryInfo.FlatListPath(); path.String() != "" { + // TODO(b/159734404): don't use module.String() to sort modules/variants. + // This is needed though, as an order of module variants may be + // different between products. + ms := module.String() + if _, ok := modulePaths[ms]; !ok { + modulePaths[ms] = path + } else if modulePaths[ms] != path { + ctx.Errorf("Mismatching output paths for the same module %v:\n%v\n%v", ms, modulePaths[ms], path) } } } }) - s.updatableFlatListsPath = android.PathForOutput(ctx, "apex", "depsinfo", "updatable-flatlists.txt") + updatableFlatLists := android.Paths{} + // Avoid non-determinism by sorting module and variation names. + for _, key := range android.FirstUniqueStrings(android.SortedStringKeys(modulePaths)) { + updatableFlatLists = append(updatableFlatLists, modulePaths[key]) + } + + // Merge all individual flatlists of updatable modules into a single output file + updatableFlatListsPath := android.PathForOutput(ctx, "apex", "depsinfo", "updatable-flatlists.txt") ctx.Build(pctx, android.BuildParams{ - Rule: combineFilesRule, - Description: "Generate " + s.updatableFlatListsPath.String(), - Inputs: updatableFlatLists, - Output: s.updatableFlatListsPath, + Rule: mergeApexDepsInfoFilesRule, + Inputs: updatableFlatLists, + Output: updatableFlatListsPath, }) + + // Build a filtered version of updatable flatlists without external dependencies + filteredFlatLists := android.PathForOutput(ctx, "apex", "depsinfo", "filtered-updatable-flatlists.txt") + ctx.Build(pctx, android.BuildParams{ + Rule: filterApexDepsRule, + Input: updatableFlatListsPath, + Output: filteredFlatLists, + }) + + // Check filtered version against allowed deps + allowedDeps := android.ExistentPathForSource(ctx, "build/soong/apex/allowed_deps.txt").Path() + s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, filteredFlatLists.Rel()+".check") + ctx.Build(pctx, android.BuildParams{ + Rule: diffAllowedApexDepsInfoRule, + Input: filteredFlatLists, + Output: s.allowedApexDepsInfoCheckResult, + Args: map[string]string{ + "allowed_flatlists": allowedDeps.String(), + "merged_flatlists": filteredFlatLists.String(), + }, + }) +} + +func (s *apexDepsInfoSingleton) MakeVars(ctx android.MakeVarsContext) { + // Export check result to Make. The path is added to droidcore. + ctx.Strict("APEX_ALLOWED_DEPS_CHECK", s.allowedApexDepsInfoCheckResult.String()) } |