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