|  | // Copyright 2017 Google Inc. All rights reserved. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  |  | 
|  | package cc | 
|  |  | 
|  | import ( | 
|  | "strings" | 
|  |  | 
|  | "android/soong/android" | 
|  | ) | 
|  |  | 
|  | var ( | 
|  | vndkSuffix     = ".vndk." | 
|  | binder32Suffix = ".binder32" | 
|  | ) | 
|  |  | 
|  | // Creates vndk prebuilts that include the VNDK version. | 
|  | // | 
|  | // Example: | 
|  | // | 
|  | //	vndk_prebuilt_shared { | 
|  | //	    name: "libfoo", | 
|  | //	    version: "27", | 
|  | //	    target_arch: "arm64", | 
|  | //	    vendor_available: true, | 
|  | //	    product_available: true, | 
|  | //	    vndk: { | 
|  | //	        enabled: true, | 
|  | //	    }, | 
|  | //	    export_include_dirs: ["include/external/libfoo/vndk_include"], | 
|  | //	    arch: { | 
|  | //	        arm64: { | 
|  | //	            srcs: ["arm/lib64/libfoo.so"], | 
|  | //	        }, | 
|  | //	        arm: { | 
|  | //	            srcs: ["arm/lib/libfoo.so"], | 
|  | //	        }, | 
|  | //	    }, | 
|  | //	} | 
|  | type vndkPrebuiltProperties struct { | 
|  | // VNDK snapshot version. | 
|  | Version *string | 
|  |  | 
|  | // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64') | 
|  | Target_arch *string | 
|  |  | 
|  | // If the prebuilt snapshot lib is built with 32 bit binder, this must be set to true. | 
|  | // The lib with 64 bit binder does not need to set this property. | 
|  | Binder32bit *bool | 
|  |  | 
|  | // Prebuilt files for each arch. | 
|  | Srcs []string `android:"arch_variant"` | 
|  |  | 
|  | // list of flags that will be used for any module that links against this module. | 
|  | Export_flags []string `android:"arch_variant"` | 
|  |  | 
|  | // Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols, | 
|  | // etc). | 
|  | Check_elf_files *bool | 
|  | } | 
|  |  | 
|  | type vndkPrebuiltLibraryDecorator struct { | 
|  | *libraryDecorator | 
|  | properties      vndkPrebuiltProperties | 
|  | androidMkSuffix string | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) Name(name string) string { | 
|  | return name + p.NameSuffix() | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) NameSuffix() string { | 
|  | suffix := p.Version() | 
|  | if p.arch() != "" { | 
|  | suffix += "." + p.arch() | 
|  | } | 
|  | if Bool(p.properties.Binder32bit) { | 
|  | suffix += binder32Suffix | 
|  | } | 
|  | return vndkSuffix + suffix | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) Version() string { | 
|  | return String(p.properties.Version) | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) arch() string { | 
|  | return String(p.properties.Target_arch) | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) binderBit() string { | 
|  | if Bool(p.properties.Binder32bit) { | 
|  | return "32" | 
|  | } | 
|  | return "64" | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) SnapshotAndroidMkSuffix() string { | 
|  | return ".vendor" | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { | 
|  | p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix()) | 
|  | return p.libraryDecorator.linkerFlags(ctx, flags) | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) singleSourcePath(ctx ModuleContext) android.Path { | 
|  | if len(p.properties.Srcs) == 0 { | 
|  | ctx.PropertyErrorf("srcs", "missing prebuilt source file") | 
|  | return nil | 
|  | } | 
|  |  | 
|  | if len(p.properties.Srcs) > 1 { | 
|  | ctx.PropertyErrorf("srcs", "multiple prebuilt source files") | 
|  | return nil | 
|  | } | 
|  |  | 
|  | return android.PathForModuleSrc(ctx, p.properties.Srcs[0]) | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext, | 
|  | flags Flags, deps PathDeps, objs Objects) android.Path { | 
|  | platformVndkApiLevel := android.ApiLevelOrPanic(ctx, ctx.DeviceConfig().PlatformVndkVersion()) | 
|  | if platformVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(ctx, p.Version())) { | 
|  | // This prebuilt VNDK module is not required for the current build | 
|  | ctx.Module().HideFromMake() | 
|  | return nil | 
|  | } | 
|  |  | 
|  | if !p.MatchesWithDevice(ctx.DeviceConfig()) { | 
|  | ctx.Module().HideFromMake() | 
|  | return nil | 
|  | } | 
|  |  | 
|  | if len(p.properties.Srcs) > 0 && p.shared() { | 
|  | p.libraryDecorator.exportIncludes(ctx) | 
|  | p.libraryDecorator.reexportFlags(p.properties.Export_flags...) | 
|  | // current VNDK prebuilts are only shared libs. | 
|  |  | 
|  | in := p.singleSourcePath(ctx) | 
|  | p.unstrippedOutputFile = in | 
|  | libName := in.Base() | 
|  | if p.stripper.NeedsStrip(ctx) { | 
|  | stripFlags := flagsToStripFlags(flags) | 
|  | stripped := android.PathForModuleOut(ctx, "stripped", libName) | 
|  | p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags) | 
|  | in = stripped | 
|  | } | 
|  |  | 
|  | // Optimize out relinking against shared libraries whose interface hasn't changed by | 
|  | // depending on a table of contents file instead of the library itself. | 
|  | tocFile := android.PathForModuleOut(ctx, libName+".toc") | 
|  | p.tocFile = android.OptionalPathForPath(tocFile) | 
|  | TransformSharedObjectToToc(ctx, in, tocFile) | 
|  |  | 
|  | p.androidMkSuffix = p.NameSuffix() | 
|  |  | 
|  | vndkVersion := ctx.DeviceConfig().VndkVersion() | 
|  | if vndkVersion == p.Version() { | 
|  | p.androidMkSuffix = "" | 
|  | } | 
|  |  | 
|  | ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ | 
|  | SharedLibrary: in, | 
|  | Target:        ctx.Target(), | 
|  |  | 
|  | TableOfContents: p.tocFile, | 
|  | }) | 
|  |  | 
|  | p.libraryDecorator.flagExporter.setProvider(ctx) | 
|  |  | 
|  | return in | 
|  | } | 
|  |  | 
|  | ctx.Module().HideFromMake() | 
|  | return nil | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool { | 
|  | arches := config.Arches() | 
|  | if len(arches) == 0 || arches[0].ArchType.String() != p.arch() { | 
|  | return false | 
|  | } | 
|  | if config.BinderBitness() != p.binderBit() { | 
|  | return false | 
|  | } | 
|  | if len(p.properties.Srcs) == 0 { | 
|  | return false | 
|  | } | 
|  | return true | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool { | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) IsSnapshotPrebuilt() bool { | 
|  | return true | 
|  | } | 
|  |  | 
|  | func (p *vndkPrebuiltLibraryDecorator) install(ctx ModuleContext, file android.Path) { | 
|  | // do not install vndk libs | 
|  | } | 
|  |  | 
|  | func vndkPrebuiltSharedLibrary() *Module { | 
|  | module, library := NewLibrary(android.DeviceSupported) | 
|  | library.BuildOnlyShared() | 
|  | module.stl = nil | 
|  | module.sanitize = nil | 
|  | library.disableStripping() | 
|  |  | 
|  | prebuilt := &vndkPrebuiltLibraryDecorator{ | 
|  | libraryDecorator: library, | 
|  | } | 
|  |  | 
|  | prebuilt.properties.Check_elf_files = BoolPtr(false) | 
|  | prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true) | 
|  | prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true) | 
|  |  | 
|  | // Prevent default system libs (libc, libm, and libdl) from being linked | 
|  | if prebuilt.baseLinker.Properties.System_shared_libs == nil { | 
|  | prebuilt.baseLinker.Properties.System_shared_libs = []string{} | 
|  | } | 
|  |  | 
|  | module.compiler = nil | 
|  | module.linker = prebuilt | 
|  | module.installer = prebuilt | 
|  |  | 
|  | module.AddProperties( | 
|  | &prebuilt.properties, | 
|  | ) | 
|  |  | 
|  | android.AddLoadHook(module, func(ctx android.LoadHookContext) { | 
|  | // empty BOARD_VNDK_VERSION implies that the device won't support | 
|  | // system only OTA. In this case, VNDK snapshots aren't needed. | 
|  | if ctx.DeviceConfig().VndkVersion() == "" { | 
|  | ctx.Module().Disable() | 
|  | } | 
|  | }) | 
|  |  | 
|  | return module | 
|  | } | 
|  |  | 
|  | // vndk_prebuilt_shared installs Vendor Native Development kit (VNDK) snapshot | 
|  | // shared libraries for system build. Example: | 
|  | // | 
|  | //	vndk_prebuilt_shared { | 
|  | //	    name: "libfoo", | 
|  | //	    version: "27", | 
|  | //	    target_arch: "arm64", | 
|  | //	    vendor_available: true, | 
|  | //	    product_available: true, | 
|  | //	    vndk: { | 
|  | //	        enabled: true, | 
|  | //	    }, | 
|  | //	    export_include_dirs: ["include/external/libfoo/vndk_include"], | 
|  | //	    arch: { | 
|  | //	        arm64: { | 
|  | //	            srcs: ["arm/lib64/libfoo.so"], | 
|  | //	        }, | 
|  | //	        arm: { | 
|  | //	            srcs: ["arm/lib/libfoo.so"], | 
|  | //	        }, | 
|  | //	    }, | 
|  | //	} | 
|  | func VndkPrebuiltSharedFactory() android.Module { | 
|  | module := vndkPrebuiltSharedLibrary() | 
|  | return module.Init() | 
|  | } | 
|  |  | 
|  | func init() { | 
|  | android.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) | 
|  | } |