Merge "Allow platform modules to link to vendor public libraries"
This commit is contained in:
commit
01b715e94e
|
@ -163,6 +163,8 @@ bootstrap_go_package {
|
|||
"cc/kernel_headers.go",
|
||||
|
||||
"cc/genrule.go",
|
||||
|
||||
"cc/vendor_public_library.go",
|
||||
],
|
||||
testSrcs: [
|
||||
"cc/cc_test.go",
|
||||
|
|
|
@ -36,6 +36,7 @@ func androidMakeVarsProvider(ctx MakeVarsContext) {
|
|||
// Interface for other packages to use to declare make variables
|
||||
type MakeVarsContext interface {
|
||||
Config() Config
|
||||
SingletonContext() SingletonContext
|
||||
|
||||
// Verify the make variable matches the Soong version, fail the build
|
||||
// if it does not. If the make variable is empty, just set it.
|
||||
|
@ -230,6 +231,10 @@ func (c *makeVarsContext) Config() Config {
|
|||
return c.config
|
||||
}
|
||||
|
||||
func (c *makeVarsContext) SingletonContext() SingletonContext {
|
||||
return c.ctx
|
||||
}
|
||||
|
||||
func (c *makeVarsContext) Eval(ninjaStr string) (string, error) {
|
||||
return c.ctx.Eval(c.pctx, ninjaStr)
|
||||
}
|
||||
|
|
|
@ -177,6 +177,7 @@ type Module interface {
|
|||
InstallInData() bool
|
||||
InstallInSanitizerDir() bool
|
||||
SkipInstall()
|
||||
ExportedToMake() bool
|
||||
|
||||
AddProperties(props ...interface{})
|
||||
GetProperties() []interface{}
|
||||
|
@ -507,6 +508,10 @@ func (a *ModuleBase) SkipInstall() {
|
|||
a.commonProperties.SkipInstall = true
|
||||
}
|
||||
|
||||
func (a *ModuleBase) ExportedToMake() bool {
|
||||
return a.commonProperties.NamespaceExportedToMake
|
||||
}
|
||||
|
||||
func (a *ModuleBase) computeInstallDeps(
|
||||
ctx blueprint.ModuleContext) Paths {
|
||||
|
||||
|
|
|
@ -383,3 +383,18 @@ func (c *ndkPrebuiltStlLinker) AndroidMk(ctx AndroidMkContext, ret *android.Andr
|
|||
fmt.Fprintln(w, "LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES := false")
|
||||
})
|
||||
}
|
||||
|
||||
func (c *vendorPublicLibraryStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||
ret.Class = "SHARED_LIBRARIES"
|
||||
ret.SubName = vendorPublicLibrarySuffix
|
||||
|
||||
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
|
||||
c.libraryDecorator.androidMkWriteExportedFlags(w)
|
||||
|
||||
fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+outputFile.Ext())
|
||||
fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
|
||||
fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
|
||||
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
|
||||
fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
|
||||
})
|
||||
}
|
||||
|
|
14
cc/cc.go
14
cc/cc.go
|
@ -922,6 +922,16 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||
}
|
||||
} else if ctx.useVndk() && inList(entry, llndkLibraries) {
|
||||
nonvariantLibs = append(nonvariantLibs, entry+llndkLibrarySuffix)
|
||||
} else if (ctx.Platform() || ctx.ProductSpecific()) && inList(entry, vendorPublicLibraries) {
|
||||
vendorPublicLib := entry + vendorPublicLibrarySuffix
|
||||
if actx.OtherModuleExists(vendorPublicLib) {
|
||||
nonvariantLibs = append(nonvariantLibs, vendorPublicLib)
|
||||
} else {
|
||||
// This can happen if vendor_public_library module is defined in a
|
||||
// namespace that isn't visible to the current module. In that case,
|
||||
// link to the original library.
|
||||
nonvariantLibs = append(nonvariantLibs, entry)
|
||||
}
|
||||
} else {
|
||||
nonvariantLibs = append(nonvariantLibs, entry)
|
||||
}
|
||||
|
@ -1306,14 +1316,18 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||
switch depTag {
|
||||
case sharedDepTag, sharedExportDepTag, lateSharedDepTag:
|
||||
libName := strings.TrimSuffix(depName, llndkLibrarySuffix)
|
||||
libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix)
|
||||
libName = strings.TrimPrefix(libName, "prebuilt_")
|
||||
isLLndk := inList(libName, llndkLibraries)
|
||||
isVendorPublicLib := inList(libName, vendorPublicLibraries)
|
||||
var makeLibName string
|
||||
bothVendorAndCoreVariantsExist := ccDep.hasVendorVariant() || isLLndk
|
||||
if c.useVndk() && bothVendorAndCoreVariantsExist {
|
||||
// The vendor module in Make will have been renamed to not conflict with the core
|
||||
// module, so update the dependency name here accordingly.
|
||||
makeLibName = libName + vendorSuffix
|
||||
} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
|
||||
makeLibName = libName + vendorPublicLibrarySuffix
|
||||
} else {
|
||||
makeLibName = libName
|
||||
}
|
||||
|
|
103
cc/cc_test.go
103
cc/cc_test.go
|
@ -56,15 +56,18 @@ func createTestContext(t *testing.T, config android.Config, bp string) *android.
|
|||
ctx := android.NewTestArchContext()
|
||||
ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
|
||||
ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
|
||||
ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory))
|
||||
ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(toolchainLibraryFactory))
|
||||
ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory))
|
||||
ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory))
|
||||
ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
|
||||
ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(objectFactory))
|
||||
ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(genrule.FileGroupFactory))
|
||||
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
||||
ctx.BottomUp("image", vendorMutator).Parallel()
|
||||
ctx.BottomUp("link", linkageMutator).Parallel()
|
||||
ctx.BottomUp("vndk", vndkMutator).Parallel()
|
||||
ctx.BottomUp("begin", beginMutator).Parallel()
|
||||
})
|
||||
ctx.Register()
|
||||
|
||||
|
@ -115,6 +118,34 @@ func createTestContext(t *testing.T, config android.Config, bp string) *android.
|
|||
name: "libdl",
|
||||
symbol_file: "",
|
||||
}
|
||||
cc_library {
|
||||
name: "libc++_static",
|
||||
no_libgcc: true,
|
||||
nocrt: true,
|
||||
system_shared_libs: [],
|
||||
stl: "none",
|
||||
vendor_available: true,
|
||||
}
|
||||
cc_library {
|
||||
name: "libc++",
|
||||
no_libgcc: true,
|
||||
nocrt: true,
|
||||
system_shared_libs: [],
|
||||
stl: "none",
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
support_system_process: true,
|
||||
},
|
||||
}
|
||||
cc_library {
|
||||
name: "libunwind_llvm",
|
||||
no_libgcc: true,
|
||||
nocrt: true,
|
||||
system_shared_libs: [],
|
||||
stl: "none",
|
||||
vendor_available: true,
|
||||
}
|
||||
|
||||
cc_object {
|
||||
name: "crtbegin_so",
|
||||
|
@ -1077,16 +1108,20 @@ func TestStaticLibDepReordering(t *testing.T) {
|
|||
cc_library {
|
||||
name: "a",
|
||||
static_libs: ["b", "c", "d"],
|
||||
stl: "none",
|
||||
}
|
||||
cc_library {
|
||||
name: "b",
|
||||
stl: "none",
|
||||
}
|
||||
cc_library {
|
||||
name: "c",
|
||||
static_libs: ["b"],
|
||||
stl: "none",
|
||||
}
|
||||
cc_library {
|
||||
name: "d",
|
||||
stl: "none",
|
||||
}
|
||||
|
||||
`)
|
||||
|
@ -1111,13 +1146,16 @@ func TestStaticLibDepReorderingWithShared(t *testing.T) {
|
|||
cc_library {
|
||||
name: "a",
|
||||
static_libs: ["b", "c"],
|
||||
stl: "none",
|
||||
}
|
||||
cc_library {
|
||||
name: "b",
|
||||
stl: "none",
|
||||
}
|
||||
cc_library {
|
||||
name: "c",
|
||||
shared_libs: ["b"],
|
||||
stl: "none",
|
||||
}
|
||||
|
||||
`)
|
||||
|
@ -1249,3 +1287,68 @@ func TestCompilerFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVendorPublicLibraries(t *testing.T) {
|
||||
ctx := testCc(t, `
|
||||
cc_library_headers {
|
||||
name: "libvendorpublic_headers",
|
||||
export_include_dirs: ["my_include"],
|
||||
}
|
||||
vendor_public_library {
|
||||
name: "libvendorpublic",
|
||||
symbol_file: "",
|
||||
export_public_headers: ["libvendorpublic_headers"],
|
||||
}
|
||||
cc_library {
|
||||
name: "libvendorpublic",
|
||||
srcs: ["foo.c"],
|
||||
vendor: true,
|
||||
no_libgcc: true,
|
||||
nocrt: true,
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libsystem",
|
||||
shared_libs: ["libvendorpublic"],
|
||||
vendor: false,
|
||||
srcs: ["foo.c"],
|
||||
no_libgcc: true,
|
||||
nocrt: true,
|
||||
}
|
||||
cc_library {
|
||||
name: "libvendor",
|
||||
shared_libs: ["libvendorpublic"],
|
||||
vendor: true,
|
||||
srcs: ["foo.c"],
|
||||
no_libgcc: true,
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
|
||||
variant := "android_arm64_armv8-a_core_shared"
|
||||
|
||||
// test if header search paths are correctly added
|
||||
// _static variant is used since _shared reuses *.o from the static variant
|
||||
cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
|
||||
cflags := cc.Args["cFlags"]
|
||||
if !strings.Contains(cflags, "-Imy_include") {
|
||||
t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
|
||||
}
|
||||
|
||||
// test if libsystem is linked to the stub
|
||||
ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
|
||||
libflags := ld.Args["libFlags"]
|
||||
stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
|
||||
if !strings.Contains(libflags, stubPaths[0].String()) {
|
||||
t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
|
||||
}
|
||||
|
||||
// test if libvendor is linked to the real shared lib
|
||||
ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
|
||||
libflags = ld.Args["libFlags"]
|
||||
stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
|
||||
if !strings.Contains(libflags, stubPaths[0].String()) {
|
||||
t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -100,6 +100,21 @@ func makeVarsProvider(ctx android.MakeVarsContext) {
|
|||
ctx.Strict("LLNDK_LIBRARIES", strings.Join(llndkLibraries, " "))
|
||||
ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(vndkPrivateLibraries, " "))
|
||||
|
||||
// Filter vendor_public_library that are exported to make
|
||||
exportedVendorPublicLibraries := []string{}
|
||||
ctx.SingletonContext().VisitAllModules(func(module android.Module) {
|
||||
if ccModule, ok := module.(*Module); ok {
|
||||
baseName := ccModule.BaseModuleName()
|
||||
if inList(baseName, vendorPublicLibraries) && module.ExportedToMake() {
|
||||
if !inList(baseName, exportedVendorPublicLibraries) {
|
||||
exportedVendorPublicLibraries = append(exportedVendorPublicLibraries, baseName)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
sort.Strings(exportedVendorPublicLibraries)
|
||||
ctx.Strict("VENDOR_PUBLIC_LIBRARIES", strings.Join(exportedVendorPublicLibraries, " "))
|
||||
|
||||
sort.Strings(lsdumpPaths)
|
||||
ctx.Strict("LSDUMP_PATHS", strings.Join(lsdumpPaths, " "))
|
||||
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
// Copyright 2018 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"
|
||||
"sync"
|
||||
|
||||
"android/soong/android"
|
||||
)
|
||||
|
||||
var (
|
||||
vendorPublicLibrarySuffix = ".vendorpublic"
|
||||
|
||||
vendorPublicLibraries = []string{}
|
||||
vendorPublicLibrariesLock sync.Mutex
|
||||
)
|
||||
|
||||
// Creates a stub shared library for a vendor public library. Vendor public libraries
|
||||
// are vendor libraries (owned by them and installed to /vendor partition) that are
|
||||
// exposed to Android apps via JNI. The libraries are made public by being listed in
|
||||
// /vendor/etc/public.libraries.txt.
|
||||
//
|
||||
// This stub library is a build-time only artifact that provides symbols that are
|
||||
// exposed from a vendor public library.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// vendor_public_library {
|
||||
// name: "libfoo",
|
||||
// symbol_file: "libfoo.map.txt",
|
||||
// export_public_headers: ["libfoo_headers"],
|
||||
// }
|
||||
//
|
||||
// cc_headers {
|
||||
// name: "libfoo_headers",
|
||||
// export_include_dirs: ["include"],
|
||||
// }
|
||||
//
|
||||
type vendorPublicLibraryProperties struct {
|
||||
// Relative path to the symbol map.
|
||||
Symbol_file *string
|
||||
|
||||
// Whether the system library uses symbol versions.
|
||||
Unversioned *bool
|
||||
|
||||
// list of header libs to re-export include directories from.
|
||||
Export_public_headers []string `android:"arch_variant"`
|
||||
}
|
||||
|
||||
type vendorPublicLibraryStubDecorator struct {
|
||||
*libraryDecorator
|
||||
|
||||
Properties vendorPublicLibraryProperties
|
||||
|
||||
versionScriptPath android.ModuleGenPath
|
||||
}
|
||||
|
||||
func (stub *vendorPublicLibraryStubDecorator) Name(name string) string {
|
||||
return name + vendorPublicLibrarySuffix
|
||||
}
|
||||
|
||||
func (stub *vendorPublicLibraryStubDecorator) compilerInit(ctx BaseModuleContext) {
|
||||
stub.baseCompiler.compilerInit(ctx)
|
||||
|
||||
name := ctx.baseModuleName()
|
||||
if strings.HasSuffix(name, vendorPublicLibrarySuffix) {
|
||||
ctx.PropertyErrorf("name", "Do not append %q manually, just use the base name", vendorPublicLibrarySuffix)
|
||||
}
|
||||
|
||||
vendorPublicLibrariesLock.Lock()
|
||||
defer vendorPublicLibrariesLock.Unlock()
|
||||
for _, lib := range vendorPublicLibraries {
|
||||
if lib == name {
|
||||
return
|
||||
}
|
||||
}
|
||||
vendorPublicLibraries = append(vendorPublicLibraries, name)
|
||||
}
|
||||
|
||||
func (stub *vendorPublicLibraryStubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
|
||||
flags = stub.baseCompiler.compilerFlags(ctx, flags, deps)
|
||||
return addStubLibraryCompilerFlags(flags)
|
||||
}
|
||||
|
||||
func (stub *vendorPublicLibraryStubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
|
||||
objs, versionScript := compileStubLibrary(ctx, flags, String(stub.Properties.Symbol_file), "current", "")
|
||||
stub.versionScriptPath = versionScript
|
||||
return objs
|
||||
}
|
||||
|
||||
func (stub *vendorPublicLibraryStubDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
||||
headers := stub.Properties.Export_public_headers
|
||||
deps.HeaderLibs = append(deps.HeaderLibs, headers...)
|
||||
deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders, headers...)
|
||||
return deps
|
||||
}
|
||||
|
||||
func (stub *vendorPublicLibraryStubDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||
stub.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), vendorPublicLibrarySuffix)
|
||||
return stub.libraryDecorator.linkerFlags(ctx, flags)
|
||||
}
|
||||
|
||||
func (stub *vendorPublicLibraryStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps,
|
||||
objs Objects) android.Path {
|
||||
if !Bool(stub.Properties.Unversioned) {
|
||||
linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String()
|
||||
flags.LdFlags = append(flags.LdFlags, linkerScriptFlag)
|
||||
}
|
||||
return stub.libraryDecorator.link(ctx, flags, deps, objs)
|
||||
}
|
||||
|
||||
func vendorPublicLibraryFactory() android.Module {
|
||||
module, library := NewLibrary(android.DeviceSupported)
|
||||
library.BuildOnlyShared()
|
||||
module.stl = nil
|
||||
module.sanitize = nil
|
||||
library.StripProperties.Strip.None = BoolPtr(true)
|
||||
|
||||
stub := &vendorPublicLibraryStubDecorator{
|
||||
libraryDecorator: library,
|
||||
}
|
||||
module.compiler = stub
|
||||
module.linker = stub
|
||||
module.installer = nil
|
||||
|
||||
module.AddProperties(
|
||||
&stub.Properties,
|
||||
&library.MutatedProperties,
|
||||
&library.flagExporter.Properties)
|
||||
|
||||
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
|
||||
return module
|
||||
}
|
||||
|
||||
func init() {
|
||||
android.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory)
|
||||
}
|
Loading…
Reference in New Issue