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 p.unstrippedOutputFile = in 148 libName := in.Base() 149 if p.stripper.NeedsStrip(ctx) { 150 stripFlags := flagsToStripFlags(flags) 151 stripped := android.PathForModuleOut(ctx, "stripped", libName) 152 p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags) 153 in = stripped 154 } 155 156 // Optimize out relinking against shared libraries whose interface hasn't changed by 157 // depending on a table of contents file instead of the library itself. 158 tocFile := android.PathForModuleOut(ctx, libName+".toc") 159 p.tocFile = android.OptionalPathForPath(tocFile) 160 TransformSharedObjectToToc(ctx, in, tocFile) 161 162 p.androidMkSuffix = p.NameSuffix() 163 164 vndkVersion := ctx.DeviceConfig().VndkVersion() 165 if vndkVersion == p.Version() { 166 p.androidMkSuffix = "" 167 } 168 169 ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ 170 SharedLibrary: in, 171 Target: ctx.Target(), 172 173 TableOfContents: p.tocFile, 174 }) 175 176 p.libraryDecorator.flagExporter.setProvider(ctx) 177 178 return in 179 } 180 181 ctx.Module().HideFromMake() 182 return nil 183} 184 185func (p *vndkPrebuiltLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool { 186 arches := config.Arches() 187 if len(arches) == 0 || arches[0].ArchType.String() != p.arch() { 188 return false 189 } 190 if config.BinderBitness() != p.binderBit() { 191 return false 192 } 193 if len(p.properties.Srcs) == 0 { 194 return false 195 } 196 return true 197} 198 199func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool { 200 return false 201} 202 203func (p *vndkPrebuiltLibraryDecorator) IsSnapshotPrebuilt() bool { 204 return true 205} 206 207func (p *vndkPrebuiltLibraryDecorator) install(ctx ModuleContext, file android.Path) { 208 // do not install vndk libs 209} 210 211func vndkPrebuiltSharedLibrary() *Module { 212 module, library := NewLibrary(android.DeviceSupported) 213 library.BuildOnlyShared() 214 module.stl = nil 215 module.sanitize = nil 216 library.disableStripping() 217 218 prebuilt := &vndkPrebuiltLibraryDecorator{ 219 libraryDecorator: library, 220 } 221 222 prebuilt.properties.Check_elf_files = BoolPtr(false) 223 prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true) 224 prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true) 225 226 // Prevent default system libs (libc, libm, and libdl) from being linked 227 if prebuilt.baseLinker.Properties.System_shared_libs == nil { 228 prebuilt.baseLinker.Properties.System_shared_libs = []string{} 229 } 230 231 module.compiler = nil 232 module.linker = prebuilt 233 module.installer = prebuilt 234 235 module.AddProperties( 236 &prebuilt.properties, 237 ) 238 239 android.AddLoadHook(module, func(ctx android.LoadHookContext) { 240 // empty BOARD_VNDK_VERSION implies that the device won't support 241 // system only OTA. In this case, VNDK snapshots aren't needed. 242 if ctx.DeviceConfig().VndkVersion() == "" { 243 ctx.Module().Disable() 244 } 245 }) 246 247 return module 248} 249 250// vndk_prebuilt_shared installs Vendor Native Development kit (VNDK) snapshot 251// shared libraries for system build. Example: 252// 253// vndk_prebuilt_shared { 254// name: "libfoo", 255// version: "27", 256// target_arch: "arm64", 257// vendor_available: true, 258// product_available: true, 259// vndk: { 260// enabled: true, 261// }, 262// export_include_dirs: ["include/external/libfoo/vndk_include"], 263// arch: { 264// arm64: { 265// srcs: ["arm/lib64/libfoo.so"], 266// }, 267// arm: { 268// srcs: ["arm/lib/libfoo.so"], 269// }, 270// }, 271// } 272func VndkPrebuiltSharedFactory() android.Module { 273 module := vndkPrebuiltSharedLibrary() 274 return module.Init() 275} 276 277func init() { 278 android.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) 279} 280