Split /system and /vendor modules, allow multi-installation
Nothing changes if BOARD_VNDK_VERSION isn't set. When the VNDK is enabled (BOARD_VNDK_VERSION in Make), this will split /system and /vendor modules into two different variant spaces that can't link to each other. There are a few interfaces between the two variant spaces: The `llndk_library` stubs will be available in the /vendor variant, but won't be installed, so at runtime the /system variant will be used. Setting `vendor_available: true` will split a module into both variants. The /system (or "core") variant will compile just like today. The /vendor ("vendor") variant will compile against everything else in the vendor space (so LL-NDK instead of libc/liblog/etc). There will be two copies of these libraries installed onto the final device. Since the available runtime interfaces for vendor modules may be reduced, and your dependencies may not expose their private interfaces, we allow the vendor variants to reduce their compilation set, and export a different set of headers: cc_library { name: "libfoo", srcs: ["common.cpp", "private_impl.cpp"], export_include_dirs: ["include"], target: { vendor: { export_include_dirs: ["include_vndk"], exclude_srcs: ["private_impl.cpp"], srcs: ["vendor_only.cpp"], }, }, } So the "core" variant would compile with both "common.cpp" and "private_impl.cpp", and export "include". The "vendor" variant would compile "common.cpp" and "vendor_only.cpp", and export "include_vndk". Bug: 36426473 Bug: 36079834 Test: out/soong/build.ninja, out/soong/Android- only changes due to _core addition and .llndk -> .vendor Test: attempt to compile with BOARD_VNDK_VERSION:=current Change-Id: Idef28764043bf6c33dc0d2e7e2026c38867ff769
This commit is contained in:
parent
01a90597bc
commit
4416e5db69
|
@ -232,6 +232,7 @@ cc_defaults {
|
|||
toolchain_library {
|
||||
name: "libatomic",
|
||||
defaults: ["linux_bionic_supported"],
|
||||
vendor_available: true,
|
||||
arch: {
|
||||
arm: {
|
||||
instruction_set: "arm",
|
||||
|
@ -242,6 +243,7 @@ toolchain_library {
|
|||
toolchain_library {
|
||||
name: "libgcc",
|
||||
defaults: ["linux_bionic_supported"],
|
||||
vendor_available: true,
|
||||
arch: {
|
||||
arm: {
|
||||
instruction_set: "arm",
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
type AndroidMkContext interface {
|
||||
Target() android.Target
|
||||
subAndroidMk(*android.AndroidMkData, interface{})
|
||||
vndk() bool
|
||||
}
|
||||
|
||||
type subAndroidMkProvider interface {
|
||||
|
@ -56,13 +57,16 @@ func (c *Module) AndroidMk() (ret android.AndroidMkData, err error) {
|
|||
if len(c.Properties.AndroidMkSharedLibs) > 0 {
|
||||
fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES := "+strings.Join(c.Properties.AndroidMkSharedLibs, " "))
|
||||
}
|
||||
if c.Target().Os == android.Android && c.Properties.Sdk_version != "" {
|
||||
if c.Target().Os == android.Android && c.Properties.Sdk_version != "" && !c.vndk() {
|
||||
fmt.Fprintln(w, "LOCAL_SDK_VERSION := "+c.Properties.Sdk_version)
|
||||
fmt.Fprintln(w, "LOCAL_NDK_STL_VARIANT := none")
|
||||
} else {
|
||||
// These are already included in LOCAL_SHARED_LIBRARIES
|
||||
fmt.Fprintln(w, "LOCAL_CXX_STL := none")
|
||||
}
|
||||
if c.vndk() {
|
||||
fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
|
@ -74,6 +78,10 @@ func (c *Module) AndroidMk() (ret android.AndroidMkData, err error) {
|
|||
c.subAndroidMk(&ret, c.linker)
|
||||
c.subAndroidMk(&ret, c.installer)
|
||||
|
||||
if c.vndk() {
|
||||
ret.SubName += ".vendor"
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
@ -118,6 +126,8 @@ func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.An
|
|||
if host {
|
||||
fmt.Fprintln(w, "LOCAL_MODULE_HOST_OS :=", ctx.Target().Os.String())
|
||||
fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
|
||||
} else if ctx.vndk() {
|
||||
fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
|
||||
}
|
||||
|
||||
library.androidMkWriteExportedFlags(w)
|
||||
|
@ -301,7 +311,7 @@ func (c *stubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkDa
|
|||
|
||||
func (c *llndkStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||
ret.Class = "SHARED_LIBRARIES"
|
||||
ret.SubName = llndkLibrarySuffix
|
||||
ret.SubName = ".vendor"
|
||||
|
||||
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
||||
c.libraryDecorator.androidMkWriteExportedFlags(w)
|
||||
|
@ -311,6 +321,7 @@ func (c *llndkStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.Androi
|
|||
fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
|
||||
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
|
||||
fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
|
||||
fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
|
|
@ -108,7 +108,7 @@ func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||
deps = binary.baseLinker.linkerDeps(ctx, deps)
|
||||
if ctx.toolchain().Bionic() {
|
||||
if !Bool(binary.baseLinker.Properties.Nocrt) {
|
||||
if !ctx.sdk() && !ctx.vndk() {
|
||||
if !ctx.sdk() {
|
||||
if binary.static() {
|
||||
deps.CrtBegin = "crtbegin_static"
|
||||
} else {
|
||||
|
|
85
cc/cc.go
85
cc/cc.go
|
@ -35,6 +35,7 @@ func init() {
|
|||
|
||||
android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
||||
ctx.BottomUp("link", linkageMutator).Parallel()
|
||||
ctx.BottomUp("image", vendorMutator).Parallel()
|
||||
ctx.BottomUp("ndk_api", ndkApiMutator).Parallel()
|
||||
ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel()
|
||||
ctx.BottomUp("begin", beginMutator).Parallel()
|
||||
|
@ -143,9 +144,24 @@ type BaseProperties struct {
|
|||
// cppflags, conlyflags, ldflags, or include_dirs
|
||||
No_default_compiler_flags *bool
|
||||
|
||||
// whether this module should be allowed to install onto /vendor as
|
||||
// well as /system. The two variants will be built separately, one
|
||||
// like normal, and the other limited to the set of libraries and
|
||||
// headers that are exposed to /vendor modules.
|
||||
//
|
||||
// The vendor variant may be used with a different (newer) /system,
|
||||
// so it shouldn't have any unversioned runtime dependencies, or
|
||||
// make assumptions about the system that may not be true in the
|
||||
// future.
|
||||
//
|
||||
// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
|
||||
Vendor_available *bool
|
||||
|
||||
AndroidMkSharedLibs []string `blueprint:"mutated"`
|
||||
HideFromMake bool `blueprint:"mutated"`
|
||||
PreventInstall bool `blueprint:"mutated"`
|
||||
|
||||
UseVndk bool `blueprint:"mutated"`
|
||||
}
|
||||
|
||||
type UnusedProperties struct {
|
||||
|
@ -320,6 +336,10 @@ func (c *Module) isDependencyRoot() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (c *Module) vndk() bool {
|
||||
return c.Properties.UseVndk
|
||||
}
|
||||
|
||||
type baseModuleContext struct {
|
||||
android.BaseContext
|
||||
moduleContextImpl
|
||||
|
@ -335,6 +355,12 @@ type moduleContext struct {
|
|||
moduleContextImpl
|
||||
}
|
||||
|
||||
// Vendor returns true for vendor modules so that they get installed onto the
|
||||
// correct partition
|
||||
func (ctx *moduleContext) Vendor() bool {
|
||||
return ctx.ModuleContext.Vendor() || ctx.moduleContextImpl.mod.Properties.UseVndk
|
||||
}
|
||||
|
||||
type moduleContextImpl struct {
|
||||
mod *Module
|
||||
ctx BaseModuleContext
|
||||
|
@ -371,7 +397,7 @@ func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
|
|||
}
|
||||
|
||||
func (ctx *moduleContextImpl) sdk() bool {
|
||||
if ctx.ctx.Device() {
|
||||
if ctx.ctx.Device() && !ctx.vndk() {
|
||||
return ctx.mod.Properties.Sdk_version != ""
|
||||
}
|
||||
return false
|
||||
|
@ -389,7 +415,7 @@ func (ctx *moduleContextImpl) sdkVersion() string {
|
|||
}
|
||||
|
||||
func (ctx *moduleContextImpl) vndk() bool {
|
||||
return ctx.ctx.Os() == android.Android && ctx.ctx.Vendor() && ctx.ctx.DeviceConfig().CompileVndk()
|
||||
return ctx.mod.vndk()
|
||||
}
|
||||
|
||||
func (ctx *moduleContextImpl) selectedStl() string {
|
||||
|
@ -772,6 +798,10 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||
// Host code is not restricted
|
||||
return
|
||||
}
|
||||
if from.Properties.UseVndk {
|
||||
// Vendor code is already limited by the vendor mutator
|
||||
return
|
||||
}
|
||||
if from.Properties.Sdk_version == "" {
|
||||
// Platform code can link to anything
|
||||
return
|
||||
|
@ -1060,6 +1090,57 @@ func DefaultsFactory(props ...interface{}) (blueprint.Module, []interface{}) {
|
|||
return android.InitDefaultsModule(module, module, props...)
|
||||
}
|
||||
|
||||
const (
|
||||
// coreMode is the variant used for framework-private libraries, or
|
||||
// SDK libraries. (which framework-private libraries can use)
|
||||
coreMode = "core"
|
||||
|
||||
// vendorMode is the variant used for /vendor code that compiles
|
||||
// against the VNDK.
|
||||
vendorMode = "vendor"
|
||||
)
|
||||
|
||||
func vendorMutator(mctx android.BottomUpMutatorContext) {
|
||||
if mctx.Os() != android.Android {
|
||||
return
|
||||
}
|
||||
|
||||
m, ok := mctx.Module().(*Module)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if Bool(m.Properties.Vendor_available) && mctx.Vendor() {
|
||||
mctx.PropertyErrorf("vendor_available",
|
||||
"doesn't make sense at the same time as `vendor: true` or `proprietary: true`")
|
||||
return
|
||||
}
|
||||
|
||||
if !mctx.DeviceConfig().CompileVndk() {
|
||||
// If the device isn't compiling against the VNDK, we always
|
||||
// use the core mode.
|
||||
mctx.CreateVariations(coreMode)
|
||||
} else if _, ok := m.linker.(*llndkStubDecorator); ok {
|
||||
// LL-NDK stubs only exist in the vendor variant, since the
|
||||
// real libraries will be used in the core variant.
|
||||
mctx.CreateVariations(vendorMode)
|
||||
} else if Bool(m.Properties.Vendor_available) {
|
||||
// This will be available in both /system and /vendor
|
||||
mod := mctx.CreateVariations(coreMode, vendorMode)
|
||||
mod[1].(*Module).Properties.UseVndk = true
|
||||
} else if mctx.Vendor() && m.Properties.Sdk_version == "" {
|
||||
// This will be available in /vendor only
|
||||
mod := mctx.CreateVariations(vendorMode)
|
||||
mod[0].(*Module).Properties.UseVndk = true
|
||||
} else {
|
||||
// This is either in /system (or similar: /data), or is a
|
||||
// modules built with the NDK. Modules built with the NDK
|
||||
// will be restricted using the existing link type checks.
|
||||
mctx.CreateVariations(coreMode)
|
||||
}
|
||||
}
|
||||
|
||||
// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
|
||||
// modifies the slice contents in place, and returns a subslice of the original slice
|
||||
func lastUniqueElements(list []string) []string {
|
||||
|
|
|
@ -113,6 +113,18 @@ type BaseCompilerProperties struct {
|
|||
// release builds
|
||||
Cflags []string `android:"arch_variant"`
|
||||
} `android:"arch_variant"`
|
||||
|
||||
Target struct {
|
||||
Vendor struct {
|
||||
// list of source files that should only be used in the
|
||||
// vendor variant of the C/C++ module.
|
||||
Srcs []string
|
||||
|
||||
// list of source files that should not be used to
|
||||
// build the vendor variant of the C/C++ module.
|
||||
Exclude_srcs []string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewBaseCompiler() *baseCompiler {
|
||||
|
@ -429,6 +441,14 @@ func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathD
|
|||
pathDeps := deps.GeneratedHeaders
|
||||
pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
|
||||
|
||||
if ctx.vndk() {
|
||||
compiler.Properties.Srcs = append(compiler.Properties.Srcs,
|
||||
compiler.Properties.Target.Vendor.Srcs...)
|
||||
|
||||
compiler.Properties.Exclude_srcs = append(compiler.Properties.Exclude_srcs,
|
||||
compiler.Properties.Target.Vendor.Exclude_srcs...)
|
||||
}
|
||||
|
||||
srcs := ctx.ExpandSources(compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
|
||||
srcs = append(srcs, deps.GeneratedSources...)
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@ func (installer *baseInstaller) installDir(ctx ModuleContext) android.OutputPath
|
|||
if !ctx.Host() && !ctx.Arch().Native {
|
||||
subDir = filepath.Join(subDir, ctx.Arch().ArchType.String())
|
||||
}
|
||||
if installer.location == InstallInData && ctx.vndk() {
|
||||
subDir = filepath.Join(subDir, "vendor")
|
||||
}
|
||||
return android.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path, installer.relative)
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,16 @@ type FlagExporterProperties struct {
|
|||
// be added to the include path (using -I) for this module and any module that links
|
||||
// against this module
|
||||
Export_include_dirs []string `android:"arch_variant"`
|
||||
|
||||
Target struct {
|
||||
Vendor struct {
|
||||
// list of exported include directories, like
|
||||
// export_include_dirs, that will be applied to the
|
||||
// vendor variant of this library. This will overwrite
|
||||
// any other declarations.
|
||||
Export_include_dirs []string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -144,8 +154,16 @@ type flagExporter struct {
|
|||
flagsDeps android.Paths
|
||||
}
|
||||
|
||||
func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths {
|
||||
if ctx.Vendor() && f.Properties.Target.Vendor.Export_include_dirs != nil {
|
||||
return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Export_include_dirs)
|
||||
} else {
|
||||
return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) {
|
||||
includeDirs := android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
|
||||
includeDirs := f.exportedIncludes(ctx)
|
||||
for _, dir := range includeDirs.Strings() {
|
||||
f.flags = append(f.flags, inc+dir)
|
||||
}
|
||||
|
@ -277,7 +295,7 @@ func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Fla
|
|||
}
|
||||
|
||||
func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||
exportIncludeDirs := android.PathsForModuleSrc(ctx, library.flagExporter.Properties.Export_include_dirs)
|
||||
exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
|
||||
if len(exportIncludeDirs) > 0 {
|
||||
flags.GlobalFlags = append(flags.GlobalFlags, includeDirsToFlags(exportIncludeDirs))
|
||||
}
|
||||
|
@ -369,7 +387,7 @@ func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||
deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
|
||||
} else if library.shared() {
|
||||
if ctx.toolchain().Bionic() && !Bool(library.baseLinker.Properties.Nocrt) {
|
||||
if !ctx.sdk() && !ctx.vndk() {
|
||||
if !ctx.sdk() {
|
||||
deps.CrtBegin = "crtbegin_so"
|
||||
deps.CrtEnd = "crtend_so"
|
||||
} else {
|
||||
|
|
|
@ -143,7 +143,7 @@ func (linker *baseLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
|||
if linker.Properties.System_shared_libs != nil {
|
||||
deps.LateSharedLibs = append(deps.LateSharedLibs,
|
||||
linker.Properties.System_shared_libs...)
|
||||
} else if !ctx.sdk() {
|
||||
} else if !ctx.sdk() && !ctx.vndk() {
|
||||
deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +154,9 @@ func (linker *baseLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
|||
"libm",
|
||||
)
|
||||
}
|
||||
if ctx.vndk() {
|
||||
deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.Windows() {
|
||||
|
|
|
@ -57,8 +57,6 @@ func makeVarsProvider(ctx android.MakeVarsContext) {
|
|||
} else {
|
||||
ctx.Strict("BOARD_VNDK_VERSION", "")
|
||||
}
|
||||
ctx.Strict("VNDK_LIBRARIES", strings.Join(config.VndkLibraries(), " "))
|
||||
ctx.Strict("LLNDK_LIBRARIES", strings.Join(config.LLndkLibraries(), " "))
|
||||
|
||||
ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS", asanCflags)
|
||||
ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS", asanLdflags)
|
||||
|
|
Loading…
Reference in New Issue