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