1// Copyright 2016 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package etc 16 17// This file implements module types that install prebuilt artifacts. 18// 19// There exist two classes of prebuilt modules in the Android tree. The first class are the ones 20// based on `android.Prebuilt`, such as `cc_prebuilt_library` and `java_import`. This kind of 21// modules may exist both as prebuilts and source at the same time, though only one would be 22// installed and the other would be marked disabled. The `prebuilt_postdeps` mutator would select 23// the actual modules to be installed. More details in android/prebuilt.go. 24// 25// The second class is described in this file. Unlike `android.Prebuilt` based module types, 26// `prebuilt_etc` exist only as prebuilts and cannot have a same-named source module counterpart. 27// This makes the logic of `prebuilt_etc` to be much simpler as they don't need to go through the 28// various `prebuilt_*` mutators. 29 30import ( 31 "fmt" 32 "strings" 33 34 "github.com/google/blueprint/proptools" 35 36 "android/soong/android" 37) 38 39var pctx = android.NewPackageContext("android/soong/etc") 40 41// TODO(jungw): Now that it handles more than the ones in etc/, consider renaming this file. 42 43func init() { 44 pctx.Import("android/soong/android") 45 RegisterPrebuiltEtcBuildComponents(android.InitRegistrationContext) 46} 47 48func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) { 49 ctx.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory) 50 ctx.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory) 51 ctx.RegisterModuleType("prebuilt_root", PrebuiltRootFactory) 52 ctx.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory) 53 ctx.RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory) 54 ctx.RegisterModuleType("prebuilt_font", PrebuiltFontFactory) 55 ctx.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory) 56 ctx.RegisterModuleType("prebuilt_dsp", PrebuiltDSPFactory) 57 ctx.RegisterModuleType("prebuilt_rfsa", PrebuiltRFSAFactory) 58 59 ctx.RegisterModuleType("prebuilt_defaults", defaultsFactory) 60} 61 62var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterPrebuiltEtcBuildComponents) 63 64type prebuiltEtcProperties struct { 65 // Source file of this prebuilt. Can reference a genrule type module with the ":module" syntax. 66 Src *string `android:"path,arch_variant"` 67 68 // Optional name for the installed file. If unspecified, name of the module is used as the file 69 // name. 70 Filename *string `android:"arch_variant"` 71 72 // When set to true, and filename property is not set, the name for the installed file 73 // is the same as the file name of the source file. 74 Filename_from_src *bool `android:"arch_variant"` 75 76 // Make this module available when building for ramdisk. 77 // On device without a dedicated recovery partition, the module is only 78 // available after switching root into 79 // /first_stage_ramdisk. To expose the module before switching root, install 80 // the recovery variant instead. 81 Ramdisk_available *bool 82 83 // Make this module available when building for vendor ramdisk. 84 // On device without a dedicated recovery partition, the module is only 85 // available after switching root into 86 // /first_stage_ramdisk. To expose the module before switching root, install 87 // the recovery variant instead. 88 Vendor_ramdisk_available *bool 89 90 // Make this module available when building for debug ramdisk. 91 Debug_ramdisk_available *bool 92 93 // Make this module available when building for recovery. 94 Recovery_available *bool 95 96 // Whether this module is directly installable to one of the partitions. Default: true. 97 Installable *bool 98 99 // Install symlinks to the installed file. 100 Symlinks []string `android:"arch_variant"` 101} 102 103type prebuiltSubdirProperties struct { 104 // Optional subdirectory under which this file is installed into, cannot be specified with 105 // relative_install_path, prefer relative_install_path. 106 Sub_dir *string `android:"arch_variant"` 107 108 // Optional subdirectory under which this file is installed into, cannot be specified with 109 // sub_dir. 110 Relative_install_path *string `android:"arch_variant"` 111} 112 113type PrebuiltEtcModule interface { 114 android.Module 115 116 // Returns the base install directory, such as "etc", "usr/share". 117 BaseDir() string 118 119 // Returns the sub install directory relative to BaseDir(). 120 SubDir() string 121 122 // Returns an android.OutputPath to the intermeidate file, which is the renamed prebuilt source 123 // file. 124 OutputFile() android.OutputPath 125} 126 127type PrebuiltEtc struct { 128 android.ModuleBase 129 android.DefaultableModuleBase 130 131 properties prebuiltEtcProperties 132 subdirProperties prebuiltSubdirProperties 133 134 sourceFilePath android.Path 135 outputFilePath android.OutputPath 136 // The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share. 137 installDirBase string 138 // The base install location when soc_specific property is set to true, e.g. "firmware" for 139 // prebuilt_firmware. 140 socInstallDirBase string 141 installDirPath android.InstallPath 142 additionalDependencies *android.Paths 143} 144 145type Defaults struct { 146 android.ModuleBase 147 android.DefaultsModuleBase 148} 149 150func (p *PrebuiltEtc) inRamdisk() bool { 151 return p.ModuleBase.InRamdisk() || p.ModuleBase.InstallInRamdisk() 152} 153 154func (p *PrebuiltEtc) onlyInRamdisk() bool { 155 return p.ModuleBase.InstallInRamdisk() 156} 157 158func (p *PrebuiltEtc) InstallInRamdisk() bool { 159 return p.inRamdisk() 160} 161 162func (p *PrebuiltEtc) inVendorRamdisk() bool { 163 return p.ModuleBase.InVendorRamdisk() || p.ModuleBase.InstallInVendorRamdisk() 164} 165 166func (p *PrebuiltEtc) onlyInVendorRamdisk() bool { 167 return p.ModuleBase.InstallInVendorRamdisk() 168} 169 170func (p *PrebuiltEtc) InstallInVendorRamdisk() bool { 171 return p.inVendorRamdisk() 172} 173 174func (p *PrebuiltEtc) inDebugRamdisk() bool { 175 return p.ModuleBase.InDebugRamdisk() || p.ModuleBase.InstallInDebugRamdisk() 176} 177 178func (p *PrebuiltEtc) onlyInDebugRamdisk() bool { 179 return p.ModuleBase.InstallInDebugRamdisk() 180} 181 182func (p *PrebuiltEtc) InstallInDebugRamdisk() bool { 183 return p.inDebugRamdisk() 184} 185 186func (p *PrebuiltEtc) inRecovery() bool { 187 return p.ModuleBase.InRecovery() || p.ModuleBase.InstallInRecovery() 188} 189 190func (p *PrebuiltEtc) onlyInRecovery() bool { 191 return p.ModuleBase.InstallInRecovery() 192} 193 194func (p *PrebuiltEtc) InstallInRecovery() bool { 195 return p.inRecovery() 196} 197 198var _ android.ImageInterface = (*PrebuiltEtc)(nil) 199 200func (p *PrebuiltEtc) ImageMutatorBegin(ctx android.BaseModuleContext) {} 201 202func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool { 203 return !p.ModuleBase.InstallInRecovery() && !p.ModuleBase.InstallInRamdisk() && 204 !p.ModuleBase.InstallInVendorRamdisk() && !p.ModuleBase.InstallInDebugRamdisk() 205} 206 207func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 208 return proptools.Bool(p.properties.Ramdisk_available) || p.ModuleBase.InstallInRamdisk() 209} 210 211func (p *PrebuiltEtc) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 212 return proptools.Bool(p.properties.Vendor_ramdisk_available) || p.ModuleBase.InstallInVendorRamdisk() 213} 214 215func (p *PrebuiltEtc) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 216 return proptools.Bool(p.properties.Debug_ramdisk_available) || p.ModuleBase.InstallInDebugRamdisk() 217} 218 219func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { 220 return proptools.Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery() 221} 222 223func (p *PrebuiltEtc) ExtraImageVariations(ctx android.BaseModuleContext) []string { 224 return nil 225} 226 227func (p *PrebuiltEtc) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) { 228} 229 230func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path { 231 return android.PathForModuleSrc(ctx, proptools.String(p.properties.Src)) 232} 233 234func (p *PrebuiltEtc) InstallDirPath() android.InstallPath { 235 return p.installDirPath 236} 237 238// This allows other derivative modules (e.g. prebuilt_etc_xml) to perform 239// additional steps (like validating the src) before the file is installed. 240func (p *PrebuiltEtc) SetAdditionalDependencies(paths android.Paths) { 241 p.additionalDependencies = &paths 242} 243 244func (p *PrebuiltEtc) OutputFile() android.OutputPath { 245 return p.outputFilePath 246} 247 248var _ android.OutputFileProducer = (*PrebuiltEtc)(nil) 249 250func (p *PrebuiltEtc) OutputFiles(tag string) (android.Paths, error) { 251 switch tag { 252 case "": 253 return android.Paths{p.outputFilePath}, nil 254 default: 255 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 256 } 257} 258 259func (p *PrebuiltEtc) SubDir() string { 260 if subDir := proptools.String(p.subdirProperties.Sub_dir); subDir != "" { 261 return subDir 262 } 263 return proptools.String(p.subdirProperties.Relative_install_path) 264} 265 266func (p *PrebuiltEtc) BaseDir() string { 267 return p.installDirBase 268} 269 270func (p *PrebuiltEtc) Installable() bool { 271 return p.properties.Installable == nil || proptools.Bool(p.properties.Installable) 272} 273 274func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) { 275 if p.properties.Src == nil { 276 ctx.PropertyErrorf("src", "missing prebuilt source file") 277 return 278 } 279 p.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(p.properties.Src)) 280 281 // Determine the output file basename. 282 // If Filename is set, use the name specified by the property. 283 // If Filename_from_src is set, use the source file name. 284 // Otherwise use the module name. 285 filename := proptools.String(p.properties.Filename) 286 filenameFromSrc := proptools.Bool(p.properties.Filename_from_src) 287 if filename != "" { 288 if filenameFromSrc { 289 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true") 290 return 291 } 292 } else if filenameFromSrc { 293 filename = p.sourceFilePath.Base() 294 } else { 295 filename = ctx.ModuleName() 296 } 297 p.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath 298 299 if strings.Contains(filename, "/") { 300 ctx.PropertyErrorf("filename", "filename cannot contain separator '/'") 301 return 302 } 303 304 // Check that `sub_dir` and `relative_install_path` are not set at the same time. 305 if p.subdirProperties.Sub_dir != nil && p.subdirProperties.Relative_install_path != nil { 306 ctx.PropertyErrorf("sub_dir", "relative_install_path is set. Cannot set sub_dir") 307 } 308 309 // If soc install dir was specified and SOC specific is set, set the installDirPath to the 310 // specified socInstallDirBase. 311 installBaseDir := p.installDirBase 312 if p.SocSpecific() && p.socInstallDirBase != "" { 313 installBaseDir = p.socInstallDirBase 314 } 315 p.installDirPath = android.PathForModuleInstall(ctx, installBaseDir, p.SubDir()) 316 317 // This ensures that outputFilePath has the correct name for others to 318 // use, as the source file may have a different name. 319 ctx.Build(pctx, android.BuildParams{ 320 Rule: android.Cp, 321 Output: p.outputFilePath, 322 Input: p.sourceFilePath, 323 }) 324 325 if !p.Installable() { 326 p.SkipInstall() 327 } 328 329 // Call InstallFile even when uninstallable to make the module included in the package 330 installPath := ctx.InstallFile(p.installDirPath, p.outputFilePath.Base(), p.outputFilePath) 331 for _, sl := range p.properties.Symlinks { 332 ctx.InstallSymlink(p.installDirPath, sl, installPath) 333 } 334} 335 336func (p *PrebuiltEtc) AndroidMkEntries() []android.AndroidMkEntries { 337 nameSuffix := "" 338 if p.inRamdisk() && !p.onlyInRamdisk() { 339 nameSuffix = ".ramdisk" 340 } 341 if p.inVendorRamdisk() && !p.onlyInVendorRamdisk() { 342 nameSuffix = ".vendor_ramdisk" 343 } 344 if p.inDebugRamdisk() && !p.onlyInDebugRamdisk() { 345 nameSuffix = ".debug_ramdisk" 346 } 347 if p.inRecovery() && !p.onlyInRecovery() { 348 nameSuffix = ".recovery" 349 } 350 return []android.AndroidMkEntries{android.AndroidMkEntries{ 351 Class: "ETC", 352 SubName: nameSuffix, 353 OutputFile: android.OptionalPathForPath(p.outputFilePath), 354 ExtraEntries: []android.AndroidMkExtraEntriesFunc{ 355 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { 356 entries.SetString("LOCAL_MODULE_TAGS", "optional") 357 entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.ToMakePath().String()) 358 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base()) 359 if len(p.properties.Symlinks) > 0 { 360 entries.AddStrings("LOCAL_MODULE_SYMLINKS", p.properties.Symlinks...) 361 } 362 entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.Installable()) 363 if p.additionalDependencies != nil { 364 entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", p.additionalDependencies.Strings()...) 365 } 366 }, 367 }, 368 }} 369} 370 371func InitPrebuiltEtcModule(p *PrebuiltEtc, dirBase string) { 372 p.installDirBase = dirBase 373 p.AddProperties(&p.properties) 374 p.AddProperties(&p.subdirProperties) 375} 376 377func InitPrebuiltRootModule(p *PrebuiltEtc) { 378 p.installDirBase = "." 379 p.AddProperties(&p.properties) 380} 381 382// prebuilt_etc is for a prebuilt artifact that is installed in 383// <partition>/etc/<sub_dir> directory. 384func PrebuiltEtcFactory() android.Module { 385 module := &PrebuiltEtc{} 386 InitPrebuiltEtcModule(module, "etc") 387 // This module is device-only 388 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 389 android.InitDefaultableModule(module) 390 return module 391} 392 393func defaultsFactory() android.Module { 394 return DefaultsFactory() 395} 396 397func DefaultsFactory(props ...interface{}) android.Module { 398 module := &Defaults{} 399 400 module.AddProperties(props...) 401 module.AddProperties( 402 &prebuiltEtcProperties{}, 403 &prebuiltSubdirProperties{}, 404 ) 405 406 android.InitDefaultsModule(module) 407 408 return module 409} 410 411// prebuilt_etc_host is for a host prebuilt artifact that is installed in 412// $(HOST_OUT)/etc/<sub_dir> directory. 413func PrebuiltEtcHostFactory() android.Module { 414 module := &PrebuiltEtc{} 415 InitPrebuiltEtcModule(module, "etc") 416 // This module is host-only 417 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) 418 return module 419} 420 421// prebuilt_root is for a prebuilt artifact that is installed in 422// <partition>/ directory. Can't have any sub directories. 423func PrebuiltRootFactory() android.Module { 424 module := &PrebuiltEtc{} 425 InitPrebuiltRootModule(module) 426 // This module is device-only 427 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 428 return module 429} 430 431// prebuilt_usr_share is for a prebuilt artifact that is installed in 432// <partition>/usr/share/<sub_dir> directory. 433func PrebuiltUserShareFactory() android.Module { 434 module := &PrebuiltEtc{} 435 InitPrebuiltEtcModule(module, "usr/share") 436 // This module is device-only 437 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 438 return module 439} 440 441// prebuild_usr_share_host is for a host prebuilt artifact that is installed in 442// $(HOST_OUT)/usr/share/<sub_dir> directory. 443func PrebuiltUserShareHostFactory() android.Module { 444 module := &PrebuiltEtc{} 445 InitPrebuiltEtcModule(module, "usr/share") 446 // This module is host-only 447 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) 448 return module 449} 450 451// prebuilt_font installs a font in <partition>/fonts directory. 452func PrebuiltFontFactory() android.Module { 453 module := &PrebuiltEtc{} 454 InitPrebuiltEtcModule(module, "fonts") 455 // This module is device-only 456 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 457 return module 458} 459 460// prebuilt_firmware installs a firmware file to <partition>/etc/firmware directory for system 461// image. 462// If soc_specific property is set to true, the firmware file is installed to the 463// vendor <partition>/firmware directory for vendor image. 464func PrebuiltFirmwareFactory() android.Module { 465 module := &PrebuiltEtc{} 466 module.socInstallDirBase = "firmware" 467 InitPrebuiltEtcModule(module, "etc/firmware") 468 // This module is device-only 469 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 470 return module 471} 472 473// prebuilt_dsp installs a DSP related file to <partition>/etc/dsp directory for system image. 474// If soc_specific property is set to true, the DSP related file is installed to the 475// vendor <partition>/dsp directory for vendor image. 476func PrebuiltDSPFactory() android.Module { 477 module := &PrebuiltEtc{} 478 module.socInstallDirBase = "dsp" 479 InitPrebuiltEtcModule(module, "etc/dsp") 480 // This module is device-only 481 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 482 return module 483} 484 485// prebuilt_rfsa installs a firmware file that will be available through Qualcomm's RFSA 486// to the <partition>/lib/rfsa directory. 487func PrebuiltRFSAFactory() android.Module { 488 module := &PrebuiltEtc{} 489 // Ideally these would go in /vendor/dsp, but the /vendor/lib/rfsa paths are hardcoded in too 490 // many places outside of the application processor. They could be moved to /vendor/dsp once 491 // that is cleaned up. 492 InitPrebuiltEtcModule(module, "lib/rfsa") 493 // This module is device-only 494 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 495 return module 496} 497