Support trimmed variant build in soong
variable.go: add a new product variable TrimmedApex which is controlled by environment variable PRODUCT_TRIMMED_APEX config.go: all config to check if trimmed build is turned on or not apex.go: add overridable apex module property: use_DCLA: <DCLA apex module> "use_DCLA" allows user to just use the lib list in DCLA to determine which native shared libraries to trim. This property is no-op if TrimApexEnabled is set to false. builder.go 1, if it is to produce a trimmed variant, fix the default version code by making the last variant digit to 2. this is only useful in local build. in production build, there is apex manifest injection by coastguard that determines the actual version code. 2, create a new apex rule called: "TrimmedApexRule", this rule invokes an apexer wrapper called apexer_with_trim_preprocessing which will properly trim the target libs. BUG: b/259381334 TEST: adbd banchan build for both static and trimmed variant Change-Id: I38a91cdef86a3c9185d00610ab3dd7acd07fd90a
This commit is contained in:
@@ -1498,6 +1498,10 @@ func (c *config) ApexCompressionEnabled() bool {
|
||||
return Bool(c.productVariables.CompressedApex) && !c.UnbundledBuildApps()
|
||||
}
|
||||
|
||||
func (c *config) ApexTrimEnabled() bool {
|
||||
return Bool(c.productVariables.TrimmedApex)
|
||||
}
|
||||
|
||||
func (c *config) EnforceSystemCertificate() bool {
|
||||
return Bool(c.productVariables.EnforceSystemCertificate)
|
||||
}
|
||||
|
@@ -380,6 +380,7 @@ type productVariables struct {
|
||||
|
||||
Ndk_abis *bool `json:",omitempty"`
|
||||
|
||||
TrimmedApex *bool `json:",omitempty"`
|
||||
Flatten_apex *bool `json:",omitempty"`
|
||||
ForceApexSymlinkOptimization *bool `json:",omitempty"`
|
||||
CompressedApex *bool `json:",omitempty"`
|
||||
@@ -502,6 +503,7 @@ func (v *productVariables) SetDefaultConfig() {
|
||||
Malloc_zero_contents: boolPtr(true),
|
||||
Malloc_pattern_fill_contents: boolPtr(false),
|
||||
Safestack: boolPtr(false),
|
||||
TrimmedApex: boolPtr(false),
|
||||
|
||||
BootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}},
|
||||
ApexBootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}},
|
||||
|
52
apex/apex.go
52
apex/apex.go
@@ -80,6 +80,7 @@ func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
|
||||
ctx.BottomUp("apex", apexMutator).Parallel()
|
||||
ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
|
||||
ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
|
||||
ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel()
|
||||
// Register after apex_info mutator so that it can use ApexVariationName
|
||||
ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
|
||||
}
|
||||
@@ -389,6 +390,9 @@ type overridableProperties struct {
|
||||
// conditions, e.g., target device needs to support APEX compression, are also fulfilled.
|
||||
// Default: false.
|
||||
Compressible *bool
|
||||
|
||||
// Trim against a specific Dynamic Common Lib APEX
|
||||
Trim_against *string
|
||||
}
|
||||
|
||||
type apexBundle struct {
|
||||
@@ -675,6 +679,7 @@ var (
|
||||
androidAppTag = &dependencyTag{name: "androidApp", payload: true}
|
||||
bpfTag = &dependencyTag{name: "bpf", payload: true}
|
||||
certificateTag = &dependencyTag{name: "certificate"}
|
||||
dclaTag = &dependencyTag{name: "dcla"}
|
||||
executableTag = &dependencyTag{name: "executable", payload: true}
|
||||
fsTag = &dependencyTag{name: "filesystem", payload: true}
|
||||
bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
|
||||
@@ -908,6 +913,33 @@ func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato
|
||||
}
|
||||
}
|
||||
|
||||
func apexDCLADepsMutator(mctx android.BottomUpMutatorContext) {
|
||||
if !mctx.Config().ApexTrimEnabled() {
|
||||
return
|
||||
}
|
||||
if a, ok := mctx.Module().(*apexBundle); ok && a.overridableProperties.Trim_against != nil {
|
||||
commonVariation := mctx.Config().AndroidCommonTarget.Variations()
|
||||
mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(a.overridableProperties.Trim_against))
|
||||
} else if o, ok := mctx.Module().(*OverrideApex); ok {
|
||||
for _, p := range o.GetProperties() {
|
||||
properties, ok := p.(*overridableProperties)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if properties.Trim_against != nil {
|
||||
commonVariation := mctx.Config().AndroidCommonTarget.Variations()
|
||||
mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(properties.Trim_against))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type DCLAInfo struct {
|
||||
ProvidedLibs []string
|
||||
}
|
||||
|
||||
var DCLAInfoProvider = blueprint.NewMutatorProvider(DCLAInfo{}, "apex_info")
|
||||
|
||||
type ApexBundleInfo struct {
|
||||
Contents *android.ApexContents
|
||||
}
|
||||
@@ -1035,6 +1067,12 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
|
||||
child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
|
||||
return true
|
||||
})
|
||||
|
||||
if a.dynamic_common_lib_apex() {
|
||||
mctx.SetProvider(DCLAInfoProvider, DCLAInfo{
|
||||
ProvidedLibs: a.properties.Native_shared_libs,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type ApexInfoMutator interface {
|
||||
@@ -1531,6 +1569,19 @@ func (a *apexBundle) dynamic_common_lib_apex() bool {
|
||||
return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
|
||||
}
|
||||
|
||||
// See the list of libs to trim
|
||||
func (a *apexBundle) libs_to_trim(ctx android.ModuleContext) []string {
|
||||
dclaModules := ctx.GetDirectDepsWithTag(dclaTag)
|
||||
if len(dclaModules) > 1 {
|
||||
panic(fmt.Errorf("expected exactly at most one dcla dependency, got %d", len(dclaModules)))
|
||||
}
|
||||
if len(dclaModules) > 0 {
|
||||
DCLAInfo := ctx.OtherModuleProvider(dclaModules[0], DCLAInfoProvider).(DCLAInfo)
|
||||
return DCLAInfo.ProvidedLibs
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
|
||||
// members) can be sanitized, either forcibly, or by the global configuration. For some of the
|
||||
// sanitizers, extra dependencies can be forcibly added as well.
|
||||
@@ -2473,7 +2524,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 2) traverse the dependency tree to collect apexFile structs from them.
|
||||
|
||||
// Collect the module directory for IDE info in java/jdeps.go.
|
||||
a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
|
||||
|
||||
|
@@ -40,6 +40,8 @@ func init() {
|
||||
pctx.Import("android/soong/java")
|
||||
pctx.HostBinToolVariable("apexer", "apexer")
|
||||
pctx.HostBinToolVariable("apexer_with_DCLA_preprocessing", "apexer_with_DCLA_preprocessing")
|
||||
pctx.HostBinToolVariable("apexer_with_trim_preprocessing", "apexer_with_trim_preprocessing")
|
||||
|
||||
// ART minimal builds (using the master-art manifest) do not have the "frameworks/base"
|
||||
// projects, and hence cannot build 'aapt2'. Use the SDK prebuilt instead.
|
||||
hostBinToolVariableWithPrebuilt := func(name, prebuiltDir, tool string) {
|
||||
@@ -146,6 +148,34 @@ var (
|
||||
}, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key",
|
||||
"opt_flags", "manifest", "is_DCLA")
|
||||
|
||||
TrimmedApexRule = pctx.StaticRule("TrimmedApexRule", blueprint.RuleParams{
|
||||
Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` +
|
||||
`(. ${out}.copy_commands) && ` +
|
||||
`APEXER_TOOL_PATH=${tool_path} ` +
|
||||
`${apexer_with_trim_preprocessing} ` +
|
||||
`--apexer ${apexer} ` +
|
||||
`--canned_fs_config ${canned_fs_config} ` +
|
||||
`--manifest ${manifest} ` +
|
||||
`--libs_to_trim ${libs_to_trim} ` +
|
||||
`${image_dir} ` +
|
||||
`${out} ` +
|
||||
`-- ` +
|
||||
`--include_build_info ` +
|
||||
`--force ` +
|
||||
`--payload_type image ` +
|
||||
`--key ${key} ` +
|
||||
`--file_contexts ${file_contexts} ` +
|
||||
`${opt_flags} `,
|
||||
CommandDeps: []string{"${apexer_with_trim_preprocessing}", "${apexer}", "${avbtool}", "${e2fsdroid}",
|
||||
"${merge_zips}", "${mke2fs}", "${resize2fs}", "${sefcontext_compile}", "${make_f2fs}",
|
||||
"${sload_f2fs}", "${make_erofs}", "${soong_zip}", "${zipalign}", "${aapt2}",
|
||||
"prebuilts/sdk/current/public/android.jar"},
|
||||
Rspfile: "${out}.copy_commands",
|
||||
RspfileContent: "${copy_commands}",
|
||||
Description: "APEX ${image_dir} => ${out}",
|
||||
}, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key",
|
||||
"opt_flags", "manifest", "libs_to_trim")
|
||||
|
||||
zipApexRule = pctx.StaticRule("zipApexRule", blueprint.RuleParams{
|
||||
Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` +
|
||||
`(. ${out}.copy_commands) && ` +
|
||||
@@ -706,6 +736,24 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
||||
"opt_flags": strings.Join(optFlags, " "),
|
||||
},
|
||||
})
|
||||
} else if ctx.Config().ApexTrimEnabled() && len(a.libs_to_trim(ctx)) > 0 {
|
||||
ctx.Build(pctx, android.BuildParams{
|
||||
Rule: TrimmedApexRule,
|
||||
Implicits: implicitInputs,
|
||||
Output: unsignedOutputFile,
|
||||
Description: "apex (" + apexType.name() + ")",
|
||||
Args: map[string]string{
|
||||
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
||||
"image_dir": imageDir.String(),
|
||||
"copy_commands": strings.Join(copyCommands, " && "),
|
||||
"manifest": a.manifestPbOut.String(),
|
||||
"file_contexts": fileContexts.String(),
|
||||
"canned_fs_config": cannedFsConfig.String(),
|
||||
"key": a.privateKeyFile.String(),
|
||||
"opt_flags": strings.Join(optFlags, " "),
|
||||
"libs_to_trim": strings.Join(a.libs_to_trim(ctx), ","),
|
||||
},
|
||||
})
|
||||
} else {
|
||||
ctx.Build(pctx, android.BuildParams{
|
||||
Rule: apexRule,
|
||||
|
Reference in New Issue
Block a user