The APIs that are tagged with # vndk are actually for LLNDK libraries.
Although LLNDK is part of VNDK, calling those APIs 'vndk' has given
users a wrong perception that the APIs don't need to be kept stable
because that's the norm for most of the VNDK libraries that are not
LLNDK.
In order to eliminate the misunderstanding, rename the tag to 'llndk' so
that people introducing new such API will realize what they are signing
themselves up for.
Exempt-From-Owner-Approval: cherry-pick from internal gerrit
Bug: 143765505
Test: m
Test: python3 test_gen_stub_libs.py
Merged-In: I2853df3b6e245056c21d4ab3d62466954cf26d72
(cherry picked from commit 3d7b69a657
)
Change-Id: I2853df3b6e245056c21d4ab3d62466954cf26d72
243 lines
7.2 KiB
Go
243 lines
7.2 KiB
Go
// 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 (
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"android/soong/android"
|
|
)
|
|
|
|
var (
|
|
llndkLibrarySuffix = ".llndk"
|
|
llndkHeadersSuffix = ".llndk"
|
|
)
|
|
|
|
// Creates a stub shared library based on the provided version file.
|
|
//
|
|
// Example:
|
|
//
|
|
// llndk_library {
|
|
// name: "libfoo",
|
|
// symbol_file: "libfoo.map.txt",
|
|
// export_include_dirs: ["include_vndk"],
|
|
// }
|
|
//
|
|
type llndkLibraryProperties struct {
|
|
// Relative path to the symbol map.
|
|
// An example file can be seen here: TODO(danalbert): Make an example.
|
|
Symbol_file *string
|
|
|
|
// Whether to export any headers as -isystem instead of -I. Mainly for use by
|
|
// bionic/libc.
|
|
Export_headers_as_system *bool
|
|
|
|
// Which headers to process with versioner. This really only handles
|
|
// bionic/libc/include right now.
|
|
Export_preprocessed_headers []string
|
|
|
|
// Whether the system library uses symbol versions.
|
|
Unversioned *bool
|
|
|
|
// whether this module can be directly depended upon by libs that are installed to /vendor.
|
|
// When set to false, this module can only be depended on by VNDK libraries, not vendor
|
|
// libraries. This effectively hides this module from vendors. Default value is true.
|
|
Vendor_available *bool
|
|
|
|
// list of llndk headers to re-export include directories from.
|
|
Export_llndk_headers []string `android:"arch_variant"`
|
|
}
|
|
|
|
type llndkStubDecorator struct {
|
|
*libraryDecorator
|
|
|
|
Properties llndkLibraryProperties
|
|
|
|
exportHeadersTimestamp android.OptionalPath
|
|
versionScriptPath android.ModuleGenPath
|
|
}
|
|
|
|
func (stub *llndkStubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
|
|
flags = stub.baseCompiler.compilerFlags(ctx, flags, deps)
|
|
return addStubLibraryCompilerFlags(flags)
|
|
}
|
|
|
|
func (stub *llndkStubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
|
|
vndk_ver := ctx.Module().(*Module).Properties.VndkVersion
|
|
if vndk_ver == "current" {
|
|
platform_vndk_ver := ctx.DeviceConfig().PlatformVndkVersion()
|
|
if !inList(platform_vndk_ver, ctx.Config().PlatformVersionCombinedCodenames()) {
|
|
vndk_ver = platform_vndk_ver
|
|
}
|
|
} else if vndk_ver == "" {
|
|
// For non-enforcing devices, use "current"
|
|
vndk_ver = "current"
|
|
}
|
|
objs, versionScript := compileStubLibrary(ctx, flags, String(stub.Properties.Symbol_file), vndk_ver, "--llndk")
|
|
stub.versionScriptPath = versionScript
|
|
return objs
|
|
}
|
|
|
|
func (stub *llndkStubDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|
headers := addSuffix(stub.Properties.Export_llndk_headers, llndkHeadersSuffix)
|
|
deps.HeaderLibs = append(deps.HeaderLibs, headers...)
|
|
deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders, headers...)
|
|
return deps
|
|
}
|
|
|
|
func (stub *llndkStubDecorator) Name(name string) string {
|
|
return name + llndkLibrarySuffix
|
|
}
|
|
|
|
func (stub *llndkStubDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
|
stub.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(),
|
|
llndkLibrarySuffix)
|
|
return stub.libraryDecorator.linkerFlags(ctx, flags)
|
|
}
|
|
|
|
func (stub *llndkStubDecorator) processHeaders(ctx ModuleContext, srcHeaderDir string, outDir android.ModuleGenPath) android.Path {
|
|
srcDir := android.PathForModuleSrc(ctx, srcHeaderDir)
|
|
srcFiles := ctx.GlobFiles(filepath.Join(srcDir.String(), "**/*.h"), nil)
|
|
|
|
var installPaths []android.WritablePath
|
|
for _, header := range srcFiles {
|
|
headerDir := filepath.Dir(header.String())
|
|
relHeaderDir, err := filepath.Rel(srcDir.String(), headerDir)
|
|
if err != nil {
|
|
ctx.ModuleErrorf("filepath.Rel(%q, %q) failed: %s",
|
|
srcDir.String(), headerDir, err)
|
|
continue
|
|
}
|
|
|
|
installPaths = append(installPaths, outDir.Join(ctx, relHeaderDir, header.Base()))
|
|
}
|
|
|
|
return processHeadersWithVersioner(ctx, srcDir, outDir, srcFiles, installPaths)
|
|
}
|
|
|
|
func (stub *llndkStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps,
|
|
objs Objects) android.Path {
|
|
|
|
if !Bool(stub.Properties.Unversioned) {
|
|
linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String()
|
|
flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag)
|
|
flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath)
|
|
}
|
|
|
|
if len(stub.Properties.Export_preprocessed_headers) > 0 {
|
|
genHeaderOutDir := android.PathForModuleGen(ctx, "include")
|
|
|
|
var timestampFiles android.Paths
|
|
for _, dir := range stub.Properties.Export_preprocessed_headers {
|
|
timestampFiles = append(timestampFiles, stub.processHeaders(ctx, dir, genHeaderOutDir))
|
|
}
|
|
|
|
if Bool(stub.Properties.Export_headers_as_system) {
|
|
stub.reexportSystemDirs(genHeaderOutDir)
|
|
} else {
|
|
stub.reexportDirs(genHeaderOutDir)
|
|
}
|
|
|
|
stub.reexportDeps(timestampFiles...)
|
|
}
|
|
|
|
if Bool(stub.Properties.Export_headers_as_system) {
|
|
stub.exportIncludesAsSystem(ctx)
|
|
stub.libraryDecorator.flagExporter.Properties.Export_include_dirs = []string{}
|
|
}
|
|
|
|
return stub.libraryDecorator.link(ctx, flags, deps, objs)
|
|
}
|
|
|
|
func (stub *llndkStubDecorator) nativeCoverage() bool {
|
|
return false
|
|
}
|
|
|
|
func NewLLndkStubLibrary() *Module {
|
|
module, library := NewLibrary(android.DeviceSupported)
|
|
library.BuildOnlyShared()
|
|
module.stl = nil
|
|
module.sanitize = nil
|
|
library.StripProperties.Strip.None = BoolPtr(true)
|
|
|
|
stub := &llndkStubDecorator{
|
|
libraryDecorator: library,
|
|
}
|
|
stub.Properties.Vendor_available = BoolPtr(true)
|
|
module.compiler = stub
|
|
module.linker = stub
|
|
module.installer = nil
|
|
|
|
module.AddProperties(
|
|
&module.Properties,
|
|
&stub.Properties,
|
|
&library.MutatedProperties,
|
|
&library.flagExporter.Properties)
|
|
|
|
return module
|
|
}
|
|
|
|
// llndk_library creates a stub llndk shared library based on the provided
|
|
// version file. Example:
|
|
//
|
|
// llndk_library {
|
|
// name: "libfoo",
|
|
// symbol_file: "libfoo.map.txt",
|
|
// export_include_dirs: ["include_vndk"],
|
|
// }
|
|
func LlndkLibraryFactory() android.Module {
|
|
module := NewLLndkStubLibrary()
|
|
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
|
|
return module
|
|
}
|
|
|
|
type llndkHeadersDecorator struct {
|
|
*libraryDecorator
|
|
}
|
|
|
|
func (headers *llndkHeadersDecorator) Name(name string) string {
|
|
return name + llndkHeadersSuffix
|
|
}
|
|
|
|
// llndk_headers contains a set of c/c++ llndk headers files which are imported
|
|
// by other soongs cc modules.
|
|
func llndkHeadersFactory() android.Module {
|
|
module, library := NewLibrary(android.DeviceSupported)
|
|
library.HeaderOnly()
|
|
|
|
decorator := &llndkHeadersDecorator{
|
|
libraryDecorator: library,
|
|
}
|
|
|
|
module.compiler = nil
|
|
module.linker = decorator
|
|
module.installer = nil
|
|
|
|
module.AddProperties(
|
|
&module.Properties,
|
|
&library.MutatedProperties,
|
|
&library.flagExporter.Properties)
|
|
|
|
module.Init()
|
|
|
|
return module
|
|
}
|
|
|
|
func init() {
|
|
android.RegisterModuleType("llndk_library", LlndkLibraryFactory)
|
|
android.RegisterModuleType("llndk_headers", llndkHeadersFactory)
|
|
}
|