1// Copyright 2017 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 cc 16 17import ( 18 "strings" 19 20 "android/soong/android" 21) 22 23var ( 24 vndkSuffix = ".vndk." 25 binder32Suffix = ".binder32" 26) 27 28// Creates vndk prebuilts that include the VNDK version. 29// 30// Example: 31// 32// vndk_prebuilt_shared { 33// name: "libfoo", 34// version: "27", 35// target_arch: "arm64", 36// vendor_available: true, 37// product_available: true, 38// vndk: { 39// enabled: true, 40// }, 41// export_include_dirs: ["include/external/libfoo/vndk_include"], 42// arch: { 43// arm64: { 44// srcs: ["arm/lib64/libfoo.so"], 45// }, 46// arm: { 47// srcs: ["arm/lib/libfoo.so"], 48// }, 49// }, 50// } 51type vndkPrebuiltProperties struct { 52 // VNDK snapshot version. 53 Version *string 54 55 // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64') 56 Target_arch *string 57 58 // If the prebuilt snapshot lib is built with 32 bit binder, this must be set to true. 59 // The lib with 64 bit binder does not need to set this property. 60 Binder32bit *bool 61 62 // Prebuilt files for each arch. 63 Srcs []string `android:"arch_variant"` 64 65 // list of flags that will be used for any module that links against this module. 66 Export_flags []string `android:"arch_variant"` 67 68 // Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols, 69 // etc). 70 Check_elf_files *bool 71} 72 73type vndkPrebuiltLibraryDecorator struct { 74 *libraryDecorator 75 properties vndkPrebuiltProperties 76 androidMkSuffix string 77} 78 79func (p *vndkPrebuiltLibraryDecorator) Name(name string) string { 80 return name + p.NameSuffix() 81} 82 83func (p *vndkPrebuiltLibraryDecorator) NameSuffix() string { 84 suffix := p.Version() 85 if p.arch() != "" { 86 suffix += "." + p.arch() 87 } 88 if Bool(p.properties.Binder32bit) { 89 suffix += binder32Suffix 90 } 91 return vndkSuffix + suffix 92} 93 94func (p *vndkPrebuiltLibraryDecorator) Version() string { 95 return String(p.properties.Version) 96} 97 98func (p *vndkPrebuiltLibraryDecorator) arch() string { 99 return String(p.properties.Target_arch) 100} 101 102func (p *vndkPrebuiltLibraryDecorator) binderBit() string { 103 if Bool(p.properties.Binder32bit) { 104 return "32" 105 } 106 return "64" 107} 108 109func (p *vndkPrebuiltLibraryDecorator) SnapshotAndroidMkSuffix() string { 110 return ".vendor" 111} 112 113func (p *vndkPrebuiltLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { 114 p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix()) 115 return p.libraryDecorator.linkerFlags(ctx, flags) 116} 117 118func (p *vndkPrebuiltLibraryDecorator) singleSourcePath(ctx ModuleContext) android.Path { 119 if len(p.properties.Srcs) == 0 { 120 ctx.PropertyErrorf("srcs", "missing prebuilt source file") 121 return nil 122 } 123 124 if len(p.properties.Srcs) > 1 { 125 ctx.PropertyErrorf("srcs", "multiple prebuilt source files") 126 return nil 127 } 128 129 return android.PathForModuleSrc(ctx, p.properties.Srcs[0]) 130} 131 132func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext, 133 flags Flags, deps PathDeps, objs Objects) android.Path { 134 135 if !p.MatchesWithDevice(ctx.DeviceConfig()) { 136 ctx.Module().HideFromMake() 137 return nil 138 } 139 140 if len(p.properties.Srcs) > 0 && p.shared() { 141 p.libraryDecorator.exportIncludes(ctx) 142 p.libraryDecorator.reexportFlags(p.properties.Export_flags...) 143 // current VNDK prebuilts are only shared libs. 144 145 in := p.singleSourcePath(ctx) 146 p.unstrippedOutputFile = in 147 libName := in.Base() 148 if p.stripper.NeedsStrip(ctx) { 149 stripFlags := flagsToStripFlags(flags) 150 stripped := android.PathForModuleOut(ctx, "stripped", libName) 151 p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags) 152 in = stripped 153 } 154 155 // Optimize out relinking against shared libraries whose interface hasn't changed by 156 // depending on a table of contents file instead of the library itself. 157 tocFile := android.PathForModuleOut(ctx, libName+".toc") 158 p.tocFile = android.OptionalPathForPath(tocFile) 159 TransformSharedObjectToToc(ctx, in, tocFile) 160 161 p.androidMkSuffix = p.NameSuffix() 162 163 vndkVersion := ctx.DeviceConfig().VndkVersion() 164 if vndkVersion == p.Version() { 165 p.androidMkSuffix = "" 166 } 167 168 ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ 169 SharedLibrary: in, 170 Target: ctx.Target(), 171 172 TableOfContents: p.tocFile, 173 }) 174 175 p.libraryDecorator.flagExporter.setProvider(ctx) 176 177 return in 178 } 179 180 ctx.Module().HideFromMake() 181 return nil 182} 183 184func (p *vndkPrebuiltLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool { 185 arches := config.Arches() 186 if len(arches) == 0 || arches[0].ArchType.String() != p.arch() { 187 return false 188 } 189 if config.BinderBitness() != p.binderBit() { 190 return false 191 } 192 if len(p.properties.Srcs) == 0 { 193 return false 194 } 195 return true 196} 197 198func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool { 199 return false 200} 201 202func (p *vndkPrebuiltLibraryDecorator) IsSnapshotPrebuilt() bool { 203 return true 204} 205 206func (p *vndkPrebuiltLibraryDecorator) install(ctx ModuleContext, file android.Path) { 207 // do not install vndk libs 208} 209 210func vndkPrebuiltSharedLibrary() *Module { 211 module, library := NewLibrary(android.DeviceSupported) 212 library.BuildOnlyShared() 213 module.stl = nil 214 module.sanitize = nil 215 library.disableStripping() 216 217 prebuilt := &vndkPrebuiltLibraryDecorator{ 218 libraryDecorator: library, 219 } 220 221 prebuilt.properties.Check_elf_files = BoolPtr(false) 222 prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true) 223 prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true) 224 225 // Prevent default system libs (libc, libm, and libdl) from being linked 226 if prebuilt.baseLinker.Properties.System_shared_libs == nil { 227 prebuilt.baseLinker.Properties.System_shared_libs = []string{} 228 } 229 230 module.compiler = nil 231 module.linker = prebuilt 232 module.installer = prebuilt 233 234 module.AddProperties( 235 &prebuilt.properties, 236 ) 237 238 android.AddLoadHook(module, func(ctx android.LoadHookContext) { 239 // empty BOARD_VNDK_VERSION implies that the device won't support 240 // system only OTA. In this case, VNDK snapshots aren't needed. 241 if ctx.DeviceConfig().VndkVersion() == "" { 242 ctx.Module().Disable() 243 } 244 }) 245 246 return module 247} 248 249// vndk_prebuilt_shared installs Vendor Native Development kit (VNDK) snapshot 250// shared libraries for system build. Example: 251// 252// vndk_prebuilt_shared { 253// name: "libfoo", 254// version: "27", 255// target_arch: "arm64", 256// vendor_available: true, 257// product_available: true, 258// vndk: { 259// enabled: true, 260// }, 261// export_include_dirs: ["include/external/libfoo/vndk_include"], 262// arch: { 263// arm64: { 264// srcs: ["arm/lib64/libfoo.so"], 265// }, 266// arm: { 267// srcs: ["arm/lib/libfoo.so"], 268// }, 269// }, 270// } 271func VndkPrebuiltSharedFactory() android.Module { 272 module := vndkPrebuiltSharedLibrary() 273 return module.Init() 274} 275 276func init() { 277 android.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) 278} 279