Merge changes I3079cb4e,I55a786e9
* changes:
Have pom2mk list all duplicates modules
Have pom2mk include runtime deps too
diff --git a/Android.bp b/Android.bp
index 9162926..ec69df8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -163,6 +163,8 @@
"cc/kernel_headers.go",
"cc/genrule.go",
+
+ "cc/vendor_public_library.go",
],
testSrcs: [
"cc/cc_test.go",
diff --git a/android/makevars.go b/android/makevars.go
index 00a20f5..b6cd571 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -36,6 +36,7 @@
// 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 @@
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)
}
diff --git a/android/module.go b/android/module.go
index 4a8e8ac..1e54470 100644
--- a/android/module.go
+++ b/android/module.go
@@ -177,6 +177,7 @@
InstallInData() bool
InstallInSanitizerDir() bool
SkipInstall()
+ ExportedToMake() bool
AddProperties(props ...interface{})
GetProperties() []interface{}
@@ -507,6 +508,10 @@
a.commonProperties.SkipInstall = true
}
+func (a *ModuleBase) ExportedToMake() bool {
+ return a.commonProperties.NamespaceExportedToMake
+}
+
func (a *ModuleBase) computeInstallDeps(
ctx blueprint.ModuleContext) Paths {
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index 91f47e0..b2a8914 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -111,6 +111,7 @@
"LOCAL_CONLYFLAGS": "conlyflags",
"LOCAL_CPPFLAGS": "cppflags",
"LOCAL_REQUIRED_MODULES": "required",
+ "LOCAL_OVERRIDES_MODULES": "overrides",
"LOCAL_LDLIBS": "host_ldlibs",
"LOCAL_CLANG_CFLAGS": "clang_cflags",
"LOCAL_YACCFLAGS": "yaccflags",
diff --git a/cc/androidmk.go b/cc/androidmk.go
index e78c419..9bcb783 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -228,6 +228,10 @@
if binary.coverageOutputFile.Valid() {
fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", binary.coverageOutputFile.String())
}
+
+ if len(binary.Properties.Overrides) > 0 {
+ fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES := "+strings.Join(binary.Properties.Overrides, " "))
+ }
})
}
@@ -383,3 +387,18 @@
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")
+ })
+}
diff --git a/cc/binary.go b/cc/binary.go
index 7794eab..c3e899a 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -45,6 +45,13 @@
No_pie *bool `android:"arch_variant"`
DynamicLinker string `blueprint:"mutated"`
+
+ // Names of modules to be overridden. Listed modules can only be other binaries
+ // (in Make or Soong).
+ // This does not completely prevent installation of the overridden binaries, but if both
+ // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
+ // from PRODUCT_PACKAGES.
+ Overrides []string
}
func init() {
diff --git a/cc/builder.go b/cc/builder.go
index 53ef69c..a88df88 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -203,9 +203,11 @@
commandStr := "($sAbiDiffer $allowFlags -lib $libName -arch $arch -check-all-apis -o ${out} -new $in -old $referenceDump)"
distAbiDiffDir := android.PathForDist(ctx, "abidiffs")
+ commandStr += "|| (echo ' ---- Please update abi references by running platform/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l ${libName} ----'"
if distAbiDiffDir.Valid() {
- commandStr += " || (mkdir -p " + distAbiDiffDir.String() + " && cp ${out} " + distAbiDiffDir.String() + " && exit 1)"
+ commandStr += ") && (mkdir -p " + distAbiDiffDir.String() + " && cp ${out} " + distAbiDiffDir.String()
}
+ commandStr += " && exit 1)"
return blueprint.RuleParams{
Command: commandStr,
CommandDeps: []string{"$sAbiDiffer"},
@@ -740,7 +742,7 @@
Implicit: referenceDump,
Args: map[string]string{
"referenceDump": referenceDump.String(),
- "libName": baseName,
+ "libName": baseName[0:(len(baseName) - len(filepath.Ext(baseName)))],
"arch": ctx.Arch().ArchType.Name,
"allowFlags": strings.Join(localAbiCheckAllowFlags, " "),
},
diff --git a/cc/cc.go b/cc/cc.go
index 721f4b1..c8d5251 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -52,7 +52,7 @@
ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
- ctx.TopDown("minimal_runtime_deps", minimalRuntimeDepsMutator())
+ ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator())
ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
ctx.TopDown("vndk_deps", sabiDepsMutator)
@@ -922,6 +922,16 @@
}
} 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 @@
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
}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 437211c..d3ac43b 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -56,15 +56,18 @@
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 @@
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",
@@ -143,6 +174,7 @@
}
func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
+ t.Helper()
ctx := createTestContext(t, config, bp)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
@@ -154,6 +186,7 @@
}
func testCc(t *testing.T, bp string) *android.TestContext {
+ t.Helper()
config := android.TestArchConfig(buildDir, nil)
config.ProductVariables.DeviceVndkVersion = StringPtr("current")
config.ProductVariables.Platform_vndk_version = StringPtr("VER")
@@ -162,6 +195,7 @@
}
func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
+ t.Helper()
config := android.TestArchConfig(buildDir, nil)
config.ProductVariables.Platform_vndk_version = StringPtr("VER")
@@ -169,6 +203,7 @@
}
func testCcError(t *testing.T, pattern string, bp string) {
+ t.Helper()
config := android.TestArchConfig(buildDir, nil)
config.ProductVariables.DeviceVndkVersion = StringPtr("current")
config.ProductVariables.Platform_vndk_version = StringPtr("VER")
@@ -225,6 +260,8 @@
func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
isVndkSp bool, extends string) {
+ t.Helper()
+
mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
if !mod.hasVendorVariant() {
t.Errorf("%q must have vendor variant", name)
@@ -308,6 +345,107 @@
checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
}
+func TestVndkDepError(t *testing.T) {
+ // Check whether an error is emitted when a VNDK lib depends on a system lib.
+ testCcError(t, "dependency \".*\" of \".*\" missing variant", `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ shared_libs: ["libfwk"], // Cause error
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libfwk",
+ nocrt: true,
+ }
+ `)
+
+ // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
+ testCcError(t, "dependency \".*\" of \".*\" missing variant", `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ shared_libs: ["libvendor"], // Cause error
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvendor",
+ vendor: true,
+ nocrt: true,
+ }
+ `)
+
+ // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
+ testCcError(t, "dependency \".*\" of \".*\" missing variant", `
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ shared_libs: ["libfwk"], // Cause error
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libfwk",
+ nocrt: true,
+ }
+ `)
+
+ // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
+ testCcError(t, "dependency \".*\" of \".*\" missing variant", `
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ shared_libs: ["libvendor"], // Cause error
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvendor",
+ vendor: true,
+ nocrt: true,
+ }
+ `)
+
+ // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
+ testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ shared_libs: ["libvndk"], // Cause error
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+ `)
+}
+
func TestVndkExt(t *testing.T) {
// This test checks the VNDK-Ext properties.
ctx := testCc(t, `
@@ -334,7 +472,7 @@
checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
}
-func TestVndkExtNoVndk(t *testing.T) {
+func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
// This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
ctx := testCcNoVndk(t, `
cc_library {
@@ -455,7 +593,7 @@
}
func TestVndkExtVendorAvailableFalseError(t *testing.T) {
- // This test ensures an error is emitted when a vndk-ext library extends a vndk library
+ // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
// with `vendor_available: false`.
testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
cc_library {
@@ -479,8 +617,8 @@
`)
}
-func TestVendorModuleUsesVndkExt(t *testing.T) {
- // This test ensures a vendor module can depend on a vndk-ext library.
+func TestVendorModuleUseVndkExt(t *testing.T) {
+ // This test ensures a vendor module can depend on a VNDK-Ext library.
testCc(t, `
cc_library {
name: "libvndk",
@@ -532,8 +670,8 @@
`)
}
-func TestVndkExtUsesVendorLib(t *testing.T) {
- // This test ensures a vndk-ext library can depend on a vendor library.
+func TestVndkExtUseVendorLib(t *testing.T) {
+ // This test ensures a VNDK-Ext library can depend on a vendor library.
testCc(t, `
cc_library {
name: "libvndk",
@@ -561,12 +699,9 @@
nocrt: true,
}
`)
-}
-func TestVndkSpExtUsesVendorLibError(t *testing.T) {
- // This test ensures an error is emitted if a vndk-sp-ext library depends on a vendor
- // library.
- testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
+ // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
+ testCc(t, `
cc_library {
name: "libvndk_sp",
vendor_available: true,
@@ -597,9 +732,91 @@
`)
}
-func TestVndkUsesVndkExtError(t *testing.T) {
- // This test ensures an error is emitted if a vndk/vndk-sp library depends on a
- // vndk-ext/vndk-sp-ext library.
+func TestVndkSpExtUseVndkError(t *testing.T) {
+ // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
+ // library.
+ testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk_sp",
+ support_system_process: true,
+ },
+ shared_libs: ["libvndk"], // Cause an error
+ nocrt: true,
+ }
+ `)
+
+ // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
+ // library.
+ testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk_sp",
+ support_system_process: true,
+ },
+ shared_libs: ["libvndk_ext"], // Cause an error
+ nocrt: true,
+ }
+ `)
+}
+
+func TestVndkUseVndkExtError(t *testing.T) {
+ // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
+ // VNDK-Ext/VNDK-SP-Ext library.
testCcError(t, "dependency \".*\" of \".*\" missing variant", `
cc_library {
name: "libvndk",
@@ -1077,16 +1294,20 @@
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 +1332,16 @@
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 +1473,68 @@
}
}
}
+
+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)
+ }
+
+}
diff --git a/cc/makevars.go b/cc/makevars.go
index 042af2a..2664ee1 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -100,6 +100,21 @@
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, " "))
diff --git a/cc/sanitize.go b/cc/sanitize.go
index c9fcafc..859d876 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -115,6 +115,7 @@
SanitizerEnabled bool `blueprint:"mutated"`
SanitizeDep bool `blueprint:"mutated"`
MinimalRuntimeDep bool `blueprint:"mutated"`
+ UbsanRuntimeDep bool `blueprint:"mutated"`
InSanitizerDir bool `blueprint:"mutated"`
}
@@ -199,8 +200,9 @@
}
}
+ // Global integer_overflow builds do not support static libraries.
if found, globalSanitizers = removeFromList("integer_overflow", globalSanitizers); found && s.Integer_overflow == nil {
- if !ctx.Config().IntegerOverflowDisabledForPath(ctx.ModuleDir()) {
+ if !ctx.Config().IntegerOverflowDisabledForPath(ctx.ModuleDir()) && !ctx.static() {
s.Integer_overflow = boolPtr(true)
}
}
@@ -209,8 +211,9 @@
ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
}
+ // Global integer_overflow builds do not support static library diagnostics.
if found, globalSanitizersDiag = removeFromList("integer_overflow", globalSanitizersDiag); found &&
- s.Diag.Integer_overflow == nil && Bool(s.Integer_overflow) {
+ s.Diag.Integer_overflow == nil && Bool(s.Integer_overflow) && !ctx.static() {
s.Diag.Integer_overflow = boolPtr(true)
}
@@ -250,10 +253,14 @@
s.Diag.Cfi = nil
}
- // Also disable CFI for host builds.
+ // Disable sanitizers that depend on the UBSan runtime for host builds.
if ctx.Host() {
s.Cfi = nil
s.Diag.Cfi = nil
+ s.Misc_undefined = nil
+ s.Undefined = nil
+ s.All_undefined = nil
+ s.Integer_overflow = nil
}
if ctx.staticBinary() {
@@ -305,7 +312,7 @@
if ctx.Device() && sanitize.Properties.MinimalRuntimeDep {
flags.LdFlags = append(flags.LdFlags, minimalRuntimePath)
}
- if !sanitize.Properties.SanitizerEnabled {
+ if !sanitize.Properties.SanitizerEnabled && !sanitize.Properties.UbsanRuntimeDep {
return flags
}
@@ -416,14 +423,12 @@
}
if Bool(sanitize.Properties.Sanitize.Integer_overflow) {
- if !ctx.static() {
- sanitizers = append(sanitizers, "unsigned-integer-overflow")
- sanitizers = append(sanitizers, "signed-integer-overflow")
- flags.CFlags = append(flags.CFlags, intOverflowCflags...)
- if Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) {
- diagSanitizers = append(diagSanitizers, "unsigned-integer-overflow")
- diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
- }
+ sanitizers = append(sanitizers, "unsigned-integer-overflow")
+ sanitizers = append(sanitizers, "signed-integer-overflow")
+ flags.CFlags = append(flags.CFlags, intOverflowCflags...)
+ if Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) {
+ diagSanitizers = append(diagSanitizers, "unsigned-integer-overflow")
+ diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
}
}
@@ -463,15 +468,20 @@
runtimeLibrary = config.AddressSanitizerRuntimeLibrary(ctx.toolchain())
} else if Bool(sanitize.Properties.Sanitize.Thread) {
runtimeLibrary = config.ThreadSanitizerRuntimeLibrary(ctx.toolchain())
- } else if len(diagSanitizers) > 0 {
+ } else if len(diagSanitizers) > 0 || sanitize.Properties.UbsanRuntimeDep {
runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(ctx.toolchain())
}
if runtimeLibrary != "" {
+ runtimeLibraryPath := "${config.ClangAsanLibDir}/" + runtimeLibrary
+ if !ctx.static() {
+ runtimeLibraryPath = runtimeLibraryPath + ctx.toolchain().ShlibSuffix()
+ } else {
+ runtimeLibraryPath = runtimeLibraryPath + ".a"
+ }
+
// ASan runtime library must be the first in the link order.
- flags.libFlags = append([]string{
- "${config.ClangAsanLibDir}/" + runtimeLibrary + ctx.toolchain().ShlibSuffix(),
- }, flags.libFlags...)
+ flags.libFlags = append([]string{runtimeLibraryPath}, flags.libFlags...)
sanitize.runtimeLibrary = runtimeLibrary
// When linking against VNDK, use the vendor variant of the runtime lib
@@ -594,16 +604,21 @@
}
// Propagate the ubsan minimal runtime dependency when there are integer overflow sanitized static dependencies.
-func minimalRuntimeDepsMutator() func(android.TopDownMutatorContext) {
+func sanitizerRuntimeDepsMutator() func(android.TopDownMutatorContext) {
return func(mctx android.TopDownMutatorContext) {
if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
mctx.VisitDepsDepthFirst(func(module android.Module) {
if d, ok := module.(*Module); ok && d.static() && d.sanitize != nil {
- // If a static dependency will be built with the minimal runtime,
- // make sure we include the ubsan minimal runtime.
if enableMinimalRuntime(d.sanitize) {
+ // If a static dependency is built with the minimal runtime,
+ // make sure we include the ubsan minimal runtime.
c.sanitize.Properties.MinimalRuntimeDep = true
+ } else if Bool(d.sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
+ len(d.sanitize.Properties.Sanitize.Diag.Misc_undefined) > 0 {
+ // If a static dependency runs with full ubsan diagnostics,
+ // make sure we include the ubsan runtime.
+ c.sanitize.Properties.UbsanRuntimeDep = true
}
}
})
diff --git a/cc/vendor_public_library.go b/cc/vendor_public_library.go
new file mode 100644
index 0000000..da41cbc
--- /dev/null
+++ b/cc/vendor_public_library.go
@@ -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)
+}
diff --git a/cc/vndk.go b/cc/vndk.go
index a0d338b..5a24a98 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -150,22 +150,39 @@
return
}
- // VNDK-core and VNDK-SP must not depend on VNDK extensions.
- if (vndk.isVndk() || vndk.isVndkSp()) && !vndk.isVndkExt() && to.vndkdep.isVndkExt() {
+ // Check the dependencies of VNDK shared libraries.
+ if !vndkIsVndkDepAllowed(vndk, to.vndkdep) {
ctx.ModuleErrorf("(%s) should not link to %q (%s)",
vndk.typeName(), to.Name(), to.vndkdep.typeName())
return
}
+}
- // VNDK-core must be only depend on VNDK-SP or LL-NDK. VNDK-SP must only depend on
- // LL-NDK, regardless the extension status. VNDK-Ext may depend on vendor libraries, but
- // VNDK-SP-Ext must remain self-contained.
- if (vndk.isVndk() && !to.vndkdep.isVndk() && !vndk.isVndkExt()) ||
- (vndk.isVndkSp() && !to.vndkdep.isVndkSp()) {
- ctx.ModuleErrorf("(%s) should not link to %q (%s)",
- vndk.typeName(), to.Name(), to.vndkdep.typeName())
- return
+func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) bool {
+ // Check the dependencies of VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext and vendor modules.
+ if from.isVndkExt() {
+ if from.isVndkSp() {
+ // VNDK-SP-Ext may depend on VNDK-SP, VNDK-SP-Ext, or vendor libs (excluding
+ // VNDK and VNDK-Ext).
+ return to.isVndkSp() || !to.isVndk()
+ }
+ // VNDK-Ext may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
+ return true
}
+ if from.isVndk() {
+ if to.isVndkExt() {
+ // VNDK-core and VNDK-SP must not depend on VNDK extensions.
+ return false
+ }
+ if from.isVndkSp() {
+ // VNDK-SP must only depend on VNDK-SP.
+ return to.isVndkSp()
+ }
+ // VNDK-core may depend on VNDK-core or VNDK-SP.
+ return to.isVndk()
+ }
+ // Vendor modules may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
+ return true
}
var (
diff --git a/scripts/strip.sh b/scripts/strip.sh
index ff8aaa0..318c7ad 100755
--- a/scripts/strip.sh
+++ b/scripts/strip.sh
@@ -56,6 +56,7 @@
"${CROSS_COMPILE}nm" -D "${infile}" --format=posix --defined-only | awk '{ print $$1 }' | sort >"${outfile}.dynsyms"
"${CROSS_COMPILE}nm" "${infile}" --format=posix --defined-only | awk '{ if ($$2 == "T" || $$2 == "t" || $$2 == "D") print $$1 }' | sort > "${outfile}.funcsyms"
comm -13 "${outfile}.dynsyms" "${outfile}.funcsyms" > "${outfile}.keep_symbols"
+ echo >> "${outfile}.keep_symbols" # Ensure that the keep_symbols file is not empty.
"${CROSS_COMPILE}objcopy" --rename-section .debug_frame=saved_debug_frame "${outfile}.debug" "${outfile}.mini_debuginfo"
"${CROSS_COMPILE}objcopy" -S --remove-section .gdb_index --remove-section .comment --keep-symbols="${outfile}.keep_symbols" "${outfile}.mini_debuginfo"
"${CROSS_COMPILE}objcopy" --rename-section saved_debug_frame=.debug_frame "${outfile}.mini_debuginfo"