3490dfd23f
This is a followup to aosp/2999198 and adds information about apps. Each app will have an entry in this file with the following properties - Name, mandatory - Is_prebuilt, mandatory - Prebuilt_info_file_path, optional Implementation details - Move prebuiltInfoProvider out of build/soong/apex to build/soong/android. This allows build/soong/java to use it. - Introduce a new `prebuilt_info` prop to `android_app_set` and `android_app_import` - All app module types will set a prebuiltInfoProvider in GenerateAndroidBuildActions, including the source app module types Test: m nothing --no-skip-soong-tests Test: m out/soong/prebuilt_info.json Test: ls -l out/soong/prebuilt_info.json --human-readable -rw------- 1 spandandas primarygroup 317K Mar 11 23:46 out/soong/prebuilt_info.json Test: #modified trunk_staging.locally to select prebuilts of some mainline apps. Spot-checked that `is_prebuilt` and `prebuilt_info_file_path` get populated appropriately Bug: 327480225 Change-Id: I5078e0ec26c9568194550909962b90111a5223f7
173 lines
6.4 KiB
Go
173 lines
6.4 KiB
Go
/*
|
||
* Copyright (C) 2020 The Android Open Source Project
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
*/
|
||
|
||
package apex
|
||
|
||
import (
|
||
"encoding/json"
|
||
|
||
"github.com/google/blueprint"
|
||
|
||
"android/soong/android"
|
||
)
|
||
|
||
func init() {
|
||
registerApexDepsInfoComponents(android.InitRegistrationContext)
|
||
}
|
||
|
||
func registerApexDepsInfoComponents(ctx android.RegistrationContext) {
|
||
ctx.RegisterParallelSingletonType("apex_depsinfo_singleton", apexDepsInfoSingletonFactory)
|
||
}
|
||
|
||
type apexDepsInfoSingleton struct {
|
||
allowedApexDepsInfoCheckResult android.OutputPath
|
||
}
|
||
|
||
func apexDepsInfoSingletonFactory() android.Singleton {
|
||
return &apexDepsInfoSingleton{}
|
||
}
|
||
|
||
var (
|
||
// Generate new apex allowed_deps.txt by merging all internal dependencies.
|
||
generateApexDepsInfoFilesRule = pctx.AndroidStaticRule("generateApexDepsInfoFilesRule", blueprint.RuleParams{
|
||
Command: "cat $out.rsp | xargs cat" +
|
||
// Only track non-external dependencies, i.e. those that end up in the binary
|
||
" | grep -v '(external)'" +
|
||
// Ignore comments in any of the files
|
||
" | grep -v '^#'" +
|
||
" | sort -u -f >$out",
|
||
Rspfile: "$out.rsp",
|
||
RspfileContent: "$in",
|
||
})
|
||
|
||
// Diff two given lists while ignoring comments in the allowed deps file.
|
||
diffAllowedApexDepsInfoRule = pctx.AndroidStaticRule("diffAllowedApexDepsInfoRule", blueprint.RuleParams{
|
||
Description: "Diff ${allowed_deps} and ${new_allowed_deps}",
|
||
Command: `
|
||
if grep -v '^#' ${allowed_deps} | diff -B - ${new_allowed_deps}; then
|
||
touch ${out};
|
||
else
|
||
echo -e "\n******************************";
|
||
echo "ERROR: go/apex-allowed-deps-error contains more information";
|
||
echo "******************************";
|
||
echo "Detected changes to allowed dependencies in updatable modules.";
|
||
echo "To fix and update packages/modules/common/build/allowed_deps.txt, please run:";
|
||
echo -e "$$ (croot && packages/modules/common/build/update-apex-allowed-deps.sh)\n";
|
||
echo "When submitting the generated CL, you must include the following information";
|
||
echo "in the commit message if you are adding a new dependency:";
|
||
echo "Apex-Size-Increase: Expected binary size increase for affected APEXes (or the size of the .jar / .so file of the new library)";
|
||
echo "Previous-Platform-Support: Are the maintainers of the new dependency committed to supporting previous platform releases?";
|
||
echo "Aosp-First: Is the new dependency being developed AOSP-first or internal?";
|
||
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?";
|
||
echo "You do not need OWNERS approval to submit the change, but mainline-modularization@";
|
||
echo "will periodically review additions and may require changes.";
|
||
echo -e "******************************\n";
|
||
exit 1;
|
||
fi;
|
||
`,
|
||
}, "allowed_deps", "new_allowed_deps")
|
||
)
|
||
|
||
func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||
updatableFlatLists := android.Paths{}
|
||
ctx.VisitAllModules(func(module android.Module) {
|
||
if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok {
|
||
apexInfo, _ := android.SingletonModuleProvider(ctx, module, android.ApexInfoProvider)
|
||
if path := binaryInfo.FlatListPath(); path != nil {
|
||
if binaryInfo.Updatable() || apexInfo.Updatable {
|
||
updatableFlatLists = append(updatableFlatLists, path)
|
||
}
|
||
}
|
||
}
|
||
})
|
||
|
||
allowedDepsSource := android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt")
|
||
newAllowedDeps := android.PathForOutput(ctx, "apex", "depsinfo", "new-allowed-deps.txt")
|
||
s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, newAllowedDeps.Rel()+".check")
|
||
|
||
if !allowedDepsSource.Valid() {
|
||
// Unbundled projects may not have packages/modules/common/ checked out; ignore those.
|
||
ctx.Build(pctx, android.BuildParams{
|
||
Rule: android.Touch,
|
||
Output: s.allowedApexDepsInfoCheckResult,
|
||
})
|
||
} else {
|
||
allowedDeps := allowedDepsSource.Path()
|
||
|
||
ctx.Build(pctx, android.BuildParams{
|
||
Rule: generateApexDepsInfoFilesRule,
|
||
Inputs: append(updatableFlatLists, allowedDeps),
|
||
Output: newAllowedDeps,
|
||
})
|
||
|
||
ctx.Build(pctx, android.BuildParams{
|
||
Rule: diffAllowedApexDepsInfoRule,
|
||
Input: newAllowedDeps,
|
||
Output: s.allowedApexDepsInfoCheckResult,
|
||
Args: map[string]string{
|
||
"allowed_deps": allowedDeps.String(),
|
||
"new_allowed_deps": newAllowedDeps.String(),
|
||
},
|
||
})
|
||
}
|
||
|
||
ctx.Phony("apex-allowed-deps-check", s.allowedApexDepsInfoCheckResult)
|
||
}
|
||
|
||
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())
|
||
}
|
||
|
||
func init() {
|
||
registerApexPrebuiltInfoComponents(android.InitRegistrationContext)
|
||
}
|
||
|
||
func registerApexPrebuiltInfoComponents(ctx android.RegistrationContext) {
|
||
ctx.RegisterParallelSingletonType("apex_prebuiltinfo_singleton", apexPrebuiltInfoFactory)
|
||
}
|
||
|
||
func apexPrebuiltInfoFactory() android.Singleton {
|
||
return &apexPrebuiltInfo{}
|
||
}
|
||
|
||
type apexPrebuiltInfo struct {
|
||
out android.WritablePath
|
||
}
|
||
|
||
func (a *apexPrebuiltInfo) GenerateBuildActions(ctx android.SingletonContext) {
|
||
prebuiltInfos := []android.PrebuiltInfo{}
|
||
|
||
ctx.VisitAllModules(func(m android.Module) {
|
||
prebuiltInfo, exists := android.SingletonModuleProvider(ctx, m, android.PrebuiltInfoProvider)
|
||
// Use prebuiltInfoProvider to filter out non apex soong modules.
|
||
// Use HideFromMake to filter out the unselected variants of a specific apex.
|
||
if exists && !m.IsHideFromMake() {
|
||
prebuiltInfos = append(prebuiltInfos, prebuiltInfo)
|
||
}
|
||
})
|
||
|
||
j, err := json.Marshal(prebuiltInfos)
|
||
if err != nil {
|
||
ctx.Errorf("Could not convert prebuilt info of apexes to json due to error: %v", err)
|
||
}
|
||
a.out = android.PathForOutput(ctx, "prebuilt_info.json")
|
||
android.WriteFileRule(ctx, a.out, string(j))
|
||
}
|
||
|
||
func (a *apexPrebuiltInfo) MakeVars(ctx android.MakeVarsContext) {
|
||
ctx.DistForGoal("droidcore", a.out)
|
||
}
|