apex_singleton.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (C) 2020 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package apex
  17. import (
  18. "github.com/google/blueprint"
  19. "android/soong/android"
  20. )
  21. func init() {
  22. registerApexDepsInfoComponents(android.InitRegistrationContext)
  23. }
  24. func registerApexDepsInfoComponents(ctx android.RegistrationContext) {
  25. ctx.RegisterParallelSingletonType("apex_depsinfo_singleton", apexDepsInfoSingletonFactory)
  26. }
  27. type apexDepsInfoSingleton struct {
  28. allowedApexDepsInfoCheckResult android.OutputPath
  29. }
  30. func apexDepsInfoSingletonFactory() android.Singleton {
  31. return &apexDepsInfoSingleton{}
  32. }
  33. var (
  34. // Generate new apex allowed_deps.txt by merging all internal dependencies.
  35. generateApexDepsInfoFilesRule = pctx.AndroidStaticRule("generateApexDepsInfoFilesRule", blueprint.RuleParams{
  36. Command: "cat $out.rsp | xargs cat" +
  37. // Only track non-external dependencies, i.e. those that end up in the binary
  38. " | grep -v '(external)'" +
  39. // Ignore comments in any of the files
  40. " | grep -v '^#'" +
  41. " | sort -u -f >$out",
  42. Rspfile: "$out.rsp",
  43. RspfileContent: "$in",
  44. })
  45. // Diff two given lists while ignoring comments in the allowed deps file.
  46. diffAllowedApexDepsInfoRule = pctx.AndroidStaticRule("diffAllowedApexDepsInfoRule", blueprint.RuleParams{
  47. Description: "Diff ${allowed_deps} and ${new_allowed_deps}",
  48. Command: `
  49. if grep -v '^#' ${allowed_deps} | diff -B - ${new_allowed_deps}; then
  50. touch ${out};
  51. else
  52. echo -e "\n******************************";
  53. echo "ERROR: go/apex-allowed-deps-error contains more information";
  54. echo "******************************";
  55. echo "Detected changes to allowed dependencies in updatable modules.";
  56. echo "To fix and update packages/modules/common/build/allowed_deps.txt, please run:";
  57. echo -e "$$ (croot && packages/modules/common/build/update-apex-allowed-deps.sh)\n";
  58. echo "When submitting the generated CL, you must include the following information";
  59. echo "in the commit message if you are adding a new dependency:";
  60. echo "Apex-Size-Increase: Expected binary size increase for affected APEXes (or the size of the .jar / .so file of the new library)";
  61. echo "Previous-Platform-Support: Are the maintainers of the new dependency committed to supporting previous platform releases?";
  62. echo "Aosp-First: Is the new dependency being developed AOSP-first or internal?";
  63. echo "Test-Info: What’s the testing strategy for the new dependency? Does it have its own tests, and are you adding integration tests? How/when are the tests run?";
  64. echo "You do not need OWNERS approval to submit the change, but mainline-modularization@";
  65. echo "will periodically review additions and may require changes.";
  66. echo -e "******************************\n";
  67. exit 1;
  68. fi;
  69. `,
  70. }, "allowed_deps", "new_allowed_deps")
  71. )
  72. func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  73. updatableFlatLists := android.Paths{}
  74. ctx.VisitAllModules(func(module android.Module) {
  75. if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok {
  76. apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
  77. if path := binaryInfo.FlatListPath(); path != nil {
  78. if binaryInfo.Updatable() || apexInfo.Updatable {
  79. updatableFlatLists = append(updatableFlatLists, path)
  80. }
  81. }
  82. }
  83. })
  84. allowedDepsSource := android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt")
  85. newAllowedDeps := android.PathForOutput(ctx, "apex", "depsinfo", "new-allowed-deps.txt")
  86. s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, newAllowedDeps.Rel()+".check")
  87. if !allowedDepsSource.Valid() {
  88. // Unbundled projects may not have packages/modules/common/ checked out; ignore those.
  89. ctx.Build(pctx, android.BuildParams{
  90. Rule: android.Touch,
  91. Output: s.allowedApexDepsInfoCheckResult,
  92. })
  93. } else {
  94. allowedDeps := allowedDepsSource.Path()
  95. ctx.Build(pctx, android.BuildParams{
  96. Rule: generateApexDepsInfoFilesRule,
  97. Inputs: append(updatableFlatLists, allowedDeps),
  98. Output: newAllowedDeps,
  99. })
  100. ctx.Build(pctx, android.BuildParams{
  101. Rule: diffAllowedApexDepsInfoRule,
  102. Input: newAllowedDeps,
  103. Output: s.allowedApexDepsInfoCheckResult,
  104. Args: map[string]string{
  105. "allowed_deps": allowedDeps.String(),
  106. "new_allowed_deps": newAllowedDeps.String(),
  107. },
  108. })
  109. }
  110. ctx.Phony("apex-allowed-deps-check", s.allowedApexDepsInfoCheckResult)
  111. }
  112. func (s *apexDepsInfoSingleton) MakeVars(ctx android.MakeVarsContext) {
  113. // Export check result to Make. The path is added to droidcore.
  114. ctx.Strict("APEX_ALLOWED_DEPS_CHECK", s.allowedApexDepsInfoCheckResult.String())
  115. }