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