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 VndkProperties 53 54 // VNDK snapshot version. 55 Version *string 56 57 // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64') 58 Target_arch *string 59 60 // If the prebuilt snapshot lib is built with 32 bit binder, this must be set to true. 61 // The lib with 64 bit binder does not need to set this property. 62 Binder32bit *bool 63 64 // Prebuilt files for each arch. 65 Srcs []string `android:"arch_variant"` 66 67 // list of flags that will be used for any module that links against this module. 68 Export_flags []string `android:"arch_variant"` 69 70 // Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols, 71 // etc). 72 Check_elf_files *bool 73} 74 75type vndkPrebuiltLibraryDecorator struct { 76 *libraryDecorator 77 properties vndkPrebuiltProperties 78 androidMkSuffix string 79} 80 81func (p *vndkPrebuiltLibraryDecorator) Name(name string) string { 82 return name + p.NameSuffix() 83} 84 85func (p *vndkPrebuiltLibraryDecorator) NameSuffix() string { 86 suffix := p.Version() 87 if p.arch() != "" { 88 suffix += "." + p.arch() 89 } 90 if Bool(p.properties.Binder32bit) { 91 suffix += binder32Suffix 92 } 93 return vndkSuffix + suffix 94} 95 96func (p *vndkPrebuiltLibraryDecorator) Version() string { 97 return String(p.properties.Version) 98} 99 100func (p *vndkPrebuiltLibraryDecorator) arch() string { 101 return String(p.properties.Target_arch) 102} 103 104func (p *vndkPrebuiltLibraryDecorator) binderBit() string { 105 if Bool(p.properties.Binder32bit) { 106 return "32" 107 } 108 return "64" 109} 110 111func (p *vndkPrebuiltLibraryDecorator) SnapshotAndroidMkSuffix() string { 112 return ".vendor" 113} 114 115func (p *vndkPrebuiltLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { 116 p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix()) 117 return p.libraryDecorator.linkerFlags(ctx, flags) 118} 119 120func (p *vndkPrebuiltLibraryDecorator) singleSourcePath(ctx ModuleContext) android.Path { 121 if len(p.properties.Srcs) == 0 { 122 ctx.PropertyErrorf("srcs", "missing prebuilt source file") 123 return nil 124 } 125 126 if len(p.properties.Srcs) > 1 { 127 ctx.PropertyErrorf("srcs", "multiple prebuilt source files") 128 return nil 129 } 130 131 return android.PathForModuleSrc(ctx, p.properties.Srcs[0]) 132} 133 134func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext, 135 flags Flags, deps PathDeps, objs Objects) android.Path { 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 android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{ 165 SharedLibrary: in, 166 Target: ctx.Target(), 167 168 TableOfContents: p.tocFile, 169 IsStubs: false, 170 }) 171 172 p.libraryDecorator.flagExporter.setProvider(ctx) 173 174 return in 175 } 176 177 ctx.Module().HideFromMake() 178 return nil 179} 180 181func (p *vndkPrebuiltLibraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { 182 p.libraryDecorator.moduleInfoJSON(ctx, moduleInfoJSON) 183 moduleInfoJSON.SubName += p.androidMkSuffix 184} 185 186func (p *vndkPrebuiltLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool { 187 arches := config.Arches() 188 if len(arches) == 0 || arches[0].ArchType.String() != p.arch() { 189 return false 190 } 191 if config.BinderBitness() != p.binderBit() { 192 return false 193 } 194 if len(p.properties.Srcs) == 0 { 195 return false 196 } 197 return true 198} 199 200func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool { 201 return false 202} 203 204func (p *vndkPrebuiltLibraryDecorator) IsSnapshotPrebuilt() bool { 205 return true 206} 207 208func (p *vndkPrebuiltLibraryDecorator) install(ctx ModuleContext, file android.Path) { 209 // do not install vndk libs 210} 211 212func vndkPrebuiltSharedLibrary() *Module { 213 module, library := NewLibrary(android.DeviceSupported) 214 library.BuildOnlyShared() 215 module.stl = nil 216 module.sanitize = nil 217 library.disableStripping() 218 219 prebuilt := &vndkPrebuiltLibraryDecorator{ 220 libraryDecorator: library, 221 } 222 223 prebuilt.properties.Check_elf_files = BoolPtr(false) 224 prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true) 225 prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true) 226 prebuilt.baseLinker.Properties.No_crt_pad_segment = 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 return module 242} 243 244// vndk_prebuilt_shared installs Vendor Native Development kit (VNDK) snapshot 245// shared libraries for system build. Example: 246// 247// vndk_prebuilt_shared { 248// name: "libfoo", 249// version: "27", 250// target_arch: "arm64", 251// vendor_available: true, 252// product_available: true, 253// vndk: { 254// enabled: true, 255// }, 256// export_include_dirs: ["include/external/libfoo/vndk_include"], 257// arch: { 258// arm64: { 259// srcs: ["arm/lib64/libfoo.so"], 260// }, 261// arm: { 262// srcs: ["arm/lib/libfoo.so"], 263// }, 264// }, 265// } 266func VndkPrebuiltSharedFactory() android.Module { 267 module := vndkPrebuiltSharedLibrary() 268 return module.Init() 269} 270 271func init() { 272 android.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) 273} 274 275func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool { 276 if !m.Enabled(mctx) { 277 return true 278 } 279 280 if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok { 281 return p.MatchesWithDevice(mctx.DeviceConfig()) && Bool(p.properties.Vndk.Enabled) 282 } 283 return false 284} 285