diff --git a/Android.bp b/Android.bp index 6d2b80494..a296da1a7 100644 --- a/Android.bp +++ b/Android.bp @@ -135,6 +135,7 @@ bootstrap_go_package { "cc/tidy.go", "cc/util.go", "cc/vndk.go", + "cc/vndk_prebuilt.go", "cc/cmakelists.go", "cc/compiler.go", diff --git a/android/config.go b/android/config.go index a4624c7a6..0eebb5fbd 100644 --- a/android/config.go +++ b/android/config.go @@ -632,11 +632,12 @@ func (c *deviceConfig) VendorPath() string { return "vendor" } -func (c *deviceConfig) CompileVndk() bool { - if c.config.ProductVariables.DeviceVndkVersion == nil { - return false - } - return *c.config.ProductVariables.DeviceVndkVersion == "current" +func (c *deviceConfig) VndkVersion() string { + return String(c.config.ProductVariables.DeviceVndkVersion) +} + +func (c *deviceConfig) ExtraVndkVersions() []string { + return c.config.ProductVariables.ExtraVndkVersions } func (c *deviceConfig) BtConfigIncludeDir() string { diff --git a/android/variable.go b/android/variable.go index e8d5c69bb..a3920a1cb 100644 --- a/android/variable.go +++ b/android/variable.go @@ -192,6 +192,8 @@ type productVariables struct { DeviceKernelHeaders []string `json:",omitempty"` DistDir *string `json:",omitempty"` + + ExtraVndkVersions []string `json:",omitempty"` } func boolPtr(v bool) *bool { diff --git a/cc/androidmk.go b/cc/androidmk.go index 44e977fa3..6d1c44f49 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -348,3 +348,24 @@ func (c *llndkStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.Androi fmt.Fprintln(w, "LOCAL_USE_VNDK := true") }) } + +func (c *vndkPrebuiltLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { + ret.Class = "SHARED_LIBRARIES" + + ret.SubName = vndkSuffix + c.version() + + ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { + c.libraryDecorator.androidMkWriteExportedFlags(w) + + path := c.path.RelPathString() + dir, file := filepath.Split(path) + stem := strings.TrimSuffix(file, filepath.Ext(file)) + fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false") + fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=") + fmt.Fprintln(w, "LOCAL_USE_VNDK := true") + fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+outputFile.Ext()) + fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+filepath.Ext(file)) + fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir)) + fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem) + }) +} \ No newline at end of file diff --git a/cc/cc.go b/cc/cc.go index 891dccb05..c31cf0426 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1372,7 +1372,7 @@ func vendorMutator(mctx android.BottomUpMutatorContext) { if genrule, ok := mctx.Module().(*genrule.Module); ok { if props, ok := genrule.Extra.(*VendorProperties); ok { - if !mctx.DeviceConfig().CompileVndk() { + if mctx.DeviceConfig().VndkVersion() == "" { mctx.CreateVariations(coreMode) } else if Bool(props.Vendor_available) { mctx.CreateVariations(coreMode, vendorMode) @@ -1408,7 +1408,7 @@ func vendorMutator(mctx android.BottomUpMutatorContext) { } } - if !mctx.DeviceConfig().CompileVndk() { + if mctx.DeviceConfig().VndkVersion() == "" { // If the device isn't compiling against the VNDK, we always // use the core mode. mctx.CreateVariations(coreMode) @@ -1419,6 +1419,12 @@ func vendorMutator(mctx android.BottomUpMutatorContext) { } else if _, ok := m.linker.(*llndkHeadersDecorator); ok { // ... and LL-NDK headers as well mctx.CreateVariations(vendorMode) + } else if _, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok { + // Make vendor variants only for the versions in BOARD_VNDK_VERSION and + // PRODUCT_EXTRA_VNDK_VERSIONS. + mod := mctx.CreateVariations(vendorMode) + vendor := mod[0].(*Module) + vendor.Properties.UseVndk = true } else if m.hasVendorVariant() { // This will be available in both /system and /vendor // or a /system directory that is available to vendor. diff --git a/cc/vndk.go b/cc/vndk.go index 03297df21..a61b74c90 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -172,6 +172,5 @@ func vndkMutator(mctx android.BottomUpMutatorContext) { } } } - } } diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go new file mode 100644 index 000000000..a1a164f3f --- /dev/null +++ b/cc/vndk_prebuilt.go @@ -0,0 +1,140 @@ +// 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." +) + +// Creates vndk prebuilts that include the VNDK version. +// +// Example: +// +// vndk_prebuilt_shared { +// name: "libfoo", +// version: "27.1.0", +// vendor_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 that is formated as {SDK_ver}.{Major}.{Minor}. + Version string + + // Prebuilt files for each arch. + Srcs []string `android:"arch_variant"` +} + +type vndkPrebuiltLibraryDecorator struct { + *libraryDecorator + properties vndkPrebuiltProperties +} + +func (p *vndkPrebuiltLibraryDecorator) Name(name string) string { + return name + vndkSuffix + p.version() +} + +func (p *vndkPrebuiltLibraryDecorator) version() string { + return p.properties.Version +} + +func (p *vndkPrebuiltLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { + p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), vndkSuffix+p.version()) + 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 { + if len(p.properties.Srcs) > 0 && p.shared() { + // current VNDK prebuilts are only shared libs. + return p.singleSourcePath(ctx) + } + return nil +} + +func (p *vndkPrebuiltLibraryDecorator) install(ctx ModuleContext, file android.Path) { + if p.shared() { + if ctx.Device() && ctx.useVndk() { + if ctx.isVndkSp() { + p.baseInstaller.subDir = "vndk-sp-" + p.version() + } else if ctx.isVndk() { + p.baseInstaller.subDir = "vndk-" + p.version() + } + } + p.baseInstaller.install(ctx, file) + } +} + +func vndkPrebuiltSharedLibrary() *Module { + module, library := NewLibrary(android.DeviceSupported) + library.BuildOnlyShared() + module.stl = nil + module.sanitize = nil + library.StripProperties.Strip.None = BoolPtr(true) + + prebuilt := &vndkPrebuiltLibraryDecorator{ + libraryDecorator: library, + } + + module.compiler = nil + module.linker = prebuilt + module.installer = prebuilt + + module.AddProperties( + &prebuilt.properties, + ) + + return module +} + +func vndkPrebuiltSharedFactory() android.Module { + module := vndkPrebuiltSharedLibrary() + return module.Init() +} + +func init() { + android.RegisterModuleType("vndk_prebuilt_shared", vndkPrebuiltSharedFactory) +} \ No newline at end of file