123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839 |
- // Copyright 2016 Google Inc. All rights reserved.
- //
- // 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 etc
- // This file implements module types that install prebuilt artifacts.
- //
- // There exist two classes of prebuilt modules in the Android tree. The first class are the ones
- // based on `android.Prebuilt`, such as `cc_prebuilt_library` and `java_import`. This kind of
- // modules may exist both as prebuilts and source at the same time, though only one would be
- // installed and the other would be marked disabled. The `prebuilt_postdeps` mutator would select
- // the actual modules to be installed. More details in android/prebuilt.go.
- //
- // The second class is described in this file. Unlike `android.Prebuilt` based module types,
- // `prebuilt_etc` exist only as prebuilts and cannot have a same-named source module counterpart.
- // This makes the logic of `prebuilt_etc` to be much simpler as they don't need to go through the
- // various `prebuilt_*` mutators.
- import (
- "encoding/json"
- "fmt"
- "path/filepath"
- "reflect"
- "strings"
- "github.com/google/blueprint/proptools"
- "android/soong/android"
- "android/soong/bazel"
- "android/soong/bazel/cquery"
- "android/soong/snapshot"
- )
- var pctx = android.NewPackageContext("android/soong/etc")
- // TODO(jungw): Now that it handles more than the ones in etc/, consider renaming this file.
- func init() {
- pctx.Import("android/soong/android")
- RegisterPrebuiltEtcBuildComponents(android.InitRegistrationContext)
- snapshot.RegisterSnapshotAction(generatePrebuiltSnapshot)
- }
- func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory)
- ctx.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory)
- ctx.RegisterModuleType("prebuilt_etc_cacerts", PrebuiltEtcCaCertsFactory)
- ctx.RegisterModuleType("prebuilt_root", PrebuiltRootFactory)
- ctx.RegisterModuleType("prebuilt_root_host", PrebuiltRootHostFactory)
- ctx.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
- ctx.RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory)
- ctx.RegisterModuleType("prebuilt_font", PrebuiltFontFactory)
- ctx.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory)
- ctx.RegisterModuleType("prebuilt_dsp", PrebuiltDSPFactory)
- ctx.RegisterModuleType("prebuilt_rfsa", PrebuiltRFSAFactory)
- ctx.RegisterModuleType("prebuilt_defaults", defaultsFactory)
- }
- var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterPrebuiltEtcBuildComponents)
- type prebuiltEtcProperties struct {
- // Source file of this prebuilt. Can reference a genrule type module with the ":module" syntax.
- Src *string `android:"path,arch_variant"`
- // Optional name for the installed file. If unspecified, name of the module is used as the file
- // name.
- Filename *string `android:"arch_variant"`
- // When set to true, and filename property is not set, the name for the installed file
- // is the same as the file name of the source file.
- Filename_from_src *bool `android:"arch_variant"`
- // Make this module available when building for ramdisk.
- // On device without a dedicated recovery partition, the module is only
- // available after switching root into
- // /first_stage_ramdisk. To expose the module before switching root, install
- // the recovery variant instead.
- Ramdisk_available *bool
- // Make this module available when building for vendor ramdisk.
- // On device without a dedicated recovery partition, the module is only
- // available after switching root into
- // /first_stage_ramdisk. To expose the module before switching root, install
- // the recovery variant instead.
- Vendor_ramdisk_available *bool
- // Make this module available when building for debug ramdisk.
- Debug_ramdisk_available *bool
- // Make this module available when building for recovery.
- Recovery_available *bool
- // Whether this module is directly installable to one of the partitions. Default: true.
- Installable *bool
- // Install symlinks to the installed file.
- Symlinks []string `android:"arch_variant"`
- }
- type prebuiltSubdirProperties struct {
- // Optional subdirectory under which this file is installed into, cannot be specified with
- // relative_install_path, prefer relative_install_path.
- Sub_dir *string `android:"arch_variant"`
- // Optional subdirectory under which this file is installed into, cannot be specified with
- // sub_dir.
- Relative_install_path *string `android:"arch_variant"`
- }
- type PrebuiltEtcModule interface {
- android.Module
- // Returns the base install directory, such as "etc", "usr/share".
- BaseDir() string
- // Returns the sub install directory relative to BaseDir().
- SubDir() string
- // Returns an android.OutputPath to the intermeidate file, which is the renamed prebuilt source
- // file.
- OutputFile() android.OutputPath
- }
- type PrebuiltEtc struct {
- android.ModuleBase
- android.DefaultableModuleBase
- android.BazelModuleBase
- snapshot.VendorSnapshotModuleInterface
- snapshot.RecoverySnapshotModuleInterface
- properties prebuiltEtcProperties
- subdirProperties prebuiltSubdirProperties
- sourceFilePath android.Path
- outputFilePath android.OutputPath
- // The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share.
- installDirBase string
- // The base install location when soc_specific property is set to true, e.g. "firmware" for
- // prebuilt_firmware.
- socInstallDirBase string
- installDirPath android.InstallPath
- additionalDependencies *android.Paths
- }
- type Defaults struct {
- android.ModuleBase
- android.DefaultsModuleBase
- }
- func (p *PrebuiltEtc) inRamdisk() bool {
- return p.ModuleBase.InRamdisk() || p.ModuleBase.InstallInRamdisk()
- }
- func (p *PrebuiltEtc) onlyInRamdisk() bool {
- return p.ModuleBase.InstallInRamdisk()
- }
- func (p *PrebuiltEtc) InstallInRamdisk() bool {
- return p.inRamdisk()
- }
- func (p *PrebuiltEtc) inVendorRamdisk() bool {
- return p.ModuleBase.InVendorRamdisk() || p.ModuleBase.InstallInVendorRamdisk()
- }
- func (p *PrebuiltEtc) onlyInVendorRamdisk() bool {
- return p.ModuleBase.InstallInVendorRamdisk()
- }
- func (p *PrebuiltEtc) InstallInVendorRamdisk() bool {
- return p.inVendorRamdisk()
- }
- func (p *PrebuiltEtc) inDebugRamdisk() bool {
- return p.ModuleBase.InDebugRamdisk() || p.ModuleBase.InstallInDebugRamdisk()
- }
- func (p *PrebuiltEtc) onlyInDebugRamdisk() bool {
- return p.ModuleBase.InstallInDebugRamdisk()
- }
- func (p *PrebuiltEtc) InstallInDebugRamdisk() bool {
- return p.inDebugRamdisk()
- }
- func (p *PrebuiltEtc) InRecovery() bool {
- return p.ModuleBase.InRecovery() || p.ModuleBase.InstallInRecovery()
- }
- func (p *PrebuiltEtc) onlyInRecovery() bool {
- return p.ModuleBase.InstallInRecovery()
- }
- func (p *PrebuiltEtc) InstallInRecovery() bool {
- return p.InRecovery()
- }
- var _ android.ImageInterface = (*PrebuiltEtc)(nil)
- func (p *PrebuiltEtc) ImageMutatorBegin(ctx android.BaseModuleContext) {}
- func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
- return !p.ModuleBase.InstallInRecovery() && !p.ModuleBase.InstallInRamdisk() &&
- !p.ModuleBase.InstallInVendorRamdisk() && !p.ModuleBase.InstallInDebugRamdisk()
- }
- func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return proptools.Bool(p.properties.Ramdisk_available) || p.ModuleBase.InstallInRamdisk()
- }
- func (p *PrebuiltEtc) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return proptools.Bool(p.properties.Vendor_ramdisk_available) || p.ModuleBase.InstallInVendorRamdisk()
- }
- func (p *PrebuiltEtc) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return proptools.Bool(p.properties.Debug_ramdisk_available) || p.ModuleBase.InstallInDebugRamdisk()
- }
- func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
- return proptools.Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery()
- }
- func (p *PrebuiltEtc) ExtraImageVariations(ctx android.BaseModuleContext) []string {
- return nil
- }
- func (p *PrebuiltEtc) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
- }
- func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path {
- return android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
- }
- func (p *PrebuiltEtc) InstallDirPath() android.InstallPath {
- return p.installDirPath
- }
- // This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
- // additional steps (like validating the src) before the file is installed.
- func (p *PrebuiltEtc) SetAdditionalDependencies(paths android.Paths) {
- p.additionalDependencies = &paths
- }
- func (p *PrebuiltEtc) OutputFile() android.OutputPath {
- return p.outputFilePath
- }
- var _ android.OutputFileProducer = (*PrebuiltEtc)(nil)
- func (p *PrebuiltEtc) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case "":
- return android.Paths{p.outputFilePath}, nil
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
- }
- }
- func (p *PrebuiltEtc) SubDir() string {
- if subDir := proptools.String(p.subdirProperties.Sub_dir); subDir != "" {
- return subDir
- }
- return proptools.String(p.subdirProperties.Relative_install_path)
- }
- func (p *PrebuiltEtc) BaseDir() string {
- return p.installDirBase
- }
- func (p *PrebuiltEtc) Installable() bool {
- return p.properties.Installable == nil || proptools.Bool(p.properties.Installable)
- }
- func (p *PrebuiltEtc) InVendor() bool {
- return p.ModuleBase.InstallInVendor()
- }
- func (p *PrebuiltEtc) ExcludeFromVendorSnapshot() bool {
- return false
- }
- func (p *PrebuiltEtc) ExcludeFromRecoverySnapshot() bool {
- return false
- }
- func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- filename := proptools.String(p.properties.Filename)
- filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
- if p.properties.Src != nil {
- p.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
- // Determine the output file basename.
- // If Filename is set, use the name specified by the property.
- // If Filename_from_src is set, use the source file name.
- // Otherwise use the module name.
- if filename != "" {
- if filenameFromSrc {
- ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
- return
- }
- } else if filenameFromSrc {
- filename = p.sourceFilePath.Base()
- } else {
- filename = ctx.ModuleName()
- }
- } else if ctx.Config().AllowMissingDependencies() {
- // If no srcs was set and AllowMissingDependencies is enabled then
- // mark the module as missing dependencies and set a fake source path
- // and file name.
- ctx.AddMissingDependencies([]string{"MISSING_PREBUILT_SRC_FILE"})
- p.sourceFilePath = android.PathForModuleSrc(ctx)
- if filename == "" {
- filename = ctx.ModuleName()
- }
- } else {
- ctx.PropertyErrorf("src", "missing prebuilt source file")
- return
- }
- if strings.Contains(filename, "/") {
- ctx.PropertyErrorf("filename", "filename cannot contain separator '/'")
- return
- }
- // Check that `sub_dir` and `relative_install_path` are not set at the same time.
- if p.subdirProperties.Sub_dir != nil && p.subdirProperties.Relative_install_path != nil {
- ctx.PropertyErrorf("sub_dir", "relative_install_path is set. Cannot set sub_dir")
- }
- // If soc install dir was specified and SOC specific is set, set the installDirPath to the
- // specified socInstallDirBase.
- installBaseDir := p.installDirBase
- if p.SocSpecific() && p.socInstallDirBase != "" {
- installBaseDir = p.socInstallDirBase
- }
- p.installDirPath = android.PathForModuleInstall(ctx, installBaseDir, p.SubDir())
- // Call InstallFile even when uninstallable to make the module included in the package
- ip := installProperties{
- installable: p.Installable(),
- filename: filename,
- sourceFilePath: p.sourceFilePath,
- symlinks: p.properties.Symlinks,
- }
- p.addInstallRules(ctx, ip)
- }
- type installProperties struct {
- installable bool
- filename string
- sourceFilePath android.Path
- symlinks []string
- }
- // utility function to add install rules to the build graph.
- // Reduces code duplication between Soong and Mixed build analysis
- func (p *PrebuiltEtc) addInstallRules(ctx android.ModuleContext, ip installProperties) {
- if !ip.installable {
- p.SkipInstall()
- }
- // Copy the file from src to a location in out/ with the correct `filename`
- // This ensures that outputFilePath has the correct name for others to
- // use, as the source file may have a different name.
- p.outputFilePath = android.PathForModuleOut(ctx, ip.filename).OutputPath
- ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
- Output: p.outputFilePath,
- Input: ip.sourceFilePath,
- })
- installPath := ctx.InstallFile(p.installDirPath, ip.filename, p.outputFilePath)
- for _, sl := range ip.symlinks {
- ctx.InstallSymlink(p.installDirPath, sl, installPath)
- }
- }
- func (p *PrebuiltEtc) AndroidMkEntries() []android.AndroidMkEntries {
- nameSuffix := ""
- if p.inRamdisk() && !p.onlyInRamdisk() {
- nameSuffix = ".ramdisk"
- }
- if p.inVendorRamdisk() && !p.onlyInVendorRamdisk() {
- nameSuffix = ".vendor_ramdisk"
- }
- if p.inDebugRamdisk() && !p.onlyInDebugRamdisk() {
- nameSuffix = ".debug_ramdisk"
- }
- if p.InRecovery() && !p.onlyInRecovery() {
- nameSuffix = ".recovery"
- }
- return []android.AndroidMkEntries{android.AndroidMkEntries{
- Class: "ETC",
- SubName: nameSuffix,
- OutputFile: android.OptionalPathForPath(p.outputFilePath),
- ExtraEntries: []android.AndroidMkExtraEntriesFunc{
- func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_TAGS", "optional")
- entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
- entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
- if len(p.properties.Symlinks) > 0 {
- entries.AddStrings("LOCAL_MODULE_SYMLINKS", p.properties.Symlinks...)
- }
- entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.Installable())
- if p.additionalDependencies != nil {
- entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", p.additionalDependencies.Strings()...)
- }
- },
- },
- }}
- }
- func InitPrebuiltEtcModule(p *PrebuiltEtc, dirBase string) {
- p.installDirBase = dirBase
- p.AddProperties(&p.properties)
- p.AddProperties(&p.subdirProperties)
- }
- func InitPrebuiltRootModule(p *PrebuiltEtc) {
- p.installDirBase = "."
- p.AddProperties(&p.properties)
- }
- // prebuilt_etc is for a prebuilt artifact that is installed in
- // <partition>/etc/<sub_dir> directory.
- func PrebuiltEtcFactory() android.Module {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "etc")
- // This module is device-only
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
- android.InitDefaultableModule(module)
- android.InitBazelModule(module)
- return module
- }
- func defaultsFactory() android.Module {
- return DefaultsFactory()
- }
- func DefaultsFactory(props ...interface{}) android.Module {
- module := &Defaults{}
- module.AddProperties(props...)
- module.AddProperties(
- &prebuiltEtcProperties{},
- &prebuiltSubdirProperties{},
- )
- android.InitDefaultsModule(module)
- return module
- }
- // prebuilt_etc_host is for a host prebuilt artifact that is installed in
- // $(HOST_OUT)/etc/<sub_dir> directory.
- func PrebuiltEtcHostFactory() android.Module {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "etc")
- // This module is host-only
- android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
- android.InitDefaultableModule(module)
- android.InitBazelModule(module)
- return module
- }
- // prebuilt_etc_host is for a host prebuilt artifact that is installed in
- // <partition>/etc/<sub_dir> directory.
- func PrebuiltEtcCaCertsFactory() android.Module {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "cacerts")
- // This module is device-only
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
- android.InitBazelModule(module)
- return module
- }
- // prebuilt_root is for a prebuilt artifact that is installed in
- // <partition>/ directory. Can't have any sub directories.
- func PrebuiltRootFactory() android.Module {
- module := &PrebuiltEtc{}
- InitPrebuiltRootModule(module)
- // This module is device-only
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
- android.InitDefaultableModule(module)
- return module
- }
- // prebuilt_root_host is for a host prebuilt artifact that is installed in $(HOST_OUT)/<sub_dir>
- // directory.
- func PrebuiltRootHostFactory() android.Module {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, ".")
- // This module is host-only
- android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
- android.InitDefaultableModule(module)
- return module
- }
- // prebuilt_usr_share is for a prebuilt artifact that is installed in
- // <partition>/usr/share/<sub_dir> directory.
- func PrebuiltUserShareFactory() android.Module {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "usr/share")
- // This module is device-only
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
- android.InitDefaultableModule(module)
- android.InitBazelModule(module)
- return module
- }
- // prebuild_usr_share_host is for a host prebuilt artifact that is installed in
- // $(HOST_OUT)/usr/share/<sub_dir> directory.
- func PrebuiltUserShareHostFactory() android.Module {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "usr/share")
- // This module is host-only
- android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
- android.InitDefaultableModule(module)
- return module
- }
- // prebuilt_font installs a font in <partition>/fonts directory.
- func PrebuiltFontFactory() android.Module {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "fonts")
- // This module is device-only
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
- android.InitDefaultableModule(module)
- return module
- }
- // prebuilt_firmware installs a firmware file to <partition>/etc/firmware directory for system
- // image.
- // If soc_specific property is set to true, the firmware file is installed to the
- // vendor <partition>/firmware directory for vendor image.
- func PrebuiltFirmwareFactory() android.Module {
- module := &PrebuiltEtc{}
- module.socInstallDirBase = "firmware"
- InitPrebuiltEtcModule(module, "etc/firmware")
- // This module is device-only
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
- android.InitDefaultableModule(module)
- return module
- }
- // prebuilt_dsp installs a DSP related file to <partition>/etc/dsp directory for system image.
- // If soc_specific property is set to true, the DSP related file is installed to the
- // vendor <partition>/dsp directory for vendor image.
- func PrebuiltDSPFactory() android.Module {
- module := &PrebuiltEtc{}
- module.socInstallDirBase = "dsp"
- InitPrebuiltEtcModule(module, "etc/dsp")
- // This module is device-only
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
- android.InitDefaultableModule(module)
- return module
- }
- // prebuilt_rfsa installs a firmware file that will be available through Qualcomm's RFSA
- // to the <partition>/lib/rfsa directory.
- func PrebuiltRFSAFactory() android.Module {
- module := &PrebuiltEtc{}
- // Ideally these would go in /vendor/dsp, but the /vendor/lib/rfsa paths are hardcoded in too
- // many places outside of the application processor. They could be moved to /vendor/dsp once
- // that is cleaned up.
- InitPrebuiltEtcModule(module, "lib/rfsa")
- // This module is device-only
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
- android.InitDefaultableModule(module)
- return module
- }
- // Copy file into the snapshot
- func copyFile(ctx android.SingletonContext, path android.Path, out string, fake bool) android.OutputPath {
- if fake {
- // Create empty file instead for the fake snapshot
- return snapshot.WriteStringToFileRule(ctx, "", out)
- } else {
- return snapshot.CopyFileRule(pctx, ctx, path, out)
- }
- }
- // Check if the module is target of the snapshot
- func isSnapshotAware(ctx android.SingletonContext, m *PrebuiltEtc, image snapshot.SnapshotImage) bool {
- if !m.Enabled() {
- return false
- }
- // Skip if the module is not included in the image
- if !image.InImage(m)() {
- return false
- }
- // When android/prebuilt.go selects between source and prebuilt, it sets
- // HideFromMake on the other one to avoid duplicate install rules in make.
- if m.IsHideFromMake() {
- return false
- }
- // There are some prebuilt_etc module with multiple definition of same name.
- // Check if the target would be included from the build
- if !m.ExportedToMake() {
- return false
- }
- // Skip if the module is in the predefined path list to skip
- if image.IsProprietaryPath(ctx.ModuleDir(m), ctx.DeviceConfig()) {
- return false
- }
- // Skip if the module should be excluded
- if image.ExcludeFromSnapshot(m) || image.ExcludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) {
- return false
- }
- // Skip from other exceptional cases
- if m.Target().Os.Class != android.Device {
- return false
- }
- if m.Target().NativeBridge == android.NativeBridgeEnabled {
- return false
- }
- return true
- }
- func generatePrebuiltSnapshot(s snapshot.SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) snapshot.SnapshotPaths {
- /*
- Snapshot zipped artifacts directory structure for etc modules:
- {SNAPSHOT_ARCH}/
- arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
- etc/
- (prebuilt etc files)
- arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
- etc/
- (prebuilt etc files)
- NOTICE_FILES/
- (notice files)
- */
- var snapshotOutputs android.Paths
- var snapshotNotices android.Paths
- installedNotices := make(map[string]bool)
- ctx.VisitAllModules(func(module android.Module) {
- m, ok := module.(*PrebuiltEtc)
- if !ok {
- return
- }
- if !isSnapshotAware(ctx, m, s.Image) {
- return
- }
- targetArch := "arch-" + m.Target().Arch.ArchType.String()
- snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "etc", m.BaseModuleName())
- snapshotOutputs = append(snapshotOutputs, copyFile(ctx, m.OutputFile(), snapshotLibOut, s.Fake))
- prop := snapshot.SnapshotJsonFlags{}
- propOut := snapshotLibOut + ".json"
- prop.InitBaseSnapshotProps(m)
- prop.RelativeInstallPath = m.SubDir()
- if m.properties.Filename != nil {
- prop.Filename = *m.properties.Filename
- }
- j, err := json.Marshal(prop)
- if err != nil {
- ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
- return
- }
- snapshotOutputs = append(snapshotOutputs, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
- for _, notice := range m.EffectiveLicenseFiles() {
- if _, ok := installedNotices[notice.String()]; !ok {
- installedNotices[notice.String()] = true
- snapshotNotices = append(snapshotNotices, notice)
- }
- }
- })
- return snapshot.SnapshotPaths{OutputFiles: snapshotOutputs, NoticeFiles: snapshotNotices}
- }
- // For Bazel / bp2build
- type bazelPrebuiltFileAttributes struct {
- Src bazel.LabelAttribute
- Filename bazel.LabelAttribute
- Dir string
- Installable bazel.BoolAttribute
- Filename_from_src bazel.BoolAttribute
- }
- // Bp2buildHelper returns a bazelPrebuiltFileAttributes used for the conversion
- // of prebuilt_* modules. bazelPrebuiltFileAttributes has the common attributes
- // used by both prebuilt_etc_xml and other prebuilt_* moodules
- func (module *PrebuiltEtc) Bp2buildHelper(ctx android.TopDownMutatorContext) *bazelPrebuiltFileAttributes {
- var src bazel.LabelAttribute
- for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltEtcProperties{}) {
- for config, p := range configToProps {
- props, ok := p.(*prebuiltEtcProperties)
- if !ok {
- continue
- }
- if props.Src != nil {
- label := android.BazelLabelForModuleSrcSingle(ctx, *props.Src)
- src.SetSelectValue(axis, config, label)
- }
- }
- for propName, productConfigProps := range android.ProductVariableProperties(ctx, ctx.Module()) {
- for configProp, propVal := range productConfigProps {
- if propName == "Src" {
- props, ok := propVal.(*string)
- if !ok {
- ctx.PropertyErrorf(" Expected Property to have type string, but was %s\n", reflect.TypeOf(propVal).String())
- continue
- }
- if props != nil {
- label := android.BazelLabelForModuleSrcSingle(ctx, *props)
- src.SetSelectValue(configProp.ConfigurationAxis(), configProp.SelectKey(), label)
- }
- }
- }
- }
- }
- var filename string
- var filenameFromSrc bool
- moduleProps := module.properties
- if moduleProps.Filename != nil && *moduleProps.Filename != "" {
- filename = *moduleProps.Filename
- } else if moduleProps.Filename_from_src != nil && *moduleProps.Filename_from_src {
- if moduleProps.Src != nil {
- filename = *moduleProps.Src
- }
- filenameFromSrc = true
- } else {
- filename = ctx.ModuleName()
- }
- var dir = module.installDirBase
- if subDir := module.subdirProperties.Sub_dir; subDir != nil {
- dir = dir + "/" + *subDir
- }
- var installable bazel.BoolAttribute
- if install := module.properties.Installable; install != nil {
- installable.Value = install
- }
- attrs := &bazelPrebuiltFileAttributes{
- Src: src,
- Dir: dir,
- Installable: installable,
- }
- if filename != "" {
- attrs.Filename = bazel.LabelAttribute{Value: &bazel.Label{Label: filename}}
- } else if filenameFromSrc {
- attrs.Filename_from_src = bazel.BoolAttribute{Value: moduleProps.Filename_from_src}
- }
- return attrs
- }
- // ConvertWithBp2build performs bp2build conversion of PrebuiltEtc
- // prebuilt_* modules (except prebuilt_etc_xml) are PrebuiltEtc,
- // which we treat as *PrebuiltFile*
- func (module *PrebuiltEtc) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
- var dir = module.installDirBase
- // prebuilt_file supports only `etc` or `usr/share`
- if !(dir == "etc" || dir == "usr/share") {
- return
- }
- attrs := module.Bp2buildHelper(ctx)
- props := bazel.BazelTargetModuleProperties{
- Rule_class: "prebuilt_file",
- Bzl_load_location: "//build/bazel/rules:prebuilt_file.bzl",
- }
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
- }
- var _ android.MixedBuildBuildable = (*PrebuiltEtc)(nil)
- func (pe *PrebuiltEtc) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
- return true
- }
- func (pe *PrebuiltEtc) QueueBazelCall(ctx android.BaseModuleContext) {
- ctx.Config().BazelContext.QueueBazelRequest(
- pe.GetBazelLabel(ctx, pe),
- cquery.GetPrebuiltFileInfo,
- android.GetConfigKey(ctx),
- )
- }
- func (pe *PrebuiltEtc) ProcessBazelQueryResponse(ctx android.ModuleContext) {
- bazelCtx := ctx.Config().BazelContext
- pfi, err := bazelCtx.GetPrebuiltFileInfo(pe.GetBazelLabel(ctx, pe), android.GetConfigKey(ctx))
- if err != nil {
- ctx.ModuleErrorf(err.Error())
- return
- }
- // Set properties for androidmk
- pe.installDirPath = android.PathForModuleInstall(ctx, pfi.Dir)
- // Installation rules
- ip := installProperties{
- installable: pfi.Installable,
- filename: pfi.Filename,
- sourceFilePath: android.PathForSource(ctx, pfi.Src),
- // symlinks: pe.properties.Symlinks, // TODO: b/207489266 - Fully support all properties in prebuilt_file
- }
- pe.addInstallRules(ctx, ip)
- }
|