Before this cl, blueprint expressions were evaluated as they were
parsed. We want to add a feature to select statements where we can
bind the value of soome value from soong into a blueprint variable,
that then can be used like a regular variable in the .bp file. This
means that select statements need to hold whole unevalated expression
trees, and have the ability to evaluate them later on when the value
of the bound variable is known.
This cl doesn't implement the new select syntax, but it does split
blueprint's parsing and evaluating into two separate stages. We also
store expressions in selects and evaluate them when the select is
resolved.
I didn't do extensive performance evaluation, but a simple comparison
of the time of `touch Android.bp && m nothing` before/after this cl
showed a 1 second speedup. (That was probably just noise)
Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: I12f373719991afeb4aec76517153f32229d97ff2
ReplaceDependencies[If] currently replaces dependencies on a given
module with the current module. It expects to find a variant of the
given module that has the exact same variations as the current module.
That was sometimes handled via aliases, but TransitionMutators don't
support aliases, they use IncomingTransition to rewrite the variation
instead.
In all current usages of ReplaceDependencies[If], the given module
is also a direct dependency of the current module. Instead of looking
for the exact same variations, look for the variant that is a dependency
of the current module.
Bug: 319288033
Test: all soong tests pass
Flag: NONE
Change-Id: I3e33111322040b187f6e951554366ccdcaf1bc11
Adding a dependency on a module that has already had a TransitionMutator
run on it may require adjusting the variation name based on the results
of IncomingTranstion. Store the variants that existed before the
TransitionMutator ran, find one that is a subset of the requested
variant, and call TranstionMutator.IncomingTransition to update the
value.
Bug: 319288033
Test: TestPostTransitionDeps
Change-Id: I690357f9792401a3edbc5ae9fdcb666495954fbc
* changes:
Store mutator in mutatorContext instead of name
Explicitly delete old logicModule entries from Context.moduleInfo
Keep logicModule for obsolete variants
Add Provider to transition contexts
Cache outgoing transitions
Use maps and slices packages
TransitionMutators will need access to the original *mutatorInfo,
store it in mutatorContext instead of the name, and update all
accesses to the name to go through the *mutatorInfo.
Bug: 319288033
Test: go test ./...
Change-Id: I4bb1a17f44e55b23dd70708c9a5fde2ae80ce154
Allow TransitionMutator OutgoingTransition and IncomingTransition
methods to access Providers from the current and dependency module
respectively.
Bug: 319288033
Test: none
Change-Id: If16ee7980ee0b8f4abaf3c112738fca3f13ab61c
TransitionMutators were calling OutgoingTransition and IncomingTransition
twice, once to determine all the necessary variations for each module,
and then again when creating the variations to resolve dependencies.
Store the final variation needed for each dependency during the first
computation, and use it to resolve the dependency variation in the second
pass.
Bug: 319288033
Test: all soong tests
Change-Id: I2e42c0d69efbfcff915267c484c18554b857e0b6
...and pass property name to ConfigurableEvaluator.
When trying to convert Enabled to a configurable property, I enountered
a bunch of different context types that all had different error methods.
OtherModulePropertyErrorf is an error method that can be implemented
by all contexts.
Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: I38b2a545c0ee8d23281cd88bc397f79f39835bc4
Now that nothing calls *Context.*Provider directly, make the blueprint
methods return a nil any interface instead of the zero value that was
constructed via reflection. The type-safe wrappers will return a
zero value that can be constructed without any reflection or copying.
Bug: 316410648
Test: provider_test.go
Change-Id: I0abde5bacab9964a83f03c1644b51295a6c34d0b
Using generics for the providers API allows a type to be associated
with a ProviderKey, resulting in a type-safe API without that doesn't
require runtime type assertions by every caller.
Unfortunately, Go does not allow generic types in methods, only in
functions [1]. This prevents a type-safe API on ModuleContext, and
requires moving the API to be functions that take a ModuleContext as
a parameter.
[1] https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#no-parameterized-methods)
Bug: 316410648
Test: provider_test.go
Change-Id: Ide91de9f2a2a7d075b05e287c7cc86b395db0edb
These are more limited than bottom-up or top-down mutators but in
exchange have some pleasant properties:
- "variant not found" errors are impossible
- The logic is pleasantly split into multiple, mostly orthogonal
parts
- Theoretically, if every mutator is refactored like this, they
make it possible to partially cache the module graph
- Are quite close to a "configuration transition" in Bazel.
Bug: 231370928
Test: Presubmits.
Change-Id: Idcdb66b5ea75c0d2838f527aaa988df3b12553d8
Modules created by a LoadHookContext do not currently set a module type
when creating new modules, but it would make analysis of the
module-graph.json much easier if this module type information was available.
Bug: 174879786
Test: m json-module-graph && check that module which previously had a
blank module type now have the field populated
Change-Id: Ie2fa4244113b6254e6678da9a663d883e2a48a41
If more than one loadhooks exist, calls to CreateModule will make an
error because the contexts object isn't reset and the same modules are
added more than once. This fixes the bug by initializing contexts object
every time.
Bug: 213297238
Test: manual
Change-Id: I545c1592c3217b764968a8937c962e9d58a85291
This function should only be used in corner-cases where it is not
possible to retrieve the module by traversing a dependency graph; there
are no guarantees about which variant is returned, and the function will
eagerly panic if something is amiss (the name doesn't belong to a module
but to an alias instead).
This function is particularly useful for bp2build, which does not use
real variants when evaluating the blueprint graph.
Test: With soong change, USE_BAZEL_ANALYSIS=1 m libc
Change-Id: I72b8335b642ed2d05e0a38e448cd380acc8d65b0
This is the logical extension corresponding to
AddFarVariationDependencies in the same way
OtherModuleDependencyVariantExists corresponds to
AddVariationDependencies.
Test: m nothing
Bug: 188398129
Change-Id: I5517bfd6be5e2c58432c2902dfd1ca7668c76598
Propagate the ninja file deps from a LoadHook to the build.ninja.d
file.
Bug: 188547846
Test: next CL
Change-Id: If8176474b5094ee40d07df12f5da79a906ce7290
According to the documentation, Add[Variation]Dependencies should be
returning a list the same length as the input list. A non-parallel
mutator doesn't support pausing to wait for new dependencies to finish
the current mutator pass, so it can't return the new dependencies. Make
it return a list of nil instead to match the contract.
Bug: 186539038
Test: TestAddVariationDependencies
Change-Id: I07d0ac1f3024dcb7c94a2518910a68b61cd731e2
In the coordination between #316 and #318 the calls to mctx.pause()
were forgotten, causing dependencies returned by the Add*Dependency
calls to be in an undefined state. Add the missing calls to
mctx.pause().
Change-Id: I648ad269449777363801785059b13b866424d4b5
In particular the formatting of dependencies with variants which lacked
braces that caused them to float together with the dependency names.
Also add some context to the ReplaceDependenciesIf panic message.
Test: m
Change-Id: Ibd03690317ca53f3ecbdd95033404d89d849b4dd
Providers are a new concept for Blueprint, based on providers in Bazel:
https://docs.bazel.build/versions/master/skylark/rules.html#providers
Providers aim to simplify the interaction between modules by replacing
type asserting to arbitrary interfaces with requesting optional data
objects from modules. This will also move Blueprint closer to supporting
incremental analysis by serializing the providers and only rerunning
the analysis phase on modules whose inputs have changed.
Change-Id: I39f5f78b372412a7dbf151ceccb3f917f6c874bf
The motivaion for this change is to allow writing code that uses the
newly added dependency module in the same mutator pass, for example to
add more dependencies. Like this:
for _, m := range ctx.AddVariationDependencies(nil, tag, deps...) {
if someModuleProperty(m); ok {
ctx.AddVariationDependencies(nil, tag, otherDep)
}
}
Note that there is no guarantee that the returned module has already
been processed by the current mutator.
The patch does not add runtime overhead on findng dependency modules,
as this has already been done previously.
Test: go test
Pass a channel to visitor functions called by parallelVisit that
allows them to pause the current visitor until a given visitor
has finished. This allows parallelVisit to work on a dependency
graph while it is being mutated.
Test: Test_parallelVisit
Change-Id: Id8b1542c22ac9914439310e31d992ae0d7318d69
AddFarVariationDependencies takes the first matching variant. To
maintain sensible behavior on a module with aliases, the ordering
of aliases and module variants needs to be maintained so that
AddFarVariationDependencies can find an earlier matching alias
instead of a more specific variant.
Test: go test .
Change-Id: I78f4e96edd98159f3a62d94e240e5d652667bec4
Add tests for findVariant behavior that provides the matching
behaviors of AddVariationDependencies, AddFarVariationDependencies,
etc.
Test: Test_findVariant
Change-Id: I3494d57179c8b3d62f7d32e5a1b43c9b9672c2df
Move the VisitAllModuleVariants, PrimaryModule and FinalModule methods to
baseModuleContext so they can be used by mutators.
Test: m checkbuild
Change-Id: I1827ce2fc75f017460a7f6a53b1dab6a81109435
CreateAliasVariation creates a new variation for the current mutator
that is an alias to a variation that was created with CreateVarations
by the same mutator. It is similar to AliasVariation, except that
AliasVariation creates an alias from the pre-mutated variant to one
of the new variations, while CreateAliasVariation creates an alias
from a new post-mutated variation to one of the new variations.
Bug: 164216768
Test: TestCreateAliasVariation
Change-Id: I8847b8d6fc1d3248abc910b2fe2399881f9bdaee
Adds a CheckBlueprintSyntax(...) method to check the syntax of a
Blueprint file.
Changes processModuleDef and newModule from being method on *Context to
being standalone functions. That ensures that CheckBlueprintSyntax(...)
does not need to take a context and so there is no chance that it can
change its state.
Add RegisterScopedModuleType to LoadHookContext that registers
a module type factory that will be visible for the remainder of
the file. Also add ModuleFactories that returns the globally
register module factories.
Test: all blueprint tests
Change-Id: If646a73befe3b8e45c4b0984531c6a39ddc8d066
Move LoadHooks from Blueprint and run them during ParseBlueprintsFiles.
This will allow them to add scoped module types that are visible to the
rest of the Blueprints file. Requires passing the config object to
ParseBlueprintsFiles.
Test: all blueprint tests
Change-Id: Ia2a2c9a0223d5458bfd48bd22ebed0fdbd0156c6
Adding a dependency on a module with variants can be problematic
if the code adding the dependency is not aware of every mutator
that has created variants. Add an AliasVariations to
BottomUpMutatorContext, which allows a mutator to alias the
original variant of a module to one of the new variants of the
module, which will allow future dependencies to be added using
the original list of variations. The aliases are transient,
and only exist until the next mutator that calls CreateVariations
when visiting the module without also calling AliasVariations.
Test: TestAlises
Change-Id: Ieaa04b5a6bdcb5a1ff5114b1e03460de795d4479
Modules are created with a nil variantionMap, which avoids allocating
an empty map if the module will never be split.
Context.addVariationDependencies constructs a variationMap to
compare against the variationMap of each variant, but constructed
an empty variationMap if no variations were specified. A nil
map is not the same as an empty map, so consistently use a nil
map and create it when populating the first entry.
Change-Id: I48b604659f9cdb23326b504a093cdfe5a3eb4f68