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// vndk: { 38// enabled: true, 39// }, 40// export_include_dirs: ["include/external/libfoo/vndk_include"], 41// arch: { 42// arm64: { 43// srcs: ["arm/lib64/libfoo.so"], 44// }, 45// arm: { 46// srcs: ["arm/lib/libfoo.so"], 47// }, 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_ab') 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) linkerFlags(ctx ModuleContext, flags Flags) Flags { 110 p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix()) 111 return p.libraryDecorator.linkerFlags(ctx, flags) 112} 113 114func (p *vndkPrebuiltLibraryDecorator) singleSourcePath(ctx ModuleContext) android.Path { 115 if len(p.properties.Srcs) == 0 { 116 ctx.PropertyErrorf("srcs", "missing prebuilt source file") 117 return nil 118 } 119 120 if len(p.properties.Srcs) > 1 { 121 ctx.PropertyErrorf("srcs", "multiple prebuilt source files") 122 return nil 123 } 124 125 return android.PathForModuleSrc(ctx, p.properties.Srcs[0]) 126} 127 128func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext, 129 flags Flags, deps PathDeps, objs Objects) android.Path { 130 131 if !p.matchesWithDevice(ctx.DeviceConfig()) { 132 ctx.Module().SkipInstall() 133 return nil 134 } 135 136 if len(p.properties.Srcs) > 0 && p.shared() { 137 p.libraryDecorator.exportIncludes(ctx) 138 p.libraryDecorator.reexportFlags(p.properties.Export_flags...) 139 // current VNDK prebuilts are only shared libs. 140 141 in := p.singleSourcePath(ctx) 142 builderFlags := flagsToBuilderFlags(flags) 143 p.unstrippedOutputFile = in 144 libName := in.Base() 145 if p.needsStrip(ctx) { 146 stripped := android.PathForModuleOut(ctx, "stripped", libName) 147 p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags) 148 in = stripped 149 } 150 151 // Optimize out relinking against shared libraries whose interface hasn't changed by 152 // depending on a table of contents file instead of the library itself. 153 tocFile := android.PathForModuleOut(ctx, libName+".toc") 154 p.tocFile = android.OptionalPathForPath(tocFile) 155 TransformSharedObjectToToc(ctx, in, tocFile, builderFlags) 156 157 p.androidMkSuffix = p.NameSuffix() 158 159 vndkVersion := ctx.DeviceConfig().VndkVersion() 160 if vndkVersion == p.version() { 161 p.androidMkSuffix = "" 162 } 163 164 return in 165 } 166 167 ctx.Module().SkipInstall() 168 return nil 169} 170 171func (p *vndkPrebuiltLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool { 172 arches := config.Arches() 173 if len(arches) == 0 || arches[0].ArchType.String() != p.arch() { 174 return false 175 } 176 if config.BinderBitness() != p.binderBit() { 177 return false 178 } 179 if len(p.properties.Srcs) == 0 { 180 return false 181 } 182 return true 183} 184 185func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool { 186 return false 187} 188 189func (p *vndkPrebuiltLibraryDecorator) isSnapshotPrebuilt() bool { 190 return true 191} 192 193func (p *vndkPrebuiltLibraryDecorator) install(ctx ModuleContext, file android.Path) { 194 arches := ctx.DeviceConfig().Arches() 195 if len(arches) == 0 || arches[0].ArchType.String() != p.arch() { 196 return 197 } 198 if ctx.DeviceConfig().BinderBitness() != p.binderBit() { 199 return 200 } 201 if p.shared() { 202 if ctx.isVndkSp() { 203 p.baseInstaller.subDir = "vndk-sp-" + p.version() 204 } else if ctx.isVndk() { 205 p.baseInstaller.subDir = "vndk-" + p.version() 206 } 207 p.baseInstaller.install(ctx, file) 208 } 209} 210 211func vndkPrebuiltSharedLibrary() *Module { 212 module, library := NewLibrary(android.DeviceSupported) 213 library.BuildOnlyShared() 214 module.stl = nil 215 module.sanitize = nil 216 library.StripProperties.Strip.None = BoolPtr(true) 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 return module 240} 241 242// vndk_prebuilt_shared installs Vendor Native Development kit (VNDK) snapshot 243// shared libraries for system build. Example: 244// 245// vndk_prebuilt_shared { 246// name: "libfoo", 247// version: "27", 248// target_arch: "arm64", 249// vendor_available: true, 250// vndk: { 251// enabled: true, 252// }, 253// export_include_dirs: ["include/external/libfoo/vndk_include"], 254// arch: { 255// arm64: { 256// srcs: ["arm/lib64/libfoo.so"], 257// }, 258// arm: { 259// srcs: ["arm/lib/libfoo.so"], 260// }, 261// }, 262// } 263func VndkPrebuiltSharedFactory() android.Module { 264 module := vndkPrebuiltSharedLibrary() 265 return module.Init() 266} 267 268func init() { 269 android.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) 270} 271