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 17import ( 18 "strconv" 19 20 "github.com/google/blueprint/proptools" 21 22 "android/soong/android" 23) 24 25var pctx = android.NewPackageContext("android/soong/etc") 26 27// TODO(jungw): Now that it handles more than the ones in etc/, consider renaming this file. 28 29func init() { 30 pctx.Import("android/soong/android") 31 32 android.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory) 33 android.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory) 34 android.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory) 35 android.RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory) 36 android.RegisterModuleType("prebuilt_font", PrebuiltFontFactory) 37 android.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory) 38 android.RegisterModuleType("prebuilt_dsp", PrebuiltDSPFactory) 39} 40 41type prebuiltEtcProperties struct { 42 // Source file of this prebuilt. 43 Src *string `android:"path,arch_variant"` 44 45 // optional subdirectory under which this file is installed into, cannot be specified with relative_install_path, prefer relative_install_path 46 Sub_dir *string `android:"arch_variant"` 47 48 // optional subdirectory under which this file is installed into, cannot be specified with sub_dir 49 Relative_install_path *string `android:"arch_variant"` 50 51 // optional name for the installed file. If unspecified, name of the module is used as the file name 52 Filename *string `android:"arch_variant"` 53 54 // when set to true, and filename property is not set, the name for the installed file 55 // is the same as the file name of the source file. 56 Filename_from_src *bool `android:"arch_variant"` 57 58 // Make this module available when building for ramdisk. 59 Ramdisk_available *bool 60 61 // Make this module available when building for recovery. 62 Recovery_available *bool 63 64 // Whether this module is directly installable to one of the partitions. Default: true. 65 Installable *bool 66 67 // Install symlinks to the installed file. 68 Symlinks []string `android:"arch_variant"` 69} 70 71type PrebuiltEtcModule interface { 72 android.Module 73 SubDir() string 74 OutputFile() android.OutputPath 75} 76 77type PrebuiltEtc struct { 78 android.ModuleBase 79 80 properties prebuiltEtcProperties 81 82 sourceFilePath android.Path 83 outputFilePath android.OutputPath 84 // The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share. 85 installDirBase string 86 // The base install location when soc_specific property is set to true, e.g. "firmware" for prebuilt_firmware. 87 socInstallDirBase string 88 installDirPath android.InstallPath 89 additionalDependencies *android.Paths 90} 91 92func (p *PrebuiltEtc) inRamdisk() bool { 93 return p.ModuleBase.InRamdisk() || p.ModuleBase.InstallInRamdisk() 94} 95 96func (p *PrebuiltEtc) onlyInRamdisk() bool { 97 return p.ModuleBase.InstallInRamdisk() 98} 99 100func (p *PrebuiltEtc) InstallInRamdisk() bool { 101 return p.inRamdisk() 102} 103 104func (p *PrebuiltEtc) inRecovery() bool { 105 return p.ModuleBase.InRecovery() || p.ModuleBase.InstallInRecovery() 106} 107 108func (p *PrebuiltEtc) onlyInRecovery() bool { 109 return p.ModuleBase.InstallInRecovery() 110} 111 112func (p *PrebuiltEtc) InstallInRecovery() bool { 113 return p.inRecovery() 114} 115 116var _ android.ImageInterface = (*PrebuiltEtc)(nil) 117 118func (p *PrebuiltEtc) ImageMutatorBegin(ctx android.BaseModuleContext) {} 119 120func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool { 121 return !p.ModuleBase.InstallInRecovery() && !p.ModuleBase.InstallInRamdisk() 122} 123 124func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 125 return proptools.Bool(p.properties.Ramdisk_available) || p.ModuleBase.InstallInRamdisk() 126} 127 128func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { 129 return proptools.Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery() 130} 131 132func (p *PrebuiltEtc) ExtraImageVariations(ctx android.BaseModuleContext) []string { 133 return nil 134} 135 136func (p *PrebuiltEtc) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) { 137} 138 139func (p *PrebuiltEtc) DepsMutator(ctx android.BottomUpMutatorContext) { 140 if p.properties.Src == nil { 141 ctx.PropertyErrorf("src", "missing prebuilt source file") 142 } 143} 144 145func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path { 146 return android.PathForModuleSrc(ctx, android.String(p.properties.Src)) 147} 148 149func (p *PrebuiltEtc) InstallDirPath() android.InstallPath { 150 return p.installDirPath 151} 152 153// This allows other derivative modules (e.g. prebuilt_etc_xml) to perform 154// additional steps (like validating the src) before the file is installed. 155func (p *PrebuiltEtc) SetAdditionalDependencies(paths android.Paths) { 156 p.additionalDependencies = &paths 157} 158 159func (p *PrebuiltEtc) OutputFile() android.OutputPath { 160 return p.outputFilePath 161} 162 163func (p *PrebuiltEtc) SubDir() string { 164 if subDir := proptools.String(p.properties.Sub_dir); subDir != "" { 165 return subDir 166 } 167 return proptools.String(p.properties.Relative_install_path) 168} 169 170func (p *PrebuiltEtc) Installable() bool { 171 return p.properties.Installable == nil || android.Bool(p.properties.Installable) 172} 173 174func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) { 175 p.sourceFilePath = android.PathForModuleSrc(ctx, android.String(p.properties.Src)) 176 filename := android.String(p.properties.Filename) 177 filename_from_src := android.Bool(p.properties.Filename_from_src) 178 if filename == "" { 179 if filename_from_src { 180 filename = p.sourceFilePath.Base() 181 } else { 182 filename = ctx.ModuleName() 183 } 184 } else if filename_from_src { 185 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true") 186 return 187 } 188 p.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath 189 190 if p.properties.Sub_dir != nil && p.properties.Relative_install_path != nil { 191 ctx.PropertyErrorf("sub_dir", "relative_install_path is set. Cannot set sub_dir") 192 } 193 194 // If soc install dir was specified and SOC specific is set, set the installDirPath to the specified 195 // socInstallDirBase. 196 installBaseDir := p.installDirBase 197 if ctx.SocSpecific() && p.socInstallDirBase != "" { 198 installBaseDir = p.socInstallDirBase 199 } 200 p.installDirPath = android.PathForModuleInstall(ctx, installBaseDir, p.SubDir()) 201 202 // This ensures that outputFilePath has the correct name for others to 203 // use, as the source file may have a different name. 204 ctx.Build(pctx, android.BuildParams{ 205 Rule: android.Cp, 206 Output: p.outputFilePath, 207 Input: p.sourceFilePath, 208 }) 209} 210 211func (p *PrebuiltEtc) AndroidMkEntries() []android.AndroidMkEntries { 212 nameSuffix := "" 213 if p.inRamdisk() && !p.onlyInRamdisk() { 214 nameSuffix = ".ramdisk" 215 } 216 if p.inRecovery() && !p.onlyInRecovery() { 217 nameSuffix = ".recovery" 218 } 219 return []android.AndroidMkEntries{android.AndroidMkEntries{ 220 Class: "ETC", 221 SubName: nameSuffix, 222 OutputFile: android.OptionalPathForPath(p.outputFilePath), 223 ExtraEntries: []android.AndroidMkExtraEntriesFunc{ 224 func(entries *android.AndroidMkEntries) { 225 entries.SetString("LOCAL_MODULE_TAGS", "optional") 226 entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.ToMakePath().String()) 227 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base()) 228 if len(p.properties.Symlinks) > 0 { 229 entries.AddStrings("LOCAL_MODULE_SYMLINKS", p.properties.Symlinks...) 230 } 231 entries.SetString("LOCAL_UNINSTALLABLE_MODULE", strconv.FormatBool(!p.Installable())) 232 if p.additionalDependencies != nil { 233 for _, path := range *p.additionalDependencies { 234 entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", path.String()) 235 } 236 } 237 }, 238 }, 239 }} 240} 241 242func InitPrebuiltEtcModule(p *PrebuiltEtc, dirBase string) { 243 p.installDirBase = dirBase 244 p.AddProperties(&p.properties) 245} 246 247// prebuilt_etc is for a prebuilt artifact that is installed in 248// <partition>/etc/<sub_dir> directory. 249func PrebuiltEtcFactory() android.Module { 250 module := &PrebuiltEtc{} 251 InitPrebuiltEtcModule(module, "etc") 252 // This module is device-only 253 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 254 return module 255} 256 257// prebuilt_etc_host is for a host prebuilt artifact that is installed in 258// $(HOST_OUT)/etc/<sub_dir> directory. 259func PrebuiltEtcHostFactory() android.Module { 260 module := &PrebuiltEtc{} 261 InitPrebuiltEtcModule(module, "etc") 262 // This module is host-only 263 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) 264 return module 265} 266 267// prebuilt_usr_share is for a prebuilt artifact that is installed in 268// <partition>/usr/share/<sub_dir> directory. 269func PrebuiltUserShareFactory() android.Module { 270 module := &PrebuiltEtc{} 271 InitPrebuiltEtcModule(module, "usr/share") 272 // This module is device-only 273 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 274 return module 275} 276 277// prebuild_usr_share_host is for a host prebuilt artifact that is installed in 278// $(HOST_OUT)/usr/share/<sub_dir> directory. 279func PrebuiltUserShareHostFactory() android.Module { 280 module := &PrebuiltEtc{} 281 InitPrebuiltEtcModule(module, "usr/share") 282 // This module is host-only 283 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) 284 return module 285} 286 287// prebuilt_font installs a font in <partition>/fonts directory. 288func PrebuiltFontFactory() android.Module { 289 module := &PrebuiltEtc{} 290 InitPrebuiltEtcModule(module, "fonts") 291 // This module is device-only 292 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 293 return module 294} 295 296// prebuilt_firmware installs a firmware file to <partition>/etc/firmware directory for system image. 297// If soc_specific property is set to true, the firmware file is installed to the vendor <partition>/firmware 298// directory for vendor image. 299func PrebuiltFirmwareFactory() android.Module { 300 module := &PrebuiltEtc{} 301 module.socInstallDirBase = "firmware" 302 InitPrebuiltEtcModule(module, "etc/firmware") 303 // This module is device-only 304 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 305 return module 306} 307 308// prebuilt_dsp installs a DSP related file to <partition>/etc/dsp directory for system image. 309// If soc_specific property is set to true, the DSP related file is installed to the vendor <partition>/dsp 310// directory for vendor image. 311func PrebuiltDSPFactory() android.Module { 312 module := &PrebuiltEtc{} 313 module.socInstallDirBase = "dsp" 314 InitPrebuiltEtcModule(module, "etc/dsp") 315 // This module is device-only 316 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 317 return module 318} 319