Artur Satayev | 849f844 | 2020-04-28 14:57:42 +0100 | [diff] [blame] | 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 | |
| 17 | package apex |
| 18 | |
| 19 | import ( |
Spandan Das | a747d2e | 2024-03-11 21:37:25 +0000 | [diff] [blame^] | 20 | "encoding/json" |
| 21 | |
Artur Satayev | a4405fa | 2020-05-14 15:15:01 +0100 | [diff] [blame] | 22 | "github.com/google/blueprint" |
Artur Satayev | 9af168d | 2020-06-24 10:17:19 +0000 | [diff] [blame] | 23 | |
| 24 | "android/soong/android" |
Artur Satayev | 849f844 | 2020-04-28 14:57:42 +0100 | [diff] [blame] | 25 | ) |
| 26 | |
| 27 | func init() { |
Jooyung Han | 4495f84 | 2023-04-25 16:39:59 +0900 | [diff] [blame] | 28 | registerApexDepsInfoComponents(android.InitRegistrationContext) |
| 29 | } |
| 30 | |
| 31 | func registerApexDepsInfoComponents(ctx android.RegistrationContext) { |
LaMont Jones | 0c10e4d | 2023-05-16 00:58:37 +0000 | [diff] [blame] | 32 | ctx.RegisterParallelSingletonType("apex_depsinfo_singleton", apexDepsInfoSingletonFactory) |
Artur Satayev | 849f844 | 2020-04-28 14:57:42 +0100 | [diff] [blame] | 33 | } |
| 34 | |
| 35 | type apexDepsInfoSingleton struct { |
Artur Satayev | 019560f | 2020-07-02 11:51:47 +0000 | [diff] [blame] | 36 | allowedApexDepsInfoCheckResult android.OutputPath |
Artur Satayev | 849f844 | 2020-04-28 14:57:42 +0100 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | func apexDepsInfoSingletonFactory() android.Singleton { |
| 40 | return &apexDepsInfoSingleton{} |
| 41 | } |
| 42 | |
Artur Satayev | 019560f | 2020-07-02 11:51:47 +0000 | [diff] [blame] | 43 | var ( |
| 44 | // Generate new apex allowed_deps.txt by merging all internal dependencies. |
| 45 | generateApexDepsInfoFilesRule = pctx.AndroidStaticRule("generateApexDepsInfoFilesRule", blueprint.RuleParams{ |
| 46 | Command: "cat $out.rsp | xargs cat" + |
| 47 | // Only track non-external dependencies, i.e. those that end up in the binary |
| 48 | " | grep -v '(external)'" + |
| 49 | // Ignore comments in any of the files |
| 50 | " | grep -v '^#'" + |
| 51 | " | sort -u -f >$out", |
Artur Satayev | 849f844 | 2020-04-28 14:57:42 +0100 | [diff] [blame] | 52 | Rspfile: "$out.rsp", |
| 53 | RspfileContent: "$in", |
Artur Satayev | 019560f | 2020-07-02 11:51:47 +0000 | [diff] [blame] | 54 | }) |
| 55 | |
| 56 | // Diff two given lists while ignoring comments in the allowed deps file. |
| 57 | diffAllowedApexDepsInfoRule = pctx.AndroidStaticRule("diffAllowedApexDepsInfoRule", blueprint.RuleParams{ |
| 58 | Description: "Diff ${allowed_deps} and ${new_allowed_deps}", |
| 59 | Command: ` |
| 60 | if grep -v '^#' ${allowed_deps} | diff -B - ${new_allowed_deps}; then |
| 61 | touch ${out}; |
| 62 | else |
| 63 | echo -e "\n******************************"; |
Pedro Loureiro | 87c8817 | 2023-02-07 17:08:35 +0000 | [diff] [blame] | 64 | echo "ERROR: go/apex-allowed-deps-error contains more information"; |
Artur Satayev | 019560f | 2020-07-02 11:51:47 +0000 | [diff] [blame] | 65 | echo "******************************"; |
| 66 | echo "Detected changes to allowed dependencies in updatable modules."; |
Artur Satayev | 8dfcbe4 | 2021-03-11 16:45:04 +0000 | [diff] [blame] | 67 | echo "To fix and update packages/modules/common/build/allowed_deps.txt, please run:"; |
Mathew Inwood | 768a011 | 2021-08-02 16:43:05 +0100 | [diff] [blame] | 68 | echo -e "$$ (croot && packages/modules/common/build/update-apex-allowed-deps.sh)\n"; |
| 69 | echo "When submitting the generated CL, you must include the following information"; |
| 70 | echo "in the commit message if you are adding a new dependency:"; |
Pedro Loureiro | 87c8817 | 2023-02-07 17:08:35 +0000 | [diff] [blame] | 71 | echo "Apex-Size-Increase: Expected binary size increase for affected APEXes (or the size of the .jar / .so file of the new library)"; |
| 72 | echo "Previous-Platform-Support: Are the maintainers of the new dependency committed to supporting previous platform releases?"; |
| 73 | echo "Aosp-First: Is the new dependency being developed AOSP-first or internal?"; |
| 74 | 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?"; |
Mathew Inwood | 768a011 | 2021-08-02 16:43:05 +0100 | [diff] [blame] | 75 | echo "You do not need OWNERS approval to submit the change, but mainline-modularization@"; |
| 76 | echo "will periodically review additions and may require changes."; |
Artur Satayev | 019560f | 2020-07-02 11:51:47 +0000 | [diff] [blame] | 77 | echo -e "******************************\n"; |
| 78 | exit 1; |
| 79 | fi; |
| 80 | `, |
| 81 | }, "allowed_deps", "new_allowed_deps") |
Artur Satayev | 849f844 | 2020-04-28 14:57:42 +0100 | [diff] [blame] | 82 | ) |
| 83 | |
| 84 | func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) { |
Artur Satayev | 9af168d | 2020-06-24 10:17:19 +0000 | [diff] [blame] | 85 | updatableFlatLists := android.Paths{} |
Artur Satayev | 849f844 | 2020-04-28 14:57:42 +0100 | [diff] [blame] | 86 | ctx.VisitAllModules(func(module android.Module) { |
| 87 | if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok { |
Colin Cross | 5a37718 | 2023-12-14 14:46:23 -0800 | [diff] [blame] | 88 | apexInfo, _ := android.SingletonModuleProvider(ctx, module, android.ApexInfoProvider) |
Colin Cross | 56a8321 | 2020-09-15 18:30:11 -0700 | [diff] [blame] | 89 | if path := binaryInfo.FlatListPath(); path != nil { |
| 90 | if binaryInfo.Updatable() || apexInfo.Updatable { |
| 91 | updatableFlatLists = append(updatableFlatLists, path) |
| 92 | } |
Artur Satayev | 849f844 | 2020-04-28 14:57:42 +0100 | [diff] [blame] | 93 | } |
| 94 | } |
| 95 | }) |
| 96 | |
Artur Satayev | b77b0c5 | 2021-03-18 11:04:09 +0000 | [diff] [blame] | 97 | allowedDepsSource := android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt") |
Artur Satayev | 019560f | 2020-07-02 11:51:47 +0000 | [diff] [blame] | 98 | newAllowedDeps := android.PathForOutput(ctx, "apex", "depsinfo", "new-allowed-deps.txt") |
Artur Satayev | 019560f | 2020-07-02 11:51:47 +0000 | [diff] [blame] | 99 | s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, newAllowedDeps.Rel()+".check") |
Artur Satayev | b77b0c5 | 2021-03-18 11:04:09 +0000 | [diff] [blame] | 100 | |
| 101 | if !allowedDepsSource.Valid() { |
| 102 | // Unbundled projects may not have packages/modules/common/ checked out; ignore those. |
| 103 | ctx.Build(pctx, android.BuildParams{ |
| 104 | Rule: android.Touch, |
| 105 | Output: s.allowedApexDepsInfoCheckResult, |
| 106 | }) |
| 107 | } else { |
| 108 | allowedDeps := allowedDepsSource.Path() |
| 109 | |
| 110 | ctx.Build(pctx, android.BuildParams{ |
| 111 | Rule: generateApexDepsInfoFilesRule, |
| 112 | Inputs: append(updatableFlatLists, allowedDeps), |
| 113 | Output: newAllowedDeps, |
| 114 | }) |
| 115 | |
| 116 | ctx.Build(pctx, android.BuildParams{ |
| 117 | Rule: diffAllowedApexDepsInfoRule, |
| 118 | Input: newAllowedDeps, |
| 119 | Output: s.allowedApexDepsInfoCheckResult, |
| 120 | Args: map[string]string{ |
| 121 | "allowed_deps": allowedDeps.String(), |
| 122 | "new_allowed_deps": newAllowedDeps.String(), |
| 123 | }, |
| 124 | }) |
| 125 | } |
Artur Satayev | 01aa11e | 2020-07-30 18:26:28 +0100 | [diff] [blame] | 126 | |
| 127 | ctx.Phony("apex-allowed-deps-check", s.allowedApexDepsInfoCheckResult) |
Artur Satayev | 019560f | 2020-07-02 11:51:47 +0000 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | func (s *apexDepsInfoSingleton) MakeVars(ctx android.MakeVarsContext) { |
| 131 | // Export check result to Make. The path is added to droidcore. |
| 132 | ctx.Strict("APEX_ALLOWED_DEPS_CHECK", s.allowedApexDepsInfoCheckResult.String()) |
Artur Satayev | 849f844 | 2020-04-28 14:57:42 +0100 | [diff] [blame] | 133 | } |
Spandan Das | a747d2e | 2024-03-11 21:37:25 +0000 | [diff] [blame^] | 134 | |
| 135 | func init() { |
| 136 | registerApexPrebuiltInfoComponents(android.InitRegistrationContext) |
| 137 | } |
| 138 | |
| 139 | func registerApexPrebuiltInfoComponents(ctx android.RegistrationContext) { |
| 140 | ctx.RegisterParallelSingletonType("apex_prebuiltinfo_singleton", apexPrebuiltInfoFactory) |
| 141 | } |
| 142 | |
| 143 | func apexPrebuiltInfoFactory() android.Singleton { |
| 144 | return &apexPrebuiltInfo{} |
| 145 | } |
| 146 | |
| 147 | type apexPrebuiltInfo struct { |
| 148 | out android.WritablePath |
| 149 | } |
| 150 | |
| 151 | func (a *apexPrebuiltInfo) GenerateBuildActions(ctx android.SingletonContext) { |
| 152 | prebuiltInfos := []prebuiltInfo{} |
| 153 | |
| 154 | ctx.VisitAllModules(func(m android.Module) { |
| 155 | prebuiltInfo, exists := android.SingletonModuleProvider(ctx, m, prebuiltInfoProvider) |
| 156 | // Use prebuiltInfoProvider to filter out non apex soong modules. |
| 157 | // Use HideFromMake to filter out the unselected variants of a specific apex. |
| 158 | if exists && !m.IsHideFromMake() { |
| 159 | prebuiltInfos = append(prebuiltInfos, prebuiltInfo) |
| 160 | } |
| 161 | }) |
| 162 | |
| 163 | j, err := json.Marshal(prebuiltInfos) |
| 164 | if err != nil { |
| 165 | ctx.Errorf("Could not convert prebuilt info of apexes to json due to error: %v", err) |
| 166 | } |
| 167 | a.out = android.PathForOutput(ctx, "prebuilt_info.json") |
| 168 | android.WriteFileRule(ctx, a.out, string(j)) |
| 169 | } |
| 170 | |
| 171 | func (a *apexPrebuiltInfo) MakeVars(ctx android.MakeVarsContext) { |
| 172 | ctx.DistForGoal("droidcore", a.out) |
| 173 | } |