1*333d2b36SAndroid Build Coastguard Worker/* 2*333d2b36SAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project 3*333d2b36SAndroid Build Coastguard Worker * 4*333d2b36SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*333d2b36SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*333d2b36SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*333d2b36SAndroid Build Coastguard Worker * 8*333d2b36SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*333d2b36SAndroid Build Coastguard Worker * 10*333d2b36SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*333d2b36SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*333d2b36SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*333d2b36SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*333d2b36SAndroid Build Coastguard Worker * limitations under the License. 15*333d2b36SAndroid Build Coastguard Worker */ 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerpackage apex 18*333d2b36SAndroid Build Coastguard Worker 19*333d2b36SAndroid Build Coastguard Workerimport ( 20*333d2b36SAndroid Build Coastguard Worker "encoding/json" 21*333d2b36SAndroid Build Coastguard Worker "strings" 22*333d2b36SAndroid Build Coastguard Worker 23*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 26*333d2b36SAndroid Build Coastguard Worker) 27*333d2b36SAndroid Build Coastguard Worker 28*333d2b36SAndroid Build Coastguard Workerfunc init() { 29*333d2b36SAndroid Build Coastguard Worker registerApexDepsInfoComponents(android.InitRegistrationContext) 30*333d2b36SAndroid Build Coastguard Worker} 31*333d2b36SAndroid Build Coastguard Worker 32*333d2b36SAndroid Build Coastguard Workerfunc registerApexDepsInfoComponents(ctx android.RegistrationContext) { 33*333d2b36SAndroid Build Coastguard Worker ctx.RegisterParallelSingletonType("apex_depsinfo_singleton", apexDepsInfoSingletonFactory) 34*333d2b36SAndroid Build Coastguard Worker} 35*333d2b36SAndroid Build Coastguard Worker 36*333d2b36SAndroid Build Coastguard Workertype apexDepsInfoSingleton struct { 37*333d2b36SAndroid Build Coastguard Worker allowedApexDepsInfoCheckResult android.OutputPath 38*333d2b36SAndroid Build Coastguard Worker} 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Workerfunc apexDepsInfoSingletonFactory() android.Singleton { 41*333d2b36SAndroid Build Coastguard Worker return &apexDepsInfoSingleton{} 42*333d2b36SAndroid Build Coastguard Worker} 43*333d2b36SAndroid Build Coastguard Worker 44*333d2b36SAndroid Build Coastguard Workervar ( 45*333d2b36SAndroid Build Coastguard Worker // Generate new apex allowed_deps.txt by merging all internal dependencies. 46*333d2b36SAndroid Build Coastguard Worker generateApexDepsInfoFilesRule = pctx.AndroidStaticRule("generateApexDepsInfoFilesRule", blueprint.RuleParams{ 47*333d2b36SAndroid Build Coastguard Worker Command: "cat $out.rsp | xargs cat" + 48*333d2b36SAndroid Build Coastguard Worker // Only track non-external dependencies, i.e. those that end up in the binary 49*333d2b36SAndroid Build Coastguard Worker " | grep -v '(external)'" + 50*333d2b36SAndroid Build Coastguard Worker // Allowlist androidx deps 51*333d2b36SAndroid Build Coastguard Worker " | grep -v '^androidx\\.'" + 52*333d2b36SAndroid Build Coastguard Worker " | grep -v '^prebuilt_androidx\\.'" + 53*333d2b36SAndroid Build Coastguard Worker // Ignore comments in any of the files 54*333d2b36SAndroid Build Coastguard Worker " | grep -v '^#'" + 55*333d2b36SAndroid Build Coastguard Worker " | sort -u -f >$out", 56*333d2b36SAndroid Build Coastguard Worker Rspfile: "$out.rsp", 57*333d2b36SAndroid Build Coastguard Worker RspfileContent: "$in", 58*333d2b36SAndroid Build Coastguard Worker }) 59*333d2b36SAndroid Build Coastguard Worker 60*333d2b36SAndroid Build Coastguard Worker // Diff two given lists while ignoring comments in the allowed deps file. 61*333d2b36SAndroid Build Coastguard Worker diffAllowedApexDepsInfoRule = pctx.AndroidStaticRule("diffAllowedApexDepsInfoRule", blueprint.RuleParams{ 62*333d2b36SAndroid Build Coastguard Worker Description: "Diff ${allowed_deps_list} and ${new_allowed_deps}", 63*333d2b36SAndroid Build Coastguard Worker Command: ` 64*333d2b36SAndroid Build Coastguard Worker if grep -v -h '^#' ${allowed_deps_list} | sort -u -f| diff -B -u - ${new_allowed_deps}; then 65*333d2b36SAndroid Build Coastguard Worker touch ${out}; 66*333d2b36SAndroid Build Coastguard Worker else 67*333d2b36SAndroid Build Coastguard Worker echo; 68*333d2b36SAndroid Build Coastguard Worker echo "******************************"; 69*333d2b36SAndroid Build Coastguard Worker echo "ERROR: go/apex-allowed-deps-error contains more information"; 70*333d2b36SAndroid Build Coastguard Worker echo "******************************"; 71*333d2b36SAndroid Build Coastguard Worker echo "Detected changes to allowed dependencies in updatable modules."; 72*333d2b36SAndroid Build Coastguard Worker echo "To fix and update packages/modules/common/build/allowed_deps.txt, please run:"; 73*333d2b36SAndroid Build Coastguard Worker echo "$$ (croot && packages/modules/common/build/update-apex-allowed-deps.sh)"; 74*333d2b36SAndroid Build Coastguard Worker echo; 75*333d2b36SAndroid Build Coastguard Worker echo "When submitting the generated CL, you must include the following information"; 76*333d2b36SAndroid Build Coastguard Worker echo "in the commit message if you are adding a new dependency:"; 77*333d2b36SAndroid Build Coastguard Worker echo "Apex-Size-Increase: Expected binary size increase for affected APEXes (or the size of the .jar / .so file of the new library)"; 78*333d2b36SAndroid Build Coastguard Worker echo "Previous-Platform-Support: Are the maintainers of the new dependency committed to supporting previous platform releases?"; 79*333d2b36SAndroid Build Coastguard Worker echo "Aosp-First: Is the new dependency being developed AOSP-first or internal?"; 80*333d2b36SAndroid Build Coastguard Worker 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?"; 81*333d2b36SAndroid Build Coastguard Worker echo "You do not need OWNERS approval to submit the change, but mainline-modularization@"; 82*333d2b36SAndroid Build Coastguard Worker echo "will periodically review additions and may require changes."; 83*333d2b36SAndroid Build Coastguard Worker echo "******************************"; 84*333d2b36SAndroid Build Coastguard Worker echo; 85*333d2b36SAndroid Build Coastguard Worker exit 1; 86*333d2b36SAndroid Build Coastguard Worker fi; 87*333d2b36SAndroid Build Coastguard Worker `, 88*333d2b36SAndroid Build Coastguard Worker }, "allowed_deps_list", "new_allowed_deps") 89*333d2b36SAndroid Build Coastguard Worker) 90*333d2b36SAndroid Build Coastguard Worker 91*333d2b36SAndroid Build Coastguard Workerfunc (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) { 92*333d2b36SAndroid Build Coastguard Worker allowedDepsSources := []android.OptionalPath{android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt")} 93*333d2b36SAndroid Build Coastguard Worker extraAllowedDepsPath := ctx.Config().ExtraAllowedDepsTxt() 94*333d2b36SAndroid Build Coastguard Worker if extraAllowedDepsPath != "" { 95*333d2b36SAndroid Build Coastguard Worker allowedDepsSources = append(allowedDepsSources, android.ExistentPathForSource(ctx, extraAllowedDepsPath)) 96*333d2b36SAndroid Build Coastguard Worker } 97*333d2b36SAndroid Build Coastguard Worker updatableFlatLists := android.Paths{} 98*333d2b36SAndroid Build Coastguard Worker ctx.VisitAllModules(func(module android.Module) { 99*333d2b36SAndroid Build Coastguard Worker if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok { 100*333d2b36SAndroid Build Coastguard Worker apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider) 101*333d2b36SAndroid Build Coastguard Worker if path := binaryInfo.FlatListPath(); path != nil { 102*333d2b36SAndroid Build Coastguard Worker if binaryInfo.Updatable() || apexInfo.Updatable { 103*333d2b36SAndroid Build Coastguard Worker updatableFlatLists = append(updatableFlatLists, path) 104*333d2b36SAndroid Build Coastguard Worker } 105*333d2b36SAndroid Build Coastguard Worker } 106*333d2b36SAndroid Build Coastguard Worker } 107*333d2b36SAndroid Build Coastguard Worker }) 108*333d2b36SAndroid Build Coastguard Worker newAllowedDeps := android.PathForOutput(ctx, "apex", "depsinfo", "new-allowed-deps.txt") 109*333d2b36SAndroid Build Coastguard Worker s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, newAllowedDeps.Rel()+".check") 110*333d2b36SAndroid Build Coastguard Worker hasOneValidDepsPath := false 111*333d2b36SAndroid Build Coastguard Worker for _, allowedDepsSource := range allowedDepsSources { 112*333d2b36SAndroid Build Coastguard Worker if allowedDepsSource.Valid() { 113*333d2b36SAndroid Build Coastguard Worker hasOneValidDepsPath = true 114*333d2b36SAndroid Build Coastguard Worker updatableFlatLists = append(updatableFlatLists, allowedDepsSource.Path()) 115*333d2b36SAndroid Build Coastguard Worker } 116*333d2b36SAndroid Build Coastguard Worker } 117*333d2b36SAndroid Build Coastguard Worker allowedDepsStrList := make([]string, len(allowedDepsSources)) 118*333d2b36SAndroid Build Coastguard Worker for _, value := range allowedDepsSources { 119*333d2b36SAndroid Build Coastguard Worker allowedDepsStrList = append(allowedDepsStrList, value.String()) 120*333d2b36SAndroid Build Coastguard Worker } 121*333d2b36SAndroid Build Coastguard Worker allowedDepsListString := strings.Join(allowedDepsStrList, " ") 122*333d2b36SAndroid Build Coastguard Worker if !hasOneValidDepsPath { 123*333d2b36SAndroid Build Coastguard Worker // Unbundled projects may not have packages/modules/common/ checked out; ignore those. 124*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 125*333d2b36SAndroid Build Coastguard Worker Rule: android.Touch, 126*333d2b36SAndroid Build Coastguard Worker Output: s.allowedApexDepsInfoCheckResult, 127*333d2b36SAndroid Build Coastguard Worker }) 128*333d2b36SAndroid Build Coastguard Worker } else { 129*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 130*333d2b36SAndroid Build Coastguard Worker Rule: generateApexDepsInfoFilesRule, 131*333d2b36SAndroid Build Coastguard Worker Inputs: updatableFlatLists, 132*333d2b36SAndroid Build Coastguard Worker Output: newAllowedDeps, 133*333d2b36SAndroid Build Coastguard Worker }) 134*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 135*333d2b36SAndroid Build Coastguard Worker Rule: diffAllowedApexDepsInfoRule, 136*333d2b36SAndroid Build Coastguard Worker Input: newAllowedDeps, 137*333d2b36SAndroid Build Coastguard Worker Output: s.allowedApexDepsInfoCheckResult, 138*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 139*333d2b36SAndroid Build Coastguard Worker "allowed_deps_list": allowedDepsListString, 140*333d2b36SAndroid Build Coastguard Worker "new_allowed_deps": newAllowedDeps.String(), 141*333d2b36SAndroid Build Coastguard Worker }, 142*333d2b36SAndroid Build Coastguard Worker }) 143*333d2b36SAndroid Build Coastguard Worker } 144*333d2b36SAndroid Build Coastguard Worker ctx.Phony("apex-allowed-deps-check", s.allowedApexDepsInfoCheckResult) 145*333d2b36SAndroid Build Coastguard Worker} 146*333d2b36SAndroid Build Coastguard Worker 147*333d2b36SAndroid Build Coastguard Workerfunc (s *apexDepsInfoSingleton) MakeVars(ctx android.MakeVarsContext) { 148*333d2b36SAndroid Build Coastguard Worker // Export check result to Make. The path is added to droidcore. 149*333d2b36SAndroid Build Coastguard Worker ctx.Strict("APEX_ALLOWED_DEPS_CHECK", s.allowedApexDepsInfoCheckResult.String()) 150*333d2b36SAndroid Build Coastguard Worker} 151*333d2b36SAndroid Build Coastguard Worker 152*333d2b36SAndroid Build Coastguard Workerfunc init() { 153*333d2b36SAndroid Build Coastguard Worker registerApexPrebuiltInfoComponents(android.InitRegistrationContext) 154*333d2b36SAndroid Build Coastguard Worker} 155*333d2b36SAndroid Build Coastguard Worker 156*333d2b36SAndroid Build Coastguard Workerfunc registerApexPrebuiltInfoComponents(ctx android.RegistrationContext) { 157*333d2b36SAndroid Build Coastguard Worker ctx.RegisterParallelSingletonType("apex_prebuiltinfo_singleton", apexPrebuiltInfoFactory) 158*333d2b36SAndroid Build Coastguard Worker} 159*333d2b36SAndroid Build Coastguard Worker 160*333d2b36SAndroid Build Coastguard Workerfunc apexPrebuiltInfoFactory() android.Singleton { 161*333d2b36SAndroid Build Coastguard Worker return &apexPrebuiltInfo{} 162*333d2b36SAndroid Build Coastguard Worker} 163*333d2b36SAndroid Build Coastguard Worker 164*333d2b36SAndroid Build Coastguard Workertype apexPrebuiltInfo struct { 165*333d2b36SAndroid Build Coastguard Worker out android.WritablePath 166*333d2b36SAndroid Build Coastguard Worker} 167*333d2b36SAndroid Build Coastguard Worker 168*333d2b36SAndroid Build Coastguard Workerfunc (a *apexPrebuiltInfo) GenerateBuildActions(ctx android.SingletonContext) { 169*333d2b36SAndroid Build Coastguard Worker prebuiltInfos := []android.PrebuiltInfo{} 170*333d2b36SAndroid Build Coastguard Worker 171*333d2b36SAndroid Build Coastguard Worker ctx.VisitAllModules(func(m android.Module) { 172*333d2b36SAndroid Build Coastguard Worker prebuiltInfo, exists := android.OtherModuleProvider(ctx, m, android.PrebuiltInfoProvider) 173*333d2b36SAndroid Build Coastguard Worker // Use prebuiltInfoProvider to filter out non apex soong modules. 174*333d2b36SAndroid Build Coastguard Worker // Use HideFromMake to filter out the unselected variants of a specific apex. 175*333d2b36SAndroid Build Coastguard Worker if exists && !m.IsHideFromMake() { 176*333d2b36SAndroid Build Coastguard Worker prebuiltInfos = append(prebuiltInfos, prebuiltInfo) 177*333d2b36SAndroid Build Coastguard Worker } 178*333d2b36SAndroid Build Coastguard Worker }) 179*333d2b36SAndroid Build Coastguard Worker 180*333d2b36SAndroid Build Coastguard Worker j, err := json.Marshal(prebuiltInfos) 181*333d2b36SAndroid Build Coastguard Worker if err != nil { 182*333d2b36SAndroid Build Coastguard Worker ctx.Errorf("Could not convert prebuilt info of apexes to json due to error: %v", err) 183*333d2b36SAndroid Build Coastguard Worker } 184*333d2b36SAndroid Build Coastguard Worker a.out = android.PathForOutput(ctx, "prebuilt_info.json") 185*333d2b36SAndroid Build Coastguard Worker android.WriteFileRule(ctx, a.out, string(j)) 186*333d2b36SAndroid Build Coastguard Worker} 187*333d2b36SAndroid Build Coastguard Worker 188*333d2b36SAndroid Build Coastguard Workerfunc (a *apexPrebuiltInfo) MakeVars(ctx android.MakeVarsContext) { 189*333d2b36SAndroid Build Coastguard Worker ctx.DistForGoal("droidcore", a.out) 190*333d2b36SAndroid Build Coastguard Worker} 191