Merge "Move creation of deapexer modules to separate mutator" am: b60def6def
am: c9b695b6d7
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1697057 Change-Id: I649625c6f7ebf4e44ef45510fef03ee156106d15
This commit is contained in:
@@ -50,10 +50,15 @@ func registerApexBuildComponents(ctx android.RegistrationContext) {
|
|||||||
ctx.RegisterModuleType("override_apex", overrideApexFactory)
|
ctx.RegisterModuleType("override_apex", overrideApexFactory)
|
||||||
ctx.RegisterModuleType("apex_set", apexSetFactory)
|
ctx.RegisterModuleType("apex_set", apexSetFactory)
|
||||||
|
|
||||||
|
ctx.PreArchMutators(registerPreArchMutators)
|
||||||
ctx.PreDepsMutators(RegisterPreDepsMutators)
|
ctx.PreDepsMutators(RegisterPreDepsMutators)
|
||||||
ctx.PostDepsMutators(RegisterPostDepsMutators)
|
ctx.PostDepsMutators(RegisterPostDepsMutators)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
|
||||||
|
ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
|
||||||
|
}
|
||||||
|
|
||||||
func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
|
func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
|
||||||
ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
|
ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
|
||||||
ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
|
ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
|
||||||
|
159
apex/prebuilt.go
159
apex/prebuilt.go
@@ -94,6 +94,26 @@ func (p *prebuiltCommon) checkForceDisable(ctx android.ModuleContext) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prebuiltApexModuleCreator defines the methods that need to be implemented by prebuilt_apex and
|
||||||
|
// apex_set in order to create the modules needed to provide access to the prebuilt .apex file.
|
||||||
|
type prebuiltApexModuleCreator interface {
|
||||||
|
createPrebuiltApexModules(ctx android.TopDownMutatorContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// prebuiltApexModuleCreatorMutator is the mutator responsible for invoking the
|
||||||
|
// prebuiltApexModuleCreator's createPrebuiltApexModules method.
|
||||||
|
//
|
||||||
|
// It is registered as a pre-arch mutator as it must run after the ComponentDepsMutator because it
|
||||||
|
// will need to access dependencies added by that (exported modules) but must run before the
|
||||||
|
// DepsMutator so that the deapexer module it creates can add dependencies onto itself from the
|
||||||
|
// exported modules.
|
||||||
|
func prebuiltApexModuleCreatorMutator(ctx android.TopDownMutatorContext) {
|
||||||
|
module := ctx.Module()
|
||||||
|
if creator, ok := module.(prebuiltApexModuleCreator); ok {
|
||||||
|
creator.createPrebuiltApexModules(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *prebuiltCommon) deapexerDeps(ctx android.BottomUpMutatorContext) {
|
func (p *prebuiltCommon) deapexerDeps(ctx android.BottomUpMutatorContext) {
|
||||||
// Add dependencies onto the java modules that represent the java libraries that are provided by
|
// Add dependencies onto the java modules that represent the java libraries that are provided by
|
||||||
// and exported from this prebuilt apex.
|
// and exported from this prebuilt apex.
|
||||||
@@ -354,58 +374,16 @@ func (p *Prebuilt) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex.
|
// prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex.
|
||||||
//
|
|
||||||
// If this needs to make files from within a `.apex` file available for use by other Soong modules,
|
|
||||||
// e.g. make dex implementation jars available for java_import modules isted in exported_java_libs,
|
|
||||||
// it does so as follows:
|
|
||||||
//
|
|
||||||
// 1. It creates a `deapexer` module that actually extracts the files from the `.apex` file and
|
|
||||||
// makes them available for use by other modules, at both Soong and ninja levels.
|
|
||||||
//
|
|
||||||
// 2. It adds a dependency onto those modules and creates an apex specific variant similar to what
|
|
||||||
// an `apex` module does. That ensures that code which looks for specific apex variant, e.g.
|
|
||||||
// dexpreopt, will work the same way from source and prebuilt.
|
|
||||||
//
|
|
||||||
// 3. The `deapexer` module adds a dependency from the modules that require the exported files onto
|
|
||||||
// itself so that they can retrieve the file paths to those files.
|
|
||||||
//
|
|
||||||
// It also creates a child module `selector` that is responsible for selecting the appropriate
|
|
||||||
// input apex for both the prebuilt_apex and the deapexer. That is needed for a couple of reasons:
|
|
||||||
// 1. To dedup the selection logic so it only runs in one module.
|
|
||||||
// 2. To allow the deapexer to be wired up to a different source for the input apex, e.g. an
|
|
||||||
// `apex_set`.
|
|
||||||
//
|
|
||||||
// prebuilt_apex
|
|
||||||
// / | \
|
|
||||||
// / | \
|
|
||||||
// V | V
|
|
||||||
// selector <--- deapexer <--- exported java lib
|
|
||||||
//
|
|
||||||
func PrebuiltFactory() android.Module {
|
func PrebuiltFactory() android.Module {
|
||||||
module := &Prebuilt{}
|
module := &Prebuilt{}
|
||||||
module.AddProperties(&module.properties, &module.deapexerProperties, &module.selectedApexProperties)
|
module.AddProperties(&module.properties, &module.deapexerProperties, &module.selectedApexProperties)
|
||||||
android.InitSingleSourcePrebuiltModule(module, &module.selectedApexProperties, "Selected_apex")
|
android.InitSingleSourcePrebuiltModule(module, &module.selectedApexProperties, "Selected_apex")
|
||||||
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
||||||
|
|
||||||
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
|
|
||||||
baseModuleName := module.BaseModuleName()
|
|
||||||
|
|
||||||
apexSelectorModuleName := apexSelectorModuleName(baseModuleName)
|
|
||||||
createApexSelectorModule(ctx, apexSelectorModuleName, &module.properties.ApexFileProperties)
|
|
||||||
|
|
||||||
apexFileSource := ":" + apexSelectorModuleName
|
|
||||||
if len(module.deapexerProperties.Exported_java_libs) != 0 {
|
|
||||||
createDeapexerModule(ctx, deapexerModuleName(baseModuleName), apexFileSource, &module.deapexerProperties)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a source reference to retrieve the selected apex from the selector module.
|
|
||||||
module.selectedApexProperties.Selected_apex = proptools.StringPtr(apexFileSource)
|
|
||||||
})
|
|
||||||
|
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
func createApexSelectorModule(ctx android.LoadHookContext, name string, apexFileProperties *ApexFileProperties) {
|
func createApexSelectorModule(ctx android.TopDownMutatorContext, name string, apexFileProperties *ApexFileProperties) {
|
||||||
props := struct {
|
props := struct {
|
||||||
Name *string
|
Name *string
|
||||||
}{
|
}{
|
||||||
@@ -418,7 +396,17 @@ func createApexSelectorModule(ctx android.LoadHookContext, name string, apexFile
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDeapexerModule(ctx android.LoadHookContext, deapexerName string, apexFileSource string, deapexerProperties *DeapexerProperties) {
|
// createDeapexerModuleIfNeeded will create a deapexer module if it is needed.
|
||||||
|
//
|
||||||
|
// A deapexer module is only needed when the prebuilt apex specifies an `exported_java_libs`
|
||||||
|
// property as that indicates that the listed modules need access to files from within the prebuilt
|
||||||
|
// .apex file.
|
||||||
|
func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string, deapexerProperties *DeapexerProperties) {
|
||||||
|
// Only create the deapexer module if it is needed.
|
||||||
|
if len(deapexerProperties.Exported_java_libs) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
props := struct {
|
props := struct {
|
||||||
Name *string
|
Name *string
|
||||||
Selected_apex *string
|
Selected_apex *string
|
||||||
@@ -479,6 +467,50 @@ var (
|
|||||||
exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"}
|
exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ prebuiltApexModuleCreator = (*Prebuilt)(nil)
|
||||||
|
|
||||||
|
// createPrebuiltApexModules creates modules necessary to export files from the prebuilt apex to the
|
||||||
|
// build.
|
||||||
|
//
|
||||||
|
// If this needs to make files from within a `.apex` file available for use by other Soong modules,
|
||||||
|
// e.g. make dex implementation jars available for java_import modules listed in exported_java_libs,
|
||||||
|
// it does so as follows:
|
||||||
|
//
|
||||||
|
// 1. It creates a `deapexer` module that actually extracts the files from the `.apex` file and
|
||||||
|
// makes them available for use by other modules, at both Soong and ninja levels.
|
||||||
|
//
|
||||||
|
// 2. It adds a dependency onto those modules and creates an apex specific variant similar to what
|
||||||
|
// an `apex` module does. That ensures that code which looks for specific apex variant, e.g.
|
||||||
|
// dexpreopt, will work the same way from source and prebuilt.
|
||||||
|
//
|
||||||
|
// 3. The `deapexer` module adds a dependency from the modules that require the exported files onto
|
||||||
|
// itself so that they can retrieve the file paths to those files.
|
||||||
|
//
|
||||||
|
// It also creates a child module `selector` that is responsible for selecting the appropriate
|
||||||
|
// input apex for both the prebuilt_apex and the deapexer. That is needed for a couple of reasons:
|
||||||
|
// 1. To dedup the selection logic so it only runs in one module.
|
||||||
|
// 2. To allow the deapexer to be wired up to a different source for the input apex, e.g. an
|
||||||
|
// `apex_set`.
|
||||||
|
//
|
||||||
|
// prebuilt_apex
|
||||||
|
// / | \
|
||||||
|
// / | \
|
||||||
|
// V V V
|
||||||
|
// selector <--- deapexer <--- exported java lib
|
||||||
|
//
|
||||||
|
func (p *Prebuilt) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
|
||||||
|
baseModuleName := p.BaseModuleName()
|
||||||
|
|
||||||
|
apexSelectorModuleName := apexSelectorModuleName(baseModuleName)
|
||||||
|
createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties)
|
||||||
|
|
||||||
|
apexFileSource := ":" + apexSelectorModuleName
|
||||||
|
createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource, &p.deapexerProperties)
|
||||||
|
|
||||||
|
// Add a source reference to retrieve the selected apex from the selector module.
|
||||||
|
p.selectedApexProperties.Selected_apex = proptools.StringPtr(apexFileSource)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) {
|
func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
p.deapexerDeps(ctx)
|
p.deapexerDeps(ctx)
|
||||||
}
|
}
|
||||||
@@ -698,25 +730,10 @@ func apexSetFactory() android.Module {
|
|||||||
android.InitSingleSourcePrebuiltModule(module, &module.selectedApexProperties, "Selected_apex")
|
android.InitSingleSourcePrebuiltModule(module, &module.selectedApexProperties, "Selected_apex")
|
||||||
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
||||||
|
|
||||||
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
|
|
||||||
baseModuleName := module.BaseModuleName()
|
|
||||||
|
|
||||||
apexExtractorModuleName := apexExtractorModuleName(baseModuleName)
|
|
||||||
createApexExtractorModule(ctx, apexExtractorModuleName, &module.properties.ApexExtractorProperties)
|
|
||||||
|
|
||||||
apexFileSource := ":" + apexExtractorModuleName
|
|
||||||
if len(module.deapexerProperties.Exported_java_libs) != 0 {
|
|
||||||
createDeapexerModule(ctx, deapexerModuleName(baseModuleName), apexFileSource, &module.deapexerProperties)
|
|
||||||
}
|
|
||||||
|
|
||||||
// After passing the arch specific src properties to the creating the apex selector module
|
|
||||||
module.selectedApexProperties.Selected_apex = proptools.StringPtr(apexFileSource)
|
|
||||||
})
|
|
||||||
|
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
func createApexExtractorModule(ctx android.LoadHookContext, name string, apexExtractorProperties *ApexExtractorProperties) {
|
func createApexExtractorModule(ctx android.TopDownMutatorContext, name string, apexExtractorProperties *ApexExtractorProperties) {
|
||||||
props := struct {
|
props := struct {
|
||||||
Name *string
|
Name *string
|
||||||
}{
|
}{
|
||||||
@@ -733,6 +750,28 @@ func apexExtractorModuleName(baseModuleName string) string {
|
|||||||
return baseModuleName + ".apex.extractor"
|
return baseModuleName + ".apex.extractor"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ prebuiltApexModuleCreator = (*ApexSet)(nil)
|
||||||
|
|
||||||
|
// createPrebuiltApexModules creates modules necessary to export files from the apex set to other
|
||||||
|
// modules.
|
||||||
|
//
|
||||||
|
// This effectively does for apex_set what Prebuilt.createPrebuiltApexModules does for a
|
||||||
|
// prebuilt_apex except that instead of creating a selector module which selects one .apex file
|
||||||
|
// from those provided this creates an extractor module which extracts the appropriate .apex file
|
||||||
|
// from the zip file containing them.
|
||||||
|
func (a *ApexSet) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
|
||||||
|
baseModuleName := a.BaseModuleName()
|
||||||
|
|
||||||
|
apexExtractorModuleName := apexExtractorModuleName(baseModuleName)
|
||||||
|
createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties)
|
||||||
|
|
||||||
|
apexFileSource := ":" + apexExtractorModuleName
|
||||||
|
createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource, &a.deapexerProperties)
|
||||||
|
|
||||||
|
// After passing the arch specific src properties to the creating the apex selector module
|
||||||
|
a.selectedApexProperties.Selected_apex = proptools.StringPtr(apexFileSource)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *ApexSet) DepsMutator(ctx android.BottomUpMutatorContext) {
|
func (a *ApexSet) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
a.deapexerDeps(ctx)
|
a.deapexerDeps(ctx)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user