diff options
Diffstat (limited to 'cc')
| -rw-r--r-- | cc/androidmk.go | 60 | ||||
| -rw-r--r-- | cc/binary.go | 5 | ||||
| -rw-r--r-- | cc/binary_sdk_member.go | 143 | ||||
| -rw-r--r-- | cc/builder.go | 4 | ||||
| -rw-r--r-- | cc/cc.go | 160 | ||||
| -rw-r--r-- | cc/cflag_artifacts.go | 7 | ||||
| -rw-r--r-- | cc/compiler.go | 21 | ||||
| -rw-r--r-- | cc/config/clang.go | 5 | ||||
| -rw-r--r-- | cc/config/global.go | 4 | ||||
| -rw-r--r-- | cc/config/x86_darwin_host.go | 2 | ||||
| -rw-r--r-- | cc/library.go | 8 | ||||
| -rw-r--r-- | cc/pgo.go | 6 | ||||
| -rw-r--r-- | cc/sanitize.go | 46 | ||||
| -rw-r--r-- | cc/snapshot_utils.go | 27 | ||||
| -rw-r--r-- | cc/stl.go | 20 | ||||
| -rw-r--r-- | cc/vendor_snapshot.go | 461 | ||||
| -rw-r--r-- | cc/vndk_prebuilt.go | 40 | ||||
| -rw-r--r-- | cc/xom.go | 79 |
18 files changed, 940 insertions, 158 deletions
diff --git a/cc/androidmk.go b/cc/androidmk.go index 137cb63d7..d8210fc9b 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -413,9 +413,12 @@ func (c *llndkStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.Androi } func (c *vndkPrebuiltLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { + // Each vndk prebuilt is exported to androidMk only when BOARD_VNDK_VERSION != current + // and the version of the prebuilt is same as BOARD_VNDK_VERSION. ret.Class = "SHARED_LIBRARIES" - ret.SubName = c.NameSuffix() + // shouldn't add any suffixes due to mk modules + ret.SubName = "" ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { c.libraryDecorator.androidMkWriteExportedFlags(w) @@ -426,6 +429,61 @@ func (c *vndkPrebuiltLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *andr fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix) fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path) fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem) + if c.tocFile.Valid() { + fmt.Fprintln(w, "LOCAL_SOONG_TOC := "+c.tocFile.String()) + } + }) +} + +func (c *vendorSnapshotLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { + // Each vendor snapshot is exported to androidMk only when BOARD_VNDK_VERSION != current + // and the version of the prebuilt is same as BOARD_VNDK_VERSION. + if c.shared() { + ret.Class = "SHARED_LIBRARIES" + } else if c.static() { + ret.Class = "STATIC_LIBRARIES" + } else if c.header() { + ret.Class = "HEADER_LIBRARIES" + } + + if c.androidMkVendorSuffix { + ret.SubName = vendorSuffix + } else { + ret.SubName = "" + } + + ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { + c.libraryDecorator.androidMkWriteExportedFlags(w) + + if c.shared() { + path, file := filepath.Split(c.path.ToMakePath().String()) + stem, suffix, ext := android.SplitFileExt(file) + fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext) + fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix) + if c.shared() { + fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path) + fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem) + } + if c.tocFile.Valid() { + fmt.Fprintln(w, "LOCAL_SOONG_TOC := "+c.tocFile.String()) + } + } else { // static or header + fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true") + } + }) +} + +func (c *vendorSnapshotBinaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { + ret.Class = "EXECUTABLES" + + if c.androidMkVendorSuffix { + ret.SubName = vendorSuffix + } else { + ret.SubName = "" + } + + ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { + fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS := "+strings.Join(c.Properties.Symlinks, " ")) }) } diff --git a/cc/binary.go b/cc/binary.go index 280d17bfb..661264eef 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -200,6 +200,11 @@ func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) { module.compiler = NewBaseCompiler() module.linker = binary module.installer = binary + + // Allow module to be added as member of an sdk/module_exports. + module.sdkMemberTypes = []android.SdkMemberType{ + ccBinarySdkMemberType, + } return module, binary } diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go new file mode 100644 index 000000000..53bc065f9 --- /dev/null +++ b/cc/binary_sdk_member.go @@ -0,0 +1,143 @@ +// Copyright 2020 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" + + "android/soong/android" + "github.com/google/blueprint" +) + +func init() { + android.RegisterSdkMemberType(ccBinarySdkMemberType) +} + +var ccBinarySdkMemberType = &binarySdkMemberType{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ + PropertyName: "native_binaries", + }, +} + +type binarySdkMemberType struct { + android.SdkMemberTypeBase +} + +func (mt *binarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { + targets := mctx.MultiTargets() + for _, lib := range names { + for _, target := range targets { + name, version := StubsLibNameAndVersion(lib) + if version == "" { + version = LatestStubsVersionFor(mctx.Config(), name) + } + mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{ + {Mutator: "version", Variation: version}, + }...), dependencyTag, name) + } + } +} + +func (mt *binarySdkMemberType) IsInstance(module android.Module) bool { + // Check the module to see if it can be used with this module type. + if m, ok := module.(*Module); ok { + for _, allowableMemberType := range m.sdkMemberTypes { + if allowableMemberType == mt { + return true + } + } + } + + return false +} + +func (mt *binarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) { + info := mt.organizeVariants(member) + buildSharedNativeBinarySnapshot(info, builder, member) +} + +// Organize the variants by architecture. +func (mt *binarySdkMemberType) organizeVariants(member android.SdkMember) *nativeBinaryInfo { + memberName := member.Name() + info := &nativeBinaryInfo{ + name: memberName, + memberType: mt, + } + + for _, variant := range member.Variants() { + ccModule := variant.(*Module) + + info.archVariantProperties = append(info.archVariantProperties, nativeBinaryInfoProperties{ + name: memberName, + archType: ccModule.Target().Arch.ArchType.String(), + outputFile: ccModule.OutputFile().Path(), + }) + } + + // Initialize the unexported properties that will not be set during the + // extraction process. + info.commonProperties.name = memberName + + // Extract common properties from the arch specific properties. + extractCommonProperties(&info.commonProperties, info.archVariantProperties) + + return info +} + +func buildSharedNativeBinarySnapshot(info *nativeBinaryInfo, builder android.SnapshotBuilder, member android.SdkMember) { + pbm := builder.AddPrebuiltModule(member, "cc_prebuilt_binary") + pbm.AddProperty("compile_multilib", "both") + archProperties := pbm.AddPropertySet("arch") + for _, av := range info.archVariantProperties { + archTypeProperties := archProperties.AddPropertySet(av.archType) + archTypeProperties.AddProperty("srcs", []string{nativeBinaryPathFor(av)}) + + builder.CopyToSnapshot(av.outputFile, nativeBinaryPathFor(av)) + } +} + +const ( + nativeBinaryDir = "bin" +) + +// path to the native binary. Relative to <sdk_root>/<api_dir> +func nativeBinaryPathFor(lib nativeBinaryInfoProperties) string { + return filepath.Join(lib.archType, + nativeBinaryDir, lib.outputFile.Base()) +} + +// nativeBinaryInfoProperties represents properties of a native binary +// +// The exported (capitalized) fields will be examined and may be changed during common value extraction. +// The unexported fields will be left untouched. +type nativeBinaryInfoProperties struct { + // The name of the library, is not exported as this must not be changed during optimization. + name string + + // archType is not exported as if set (to a non default value) it is always arch specific. + // This is "" for common properties. + archType string + + // outputFile is not exported as it is always arch specific. + outputFile android.Path +} + +// nativeBinaryInfo represents a collection of arch-specific modules having the same name +type nativeBinaryInfo struct { + name string + memberType *binarySdkMemberType + archVariantProperties []nativeBinaryInfoProperties + commonProperties nativeBinaryInfoProperties +} diff --git a/cc/builder.go b/cc/builder.go index 3ecfe540c..136263b41 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -55,9 +55,9 @@ var ( }, "ccCmd", "cFlags") - ccNoDeps = pctx.AndroidRemoteStaticRule("ccNoDeps", android.RemoteRuleSupports{Goma: true}, + ccNoDeps = pctx.AndroidStaticRule("ccNoDeps", blueprint.RuleParams{ - Command: "$relPwd ${config.CcWrapper}$ccCmd -c $cFlags -o $out $in", + Command: "$relPwd $ccCmd -c $cFlags -o $out $in", CommandDeps: []string{"$ccCmd"}, }, "ccCmd", "cFlags") @@ -49,6 +49,8 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.BottomUp("version", VersionMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel() ctx.BottomUp("sysprop_cc", SyspropMutator).Parallel() + ctx.BottomUp("vendor_snapshot", VendorSnapshotMutator).Parallel() + ctx.BottomUp("vendor_snapshot_source", VendorSnapshotSourceMutator).Parallel() }) ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { @@ -93,6 +95,8 @@ type Deps struct { HeaderLibs []string RuntimeLibs []string + StaticUnwinderIfLegacy bool + ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string ObjFiles []string @@ -383,6 +387,7 @@ var ( lateSharedDepTag = DependencyTag{Name: "late shared", Library: true, Shared: true} staticExportDepTag = DependencyTag{Name: "static", Library: true, ReexportFlags: true} lateStaticDepTag = DependencyTag{Name: "late static", Library: true} + staticUnwinderDepTag = DependencyTag{Name: "static unwinder", Library: true} wholeStaticDepTag = DependencyTag{Name: "whole static", Library: true, ReexportFlags: true} headerDepTag = DependencyTag{Name: "header", Library: true} headerExportDepTag = DependencyTag{Name: "header", Library: true, ReexportFlags: true} @@ -448,7 +453,6 @@ type Module struct { vndkdep *vndkdep lto *lto pgo *pgo - xom *xom outputFile android.OptionalPath @@ -732,9 +736,6 @@ func (c *Module) Init() android.Module { if c.pgo != nil { c.AddProperties(c.pgo.props()...) } - if c.xom != nil { - c.AddProperties(c.xom.props()...) - } for _, feature := range c.features { c.AddProperties(feature.props()...) } @@ -923,8 +924,16 @@ func (c *Module) nativeCoverage() bool { } func (c *Module) isSnapshotPrebuilt() bool { - _, ok := c.linker.(*vndkPrebuiltLibraryDecorator) - return ok + if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok { + return true + } + if _, ok := c.linker.(*vendorSnapshotLibraryDecorator); ok { + return true + } + if _, ok := c.linker.(*vendorSnapshotBinaryDecorator); ok { + return true + } + return false } func (c *Module) ExportedIncludeDirs() android.Paths { @@ -1196,7 +1205,6 @@ func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Mo module.vndkdep = &vndkdep{} module.lto = <o{} module.pgo = &pgo{} - module.xom = &xom{} return module } @@ -1391,9 +1399,6 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if c.pgo != nil { flags = c.pgo.flags(ctx, flags) } - if c.xom != nil { - flags = c.xom.flags(ctx, flags) - } for _, feature := range c.features { flags = feature.flags(ctx, flags) } @@ -1612,6 +1617,10 @@ func StubsLibNameAndVersion(name string) (string, string) { } func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { + if !c.Enabled() { + return + } + ctx := &depsContext{ BottomUpMutatorContext: actx, moduleContextImpl: moduleContextImpl{ @@ -1627,7 +1636,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { if ctx.Os() == android.Android { version := ctx.sdkVersion() - // rewriteNdkLibs takes a list of names of shared libraries and scans it for three types + // rewriteLibs takes a list of names of shared libraries and scans it for three types // of names: // // 1. Name of an NDK library that refers to a prebuilt module. @@ -1643,7 +1652,26 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { // nonvariantLibs vendorPublicLibraries := vendorPublicLibraries(actx.Config()) - rewriteNdkLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) { + vendorSnapshotSharedLibs := vendorSnapshotSharedLibs(actx.Config()) + + rewriteVendorLibs := func(lib string) string { + if isLlndkLibrary(lib, ctx.Config()) { + return lib + llndkLibrarySuffix + } + + // only modules with BOARD_VNDK_VERSION uses snapshot. + if c.VndkVersion() != actx.DeviceConfig().VndkVersion() { + return lib + } + + if snapshot, ok := vendorSnapshotSharedLibs.get(lib, actx.Arch().ArchType); ok { + return snapshot + } + + return lib + } + + rewriteLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) { variantLibs = []string{} nonvariantLibs = []string{} for _, entry := range list { @@ -1655,8 +1683,8 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { } else { variantLibs = append(variantLibs, name+ndkLibrarySuffix) } - } else if ctx.useVndk() && isLlndkLibrary(name, ctx.Config()) { - nonvariantLibs = append(nonvariantLibs, name+llndkLibrarySuffix) + } else if ctx.useVndk() { + nonvariantLibs = append(nonvariantLibs, rewriteVendorLibs(entry)) } else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, *vendorPublicLibraries) { vendorPublicLib := name + vendorPublicLibrarySuffix if actx.OtherModuleExists(vendorPublicLib) { @@ -1675,9 +1703,14 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { return nonvariantLibs, variantLibs } - deps.SharedLibs, variantNdkLibs = rewriteNdkLibs(deps.SharedLibs) - deps.LateSharedLibs, variantLateNdkLibs = rewriteNdkLibs(deps.LateSharedLibs) - deps.ReexportSharedLibHeaders, _ = rewriteNdkLibs(deps.ReexportSharedLibHeaders) + deps.SharedLibs, variantNdkLibs = rewriteLibs(deps.SharedLibs) + deps.LateSharedLibs, variantLateNdkLibs = rewriteLibs(deps.LateSharedLibs) + deps.ReexportSharedLibHeaders, _ = rewriteLibs(deps.ReexportSharedLibHeaders) + if ctx.useVndk() { + for idx, lib := range deps.RuntimeLibs { + deps.RuntimeLibs[idx] = rewriteVendorLibs(lib) + } + } } buildStubs := false @@ -1689,11 +1722,28 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { } } + rewriteSnapshotLibs := func(lib string, snapshotMap *snapshotMap) string { + // only modules with BOARD_VNDK_VERSION uses snapshot. + if c.VndkVersion() != actx.DeviceConfig().VndkVersion() { + return lib + } + + if snapshot, ok := snapshotMap.get(lib, actx.Arch().ArchType); ok { + return snapshot + } + + return lib + } + + vendorSnapshotHeaderLibs := vendorSnapshotHeaderLibs(actx.Config()) for _, lib := range deps.HeaderLibs { depTag := headerDepTag if inList(lib, deps.ReexportHeaderLibHeaders) { depTag = headerExportDepTag } + + lib = rewriteSnapshotLibs(lib, vendorSnapshotHeaderLibs) + if buildStubs { actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()), depTag, lib) @@ -1709,12 +1759,16 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { } syspropImplLibraries := syspropImplLibraries(actx.Config()) + vendorSnapshotStaticLibs := vendorSnapshotStaticLibs(actx.Config()) for _, lib := range deps.WholeStaticLibs { depTag := wholeStaticDepTag if impl, ok := syspropImplLibraries[lib]; ok { lib = impl } + + lib = rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs) + actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, }, depTag, lib) @@ -1730,14 +1784,24 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { lib = impl } + lib = rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs) + actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, }, depTag, lib) } - actx.AddVariationDependencies([]blueprint.Variation{ - {Mutator: "link", Variation: "static"}, - }, lateStaticDepTag, deps.LateStaticLibs...) + if deps.StaticUnwinderIfLegacy && ctx.Config().UnbundledBuild() { + actx.AddVariationDependencies([]blueprint.Variation{ + {Mutator: "link", Variation: "static"}, + }, staticUnwinderDepTag, staticUnwinder(actx)) + } + + for _, lib := range deps.LateStaticLibs { + actx.AddVariationDependencies([]blueprint.Variation{ + {Mutator: "link", Variation: "static"}, + }, lateStaticDepTag, rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs)) + } addSharedLibDependencies := func(depTag DependencyTag, name string, version string) { var variations []blueprint.Variation @@ -2106,6 +2170,14 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } } + if depTag == staticUnwinderDepTag { + if c.ApexProperties.Info.LegacyAndroid10Support { + depTag = StaticDepTag + } else { + return + } + } + // Extract ExplicitlyVersioned field from the depTag and reset it inside the struct. // Otherwise, SharedDepTag and lateSharedDepTag with ExplicitlyVersioned set to true // won't be matched to SharedDepTag and lateSharedDepTag. @@ -2284,14 +2356,33 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { *depPtr = append(*depPtr, dep.Path()) } - makeLibName := func(depName string) string { + vendorSuffixModules := vendorSuffixModules(ctx.Config()) + + baseLibName := func(depName string) string { libName := strings.TrimSuffix(depName, llndkLibrarySuffix) libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix) libName = strings.TrimPrefix(libName, "prebuilt_") + return libName + } + + makeLibName := func(depName string) string { + libName := baseLibName(depName) isLLndk := isLlndkLibrary(libName, ctx.Config()) isVendorPublicLib := inList(libName, *vendorPublicLibraries) bothVendorAndCoreVariantsExist := ccDep.HasVendorVariant() || isLLndk + if c, ok := ccDep.(*Module); ok { + // Use base module name for snapshots when exporting to Makefile. + if c.isSnapshotPrebuilt() && !c.IsVndk() { + baseName := c.BaseModuleName() + if vendorSuffixModules[baseName] { + return baseName + ".vendor" + } else { + return baseName + } + } + } + if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() && !c.InRamdisk() && !c.InRecovery() { // The vendor module is a no-vendor-variant VNDK library. Depend on the // core module instead. @@ -2331,8 +2422,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // they merely serve as Make dependencies and do not affect this lib itself. c.Properties.AndroidMkSharedLibs = append( c.Properties.AndroidMkSharedLibs, makeLibName(depName)) - // Record depName as-is for snapshots. - c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, depName) + // Record baseLibName for snapshots. + c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, baseLibName(depName)) case ndkStubDepTag, ndkLateStubDepTag: c.Properties.AndroidMkSharedLibs = append( c.Properties.AndroidMkSharedLibs, @@ -2343,8 +2434,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { case runtimeDepTag: c.Properties.AndroidMkRuntimeLibs = append( c.Properties.AndroidMkRuntimeLibs, makeLibName(depName)) - // Record depName as-is for snapshots. - c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, depName) + // Record baseLibName for snapshots. + c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, baseLibName(depName)) case wholeStaticDepTag: c.Properties.AndroidMkWholeStaticLibs = append( c.Properties.AndroidMkWholeStaticLibs, makeLibName(depName)) @@ -2601,7 +2692,6 @@ func DefaultsFactory(props ...interface{}) android.Module { &VndkProperties{}, <OProperties{}, &PgoProperties{}, - &XomProperties{}, &android.ProtoProperties{}, ) @@ -2719,10 +2809,16 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { platformVndkVersion, productVndkVersion, ) - } else if lib, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok { + } else if m.isSnapshotPrebuilt() { // Make vendor variants only for the versions in BOARD_VNDK_VERSION and // PRODUCT_EXTRA_VNDK_VERSIONS. - vendorVariants = append(vendorVariants, lib.version()) + if snapshot, ok := m.linker.(interface { + version() string + }); ok { + vendorVariants = append(vendorVariants, snapshot.version()) + } else { + mctx.ModuleErrorf("version is unknown for snapshot prebuilt") + } } else if m.HasVendorVariant() && !vendorSpecific { // This will be available in /system, /vendor and /product // or a /system directory that is available to vendor and product. @@ -2819,6 +2915,14 @@ func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string m.Properties.ImageVariationPrefix = VendorVariationPrefix m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix) squashVendorSrcs(m) + + // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION. + // Hide other vendor variants to avoid collision. + vndkVersion := ctx.DeviceConfig().VndkVersion() + if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion { + m.Properties.HideFromMake = true + m.SkipInstall() + } } else if strings.HasPrefix(variant, ProductVariationPrefix) { m.Properties.ImageVariationPrefix = ProductVariationPrefix m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix) diff --git a/cc/cflag_artifacts.go b/cc/cflag_artifacts.go index b61f2a8be..855ff25b3 100644 --- a/cc/cflag_artifacts.go +++ b/cc/cflag_artifacts.go @@ -41,12 +41,7 @@ type cflagArtifactsText struct { // filter. func allowedDir(subdir string) bool { subdir += "/" - for _, prefix := range TrackedCFlagsDir { - if strings.HasPrefix(subdir, prefix) { - return true - } - } - return false + return android.HasAnyPrefix(subdir, TrackedCFlagsDir) } func (s *cflagArtifactsText) genFlagFilename(flag string) string { diff --git a/cc/compiler.go b/cc/compiler.go index 1ced451fa..c1a8d96d8 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -241,12 +241,7 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { // Return true if the module is in the WarningAllowedProjects. func warningsAreAllowed(subdir string) bool { subdir += "/" - for _, prefix := range config.WarningAllowedProjects { - if strings.HasPrefix(subdir, prefix) { - return true - } - } - return false + return android.HasAnyPrefix(subdir, config.WarningAllowedProjects) } func addToModuleList(ctx ModuleContext, key android.OnceKey, module string) { @@ -515,7 +510,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps // Exclude directories from manual binder interface whitelisting. //TODO(b/145621474): Move this check into IInterface.h when clang-tidy no longer uses absolute paths. - if android.PrefixInList(ctx.ModuleDir(), allowedManualInterfacePaths) { + if android.HasAnyPrefix(ctx.ModuleDir(), allowedManualInterfacePaths) { flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES") } @@ -604,16 +599,12 @@ var thirdPartyDirPrefixExceptions = []*regexp.Regexp{ func isThirdParty(path string) bool { thirdPartyDirPrefixes := []string{"external/", "vendor/", "hardware/"} - for _, prefix := range thirdPartyDirPrefixes { - if strings.HasPrefix(path, prefix) { - for _, prefix := range thirdPartyDirPrefixExceptions { - if prefix.MatchString(path) { - return false - } + if android.HasAnyPrefix(path, thirdPartyDirPrefixes) { + for _, prefix := range thirdPartyDirPrefixExceptions { + if prefix.MatchString(path) { + return false } - break } } - return true } diff --git a/cc/config/clang.go b/cc/config/clang.go index 8618d0955..0d036999f 100644 --- a/cc/config/clang.go +++ b/cc/config/clang.go @@ -169,6 +169,11 @@ func init() { "-Wno-reorder-init-list", // http://b/145211066 "-Wno-implicit-int-float-conversion", + // New warnings to be fixed after clang-r377782. + "-Wno-bitwise-conditional-parentheses", // http://b/148286937 + "-Wno-int-in-bool-context", // http://b/148287349 + "-Wno-sizeof-array-div", // http://b/148815709 + "-Wno-tautological-overlap-compare", // http://b/148815696 }, " ")) // Extra cflags for external third-party projects to disable warnings that diff --git a/cc/config/global.go b/cc/config/global.go index 333885f14..d01dd843e 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -127,8 +127,8 @@ var ( // prebuilts/clang default settings. ClangDefaultBase = "prebuilts/clang/host" - ClangDefaultVersion = "clang-r370808b" - ClangDefaultShortVersion = "10.0.2" + ClangDefaultVersion = "clang-r377782b" + ClangDefaultShortVersion = "10.0.4" // Directories with warnings from Android.bp files. WarningAllowedProjects = []string{ diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go index 63b9d4872..25225b5cb 100644 --- a/cc/config/x86_darwin_host.go +++ b/cc/config/x86_darwin_host.go @@ -100,7 +100,7 @@ func init() { pctx.VariableFunc("macSdkRoot", func(ctx android.PackageVarContext) string { return xcrunSdk(ctx, "--show-sdk-path") }) - pctx.StaticVariable("macMinVersion", "10.8") + pctx.StaticVariable("macMinVersion", "10.10") pctx.VariableFunc("MacArPath", func(ctx android.PackageVarContext) string { return xcrun(ctx, "--find", "ar") }) diff --git a/cc/library.go b/cc/library.go index 0bddab534..bca9a9680 100644 --- a/cc/library.go +++ b/cc/library.go @@ -281,11 +281,9 @@ func (f *flagExporter) reexportSystemDirs(dirs ...android.Path) { } func (f *flagExporter) reexportFlags(flags ...string) { - for _, flag := range flags { - if strings.HasPrefix(flag, "-I") || strings.HasPrefix(flag, "-isystem") { - panic(fmt.Errorf("Exporting invalid flag %q: "+ - "use reexportDirs or reexportSystemDirs to export directories", flag)) - } + if android.PrefixInList(flags, "-I") || android.PrefixInList(flags, "-isystem") { + panic(fmt.Errorf("Exporting invalid flag %q: "+ + "use reexportDirs or reexportSystemDirs to export directories", flag)) } f.flags = append(f.flags, flags...) } @@ -256,6 +256,12 @@ func (pgo *pgo) begin(ctx BaseModuleContext) { } } + // PGO profile use is not feasible for a Clang coverage build because + // -fprofile-use and -fprofile-instr-generate are incompatible. + if ctx.DeviceConfig().ClangCoverageEnabled() { + return + } + if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") && proptools.BoolDefault(pgo.Properties.Pgo.Enable_profile_use, true) { if profileFile := pgo.Properties.getPgoProfileFile(ctx); profileFile.Valid() { diff --git a/cc/sanitize.go b/cc/sanitize.go index 6f9dbef63..5663aa7ae 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -350,6 +350,12 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { s.Diag.Cfi = nil } + // Also disable CFI if building against snapshot. + vndkVersion := ctx.DeviceConfig().VndkVersion() + if ctx.useVndk() && vndkVersion != "current" && vndkVersion != "" { + s.Cfi = nil + } + // HWASan ramdisk (which is built from recovery) goes over some bootloader limit. // Keep libc instrumented so that ramdisk / recovery can run hwasan-instrumented code if necessary. if (ctx.inRamdisk() || ctx.inRecovery()) && !strings.HasPrefix(ctx.ModuleDir(), "bionic/libc") { @@ -739,7 +745,11 @@ func sanitizerRuntimeDepsMutator(mctx android.TopDownMutatorContext) { return false } - if d, ok := child.(*Module); ok && d.static() && d.sanitize != nil { + d, ok := child.(*Module) + if !ok || !d.static() { + return false + } + if d.sanitize != nil { if enableMinimalRuntime(d.sanitize) { // If a static dependency is built with the minimal runtime, // make sure we include the ubsan minimal runtime. @@ -757,9 +767,18 @@ func sanitizerRuntimeDepsMutator(mctx android.TopDownMutatorContext) { } return true - } else { - return false } + + if p, ok := d.linker.(*vendorSnapshotLibraryDecorator); ok { + if Bool(p.properties.Sanitize_minimal_dep) { + c.sanitize.Properties.MinimalRuntimeDep = true + } + if Bool(p.properties.Sanitize_ubsan_dep) { + c.sanitize.Properties.UbsanRuntimeDep = true + } + } + + return false }) } } @@ -900,12 +919,31 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { // Note that by adding dependency with {static|shared}DepTag, the lib is // added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module if c.staticBinary() { + deps := append(extraStaticDeps, runtimeLibrary) + // If we're using snapshots and in vendor, redirect to snapshot whenever possible + if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() { + snapshots := vendorSnapshotStaticLibs(mctx.Config()) + for idx, dep := range deps { + if lib, ok := snapshots.get(dep, mctx.Arch().ArchType); ok { + deps[idx] = lib + } + } + } + // static executable gets static runtime libs mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{ {Mutator: "link", Variation: "static"}, c.ImageVariation(), - }...), StaticDepTag, append([]string{runtimeLibrary}, extraStaticDeps...)...) + }...), StaticDepTag, deps...) } else if !c.static() && !c.header() { + // If we're using snapshots and in vendor, redirect to snapshot whenever possible + if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() { + snapshots := vendorSnapshotSharedLibs(mctx.Config()) + if lib, ok := snapshots.get(runtimeLibrary, mctx.Arch().ArchType); ok { + runtimeLibrary = lib + } + } + // dynamic executable and shared libs get shared runtime libs mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{ {Mutator: "link", Variation: "shared"}, diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go index 1c872c2c9..8f48f869b 100644 --- a/cc/snapshot_utils.go +++ b/cc/snapshot_utils.go @@ -31,6 +31,33 @@ type snapshotLibraryInterface interface { var _ snapshotLibraryInterface = (*prebuiltLibraryLinker)(nil) var _ snapshotLibraryInterface = (*libraryDecorator)(nil) +type snapshotMap struct { + snapshots map[string]string +} + +func newSnapshotMap() *snapshotMap { + return &snapshotMap{ + snapshots: make(map[string]string), + } +} + +func snapshotMapKey(name string, arch android.ArchType) string { + return name + ":" + arch.String() +} + +// Adds a snapshot name for given module name and architecture. +// e.g. add("libbase", X86, "libbase.vndk.29.x86") +func (s *snapshotMap) add(name string, arch android.ArchType, snapshot string) { + s.snapshots[snapshotMapKey(name, arch)] = snapshot +} + +// Returns snapshot name for given module name and architecture, if found. +// e.g. get("libcutils", X86) => "libcutils.vndk.29.x86", true +func (s *snapshotMap) get(name string, arch android.ArchType) (snapshot string, found bool) { + snapshot, found = s.snapshots[snapshotMapKey(name, arch)] + return snapshot, found +} + func exportedHeaders(ctx android.SingletonContext, l exportedFlagsProducer) android.Paths { var ret android.Paths @@ -151,6 +151,14 @@ func needsLibAndroidSupport(ctx BaseModuleContext) bool { return version < 21 } +func staticUnwinder(ctx android.BaseModuleContext) string { + if ctx.Arch().ArchType == android.Arm { + return "libunwind_llvm" + } else { + return "libgcc_stripped" + } +} + func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps { switch stl.Properties.SelectedStl { case "libstdc++": @@ -172,16 +180,16 @@ func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps { } if ctx.toolchain().Bionic() { if ctx.staticBinary() { - deps.StaticLibs = append(deps.StaticLibs, "libm", "libc") - if ctx.Arch().ArchType == android.Arm { - deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm") - } else { - deps.StaticLibs = append(deps.StaticLibs, "libgcc_stripped") - } + deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", staticUnwinder(ctx)) + } else { + deps.StaticUnwinderIfLegacy = true } } case "": // None or error. + if ctx.toolchain().Bionic() && ctx.Module().Name() == "libc++" { + deps.StaticUnwinderIfLegacy = true + } case "ndk_system": // TODO: Make a system STL prebuilt for the NDK. // The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go index d952a4cb1..d92caa1e1 100644 --- a/cc/vendor_snapshot.go +++ b/cc/vendor_snapshot.go @@ -18,14 +18,358 @@ import ( "path/filepath" "sort" "strings" + "sync" "github.com/google/blueprint/proptools" "android/soong/android" ) +const ( + vendorSnapshotHeaderSuffix = ".vendor_header." + vendorSnapshotSharedSuffix = ".vendor_shared." + vendorSnapshotStaticSuffix = ".vendor_static." + vendorSnapshotBinarySuffix = ".vendor_binary." +) + +var ( + vendorSnapshotsLock sync.Mutex + vendorSuffixModulesKey = android.NewOnceKey("vendorSuffixModules") + vendorSnapshotHeaderLibsKey = android.NewOnceKey("vendorSnapshotHeaderLibs") + vendorSnapshotStaticLibsKey = android.NewOnceKey("vendorSnapshotStaticLibs") + vendorSnapshotSharedLibsKey = android.NewOnceKey("vendorSnapshotSharedLibs") + vendorSnapshotBinariesKey = android.NewOnceKey("vendorSnapshotBinaries") +) + +// vendor snapshot maps hold names of vendor snapshot modules per arch. +func vendorSuffixModules(config android.Config) map[string]bool { + return config.Once(vendorSuffixModulesKey, func() interface{} { + return make(map[string]bool) + }).(map[string]bool) +} + +func vendorSnapshotHeaderLibs(config android.Config) *snapshotMap { + return config.Once(vendorSnapshotHeaderLibsKey, func() interface{} { + return newSnapshotMap() + }).(*snapshotMap) +} + +func vendorSnapshotSharedLibs(config android.Config) *snapshotMap { + return config.Once(vendorSnapshotSharedLibsKey, func() interface{} { + return newSnapshotMap() + }).(*snapshotMap) +} + +func vendorSnapshotStaticLibs(config android.Config) *snapshotMap { + return config.Once(vendorSnapshotStaticLibsKey, func() interface{} { + return newSnapshotMap() + }).(*snapshotMap) +} + +func vendorSnapshotBinaries(config android.Config) *snapshotMap { + return config.Once(vendorSnapshotBinariesKey, func() interface{} { + return newSnapshotMap() + }).(*snapshotMap) +} + +type vendorSnapshotLibraryProperties struct { + // snapshot version. + Version string + + // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64') + Target_arch string + + // Prebuilt file for each arch. + Src *string `android:"arch_variant"` + + // list of flags that will be used for any module that links against this module. + Export_flags []string `android:"arch_variant"` + + // Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols, + // etc). + Check_elf_files *bool + + // Whether this prebuilt needs to depend on sanitize ubsan runtime or not. + Sanitize_ubsan_dep *bool `android:"arch_variant"` + + // Whether this prebuilt needs to depend on sanitize minimal runtime or not. + Sanitize_minimal_dep *bool `android:"arch_variant"` +} + +type vendorSnapshotLibraryDecorator struct { + *libraryDecorator + properties vendorSnapshotLibraryProperties + androidMkVendorSuffix bool +} + +func (p *vendorSnapshotLibraryDecorator) Name(name string) string { + return name + p.NameSuffix() +} + +func (p *vendorSnapshotLibraryDecorator) NameSuffix() string { + versionSuffix := p.version() + if p.arch() != "" { + versionSuffix += "." + p.arch() + } + + var linkageSuffix string + if p.buildShared() { + linkageSuffix = vendorSnapshotSharedSuffix + } else if p.buildStatic() { + linkageSuffix = vendorSnapshotStaticSuffix + } else { + linkageSuffix = vendorSnapshotHeaderSuffix + } + + return linkageSuffix + versionSuffix +} + +func (p *vendorSnapshotLibraryDecorator) version() string { + return p.properties.Version +} + +func (p *vendorSnapshotLibraryDecorator) arch() string { + return p.properties.Target_arch +} + +func (p *vendorSnapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { + p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix()) + return p.libraryDecorator.linkerFlags(ctx, flags) +} + +func (p *vendorSnapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool { + arches := config.Arches() + if len(arches) == 0 || arches[0].ArchType.String() != p.arch() { + return false + } + if !p.header() && p.properties.Src == nil { + return false + } + return true +} + +func (p *vendorSnapshotLibraryDecorator) link(ctx ModuleContext, + flags Flags, deps PathDeps, objs Objects) android.Path { + m := ctx.Module().(*Module) + p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()] + + if p.header() { + return p.libraryDecorator.link(ctx, flags, deps, objs) + } + + if !p.matchesWithDevice(ctx.DeviceConfig()) { + return nil + } + + p.libraryDecorator.exportIncludes(ctx) + p.libraryDecorator.reexportFlags(p.properties.Export_flags...) + + in := android.PathForModuleSrc(ctx, *p.properties.Src) + p.unstrippedOutputFile = in + + if p.shared() { + libName := in.Base() + builderFlags := flagsToBuilderFlags(flags) + + // Optimize out relinking against shared libraries whose interface hasn't changed by + // depending on a table of contents file instead of the library itself. + tocFile := android.PathForModuleOut(ctx, libName+".toc") + p.tocFile = android.OptionalPathForPath(tocFile) + TransformSharedObjectToToc(ctx, in, tocFile, builderFlags) + } + + return in +} + +func (p *vendorSnapshotLibraryDecorator) nativeCoverage() bool { + return false +} + +func (p *vendorSnapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) { + if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) { + p.baseInstaller.install(ctx, file) + } +} + +type vendorSnapshotInterface interface { + version() string +} + +func vendorSnapshotLoadHook(ctx android.LoadHookContext, p vendorSnapshotInterface) { + if p.version() != ctx.DeviceConfig().VndkVersion() { + ctx.Module().Disable() + return + } +} + +func vendorSnapshotLibrary() (*Module, *vendorSnapshotLibraryDecorator) { + module, library := NewLibrary(android.DeviceSupported) + + module.stl = nil + module.sanitize = nil + library.StripProperties.Strip.None = BoolPtr(true) + + prebuilt := &vendorSnapshotLibraryDecorator{ + libraryDecorator: library, + } + + prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true) + prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true) + + // Prevent default system libs (libc, libm, and libdl) from being linked + if prebuilt.baseLinker.Properties.System_shared_libs == nil { + prebuilt.baseLinker.Properties.System_shared_libs = []string{} + } + + module.compiler = nil + module.linker = prebuilt + module.installer = prebuilt + + module.AddProperties( + &prebuilt.properties, + ) + + return module, prebuilt +} + +func VendorSnapshotSharedFactory() android.Module { + module, prebuilt := vendorSnapshotLibrary() + prebuilt.libraryDecorator.BuildOnlyShared() + android.AddLoadHook(module, func(ctx android.LoadHookContext) { + vendorSnapshotLoadHook(ctx, prebuilt) + }) + return module.Init() +} + +func VendorSnapshotStaticFactory() android.Module { + module, prebuilt := vendorSnapshotLibrary() + prebuilt.libraryDecorator.BuildOnlyStatic() + android.AddLoadHook(module, func(ctx android.LoadHookContext) { + vendorSnapshotLoadHook(ctx, prebuilt) + }) + return module.Init() +} + +func VendorSnapshotHeaderFactory() android.Module { + module, prebuilt := vendorSnapshotLibrary() + prebuilt.libraryDecorator.HeaderOnly() + android.AddLoadHook(module, func(ctx android.LoadHookContext) { + vendorSnapshotLoadHook(ctx, prebuilt) + }) + return module.Init() +} + +type vendorSnapshotBinaryProperties struct { + // snapshot version. + Version string + + // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64_ab') + Target_arch string + + // Prebuilt file for each arch. + Src *string `android:"arch_variant"` +} + +type vendorSnapshotBinaryDecorator struct { + *binaryDecorator + properties vendorSnapshotBinaryProperties + androidMkVendorSuffix bool +} + +func (p *vendorSnapshotBinaryDecorator) Name(name string) string { + return name + p.NameSuffix() +} + +func (p *vendorSnapshotBinaryDecorator) NameSuffix() string { + versionSuffix := p.version() + if p.arch() != "" { + versionSuffix += "." + p.arch() + } + return vendorSnapshotBinarySuffix + versionSuffix +} + +func (p *vendorSnapshotBinaryDecorator) version() string { + return p.properties.Version +} + +func (p *vendorSnapshotBinaryDecorator) arch() string { + return p.properties.Target_arch +} + +func (p *vendorSnapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool { + if config.DeviceArch() != p.arch() { + return false + } + if p.properties.Src == nil { + return false + } + return true +} + +func (p *vendorSnapshotBinaryDecorator) link(ctx ModuleContext, + flags Flags, deps PathDeps, objs Objects) android.Path { + if !p.matchesWithDevice(ctx.DeviceConfig()) { + return nil + } + + in := android.PathForModuleSrc(ctx, *p.properties.Src) + builderFlags := flagsToBuilderFlags(flags) + p.unstrippedOutputFile = in + binName := in.Base() + if p.needsStrip(ctx) { + stripped := android.PathForModuleOut(ctx, "stripped", binName) + p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags) + in = stripped + } + + m := ctx.Module().(*Module) + p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()] + + // use cpExecutable to make it executable + outputFile := android.PathForModuleOut(ctx, binName) + ctx.Build(pctx, android.BuildParams{ + Rule: android.CpExecutable, + Description: "prebuilt", + Output: outputFile, + Input: in, + }) + + return outputFile +} + +func VendorSnapshotBinaryFactory() android.Module { + module, binary := NewBinary(android.DeviceSupported) + binary.baseLinker.Properties.No_libcrt = BoolPtr(true) + binary.baseLinker.Properties.Nocrt = BoolPtr(true) + + // Prevent default system libs (libc, libm, and libdl) from being linked + if binary.baseLinker.Properties.System_shared_libs == nil { + binary.baseLinker.Properties.System_shared_libs = []string{} + } + + prebuilt := &vendorSnapshotBinaryDecorator{ + binaryDecorator: binary, + } + + module.compiler = nil + module.sanitize = nil + module.stl = nil + module.linker = prebuilt + + android.AddLoadHook(module, func(ctx android.LoadHookContext) { + vendorSnapshotLoadHook(ctx, prebuilt) + }) + + module.AddProperties(&prebuilt.properties) + return module.Init() +} + func init() { android.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton) + android.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory) + android.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory) + android.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory) + android.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory) } func VendorSnapshotSingleton() android.Singleton { @@ -367,3 +711,120 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont func (c *vendorSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) { ctx.Strict("SOONG_VENDOR_SNAPSHOT_ZIP", c.vendorSnapshotZipFile.String()) } + +type snapshotInterface interface { + matchesWithDevice(config android.DeviceConfig) bool +} + +var _ snapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil) +var _ snapshotInterface = (*vendorSnapshotLibraryDecorator)(nil) +var _ snapshotInterface = (*vendorSnapshotBinaryDecorator)(nil) + +// gathers all snapshot modules for vendor, and disable unnecessary snapshots +// TODO(b/145966707): remove mutator and utilize android.Prebuilt to override source modules +func VendorSnapshotMutator(ctx android.BottomUpMutatorContext) { + vndkVersion := ctx.DeviceConfig().VndkVersion() + // don't need snapshot if current + if vndkVersion == "current" || vndkVersion == "" { + return + } + + module, ok := ctx.Module().(*Module) + if !ok || !module.Enabled() || module.VndkVersion() != vndkVersion { + return + } + + snapshot, ok := module.linker.(snapshotInterface) + if !ok { + return + } + + if !snapshot.matchesWithDevice(ctx.DeviceConfig()) { + // Disable unnecessary snapshot module, but do not disable + // vndk_prebuilt_shared because they might be packed into vndk APEX + if !module.IsVndk() { + module.Disable() + } + return + } + + var snapshotMap *snapshotMap + + if lib, ok := module.linker.(libraryInterface); ok { + if lib.static() { + snapshotMap = vendorSnapshotStaticLibs(ctx.Config()) + } else if lib.shared() { + snapshotMap = vendorSnapshotSharedLibs(ctx.Config()) + } else { + // header + snapshotMap = vendorSnapshotHeaderLibs(ctx.Config()) + } + } else if _, ok := module.linker.(*vendorSnapshotBinaryDecorator); ok { + snapshotMap = vendorSnapshotBinaries(ctx.Config()) + } else { + return + } + + vendorSnapshotsLock.Lock() + defer vendorSnapshotsLock.Unlock() + snapshotMap.add(module.BaseModuleName(), ctx.Arch().ArchType, ctx.ModuleName()) +} + +// Disables source modules which have snapshots +func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) { + vndkVersion := ctx.DeviceConfig().VndkVersion() + // don't need snapshot if current + if vndkVersion == "current" || vndkVersion == "" { + return + } + + module, ok := ctx.Module().(*Module) + if !ok { + return + } + + if module.HasVendorVariant() { + vendorSnapshotsLock.Lock() + defer vendorSnapshotsLock.Unlock() + + vendorSuffixModules(ctx.Config())[ctx.ModuleName()] = true + } + + if module.isSnapshotPrebuilt() || module.VndkVersion() != ctx.DeviceConfig().VndkVersion() { + // only non-snapshot modules with BOARD_VNDK_VERSION + return + } + + var snapshotMap *snapshotMap + + if lib, ok := module.linker.(libraryInterface); ok { + if lib.static() { + snapshotMap = vendorSnapshotStaticLibs(ctx.Config()) + } else if lib.shared() { + snapshotMap = vendorSnapshotSharedLibs(ctx.Config()) + } else { + // header + snapshotMap = vendorSnapshotHeaderLibs(ctx.Config()) + } + } else if _, ok := module.linker.(*binaryDecorator); ok { + snapshotMap = vendorSnapshotBinaries(ctx.Config()) + } else if _, ok := module.linker.(*prebuiltBinaryLinker); ok { + snapshotMap = vendorSnapshotBinaries(ctx.Config()) + } else { + return + } + + if _, ok := snapshotMap.get(ctx.ModuleName(), ctx.Arch().ArchType); !ok { + // Corresponding snapshot doesn't exist + return + } + + // Disables source modules if corresponding snapshot exists. + if lib, ok := module.linker.(libraryInterface); ok && lib.buildStatic() && lib.buildShared() { + // But do not disable because the shared variant depends on the static variant. + module.SkipInstall() + module.Properties.HideFromMake = true + } else { + module.Disable() + } +} diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go index c941c4691..50bc32592 100644 --- a/cc/vndk_prebuilt.go +++ b/cc/vndk_prebuilt.go @@ -31,7 +31,8 @@ var ( // // vndk_prebuilt_shared { // name: "libfoo", -// version: "27.1.0", +// version: "27", +// target_arch: "arm64", // vendor_available: true, // vndk: { // enabled: true, @@ -61,10 +62,6 @@ type vndkPrebuiltProperties struct { // Prebuilt files for each arch. Srcs []string `android:"arch_variant"` - // list of directories relative to the Blueprints file that will be added to the include - // path (using -isystem) for any module that links against this module. - Export_system_include_dirs []string `android:"arch_variant"` - // list of flags that will be used for any module that links against this module. Export_flags []string `android:"arch_variant"` @@ -137,11 +134,26 @@ func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext, if len(p.properties.Srcs) > 0 && p.shared() { p.libraryDecorator.exportIncludes(ctx) - p.libraryDecorator.reexportSystemDirs( - android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...) p.libraryDecorator.reexportFlags(p.properties.Export_flags...) // current VNDK prebuilts are only shared libs. - return p.singleSourcePath(ctx) + + in := p.singleSourcePath(ctx) + builderFlags := flagsToBuilderFlags(flags) + p.unstrippedOutputFile = in + libName := in.Base() + if p.needsStrip(ctx) { + stripped := android.PathForModuleOut(ctx, "stripped", libName) + p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags) + in = stripped + } + + // Optimize out relinking against shared libraries whose interface hasn't changed by + // depending on a table of contents file instead of the library itself. + tocFile := android.PathForModuleOut(ctx, libName+".toc") + p.tocFile = android.OptionalPathForPath(tocFile) + TransformSharedObjectToToc(ctx, in, tocFile, builderFlags) + + return in } ctx.Module().SkipInstall() @@ -212,6 +224,15 @@ func vndkPrebuiltSharedLibrary() *Module { &prebuilt.properties, ) + android.AddLoadHook(module, func(ctx android.LoadHookContext) { + // Only vndk snapshots of BOARD_VNDK_VERSION will be used when building. + if prebuilt.version() != ctx.DeviceConfig().VndkVersion() { + module.SkipInstall() + module.Properties.HideFromMake = true + return + } + }) + return module } @@ -220,7 +241,8 @@ func vndkPrebuiltSharedLibrary() *Module { // // vndk_prebuilt_shared { // name: "libfoo", -// version: "27.1.0", +// version: "27", +// target_arch: "arm64", // vendor_available: true, // vndk: { // enabled: true, diff --git a/cc/xom.go b/cc/xom.go deleted file mode 100644 index ce817aad6..000000000 --- a/cc/xom.go +++ /dev/null @@ -1,79 +0,0 @@ -// 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 ( - "android/soong/android" -) - -type XomProperties struct { - Xom *bool -} - -type xom struct { - Properties XomProperties -} - -func (xom *xom) props() []interface{} { - return []interface{}{&xom.Properties} -} - -func (xom *xom) begin(ctx BaseModuleContext) {} - -func (xom *xom) deps(ctx BaseModuleContext, deps Deps) Deps { - return deps -} - -func (xom *xom) flags(ctx ModuleContext, flags Flags) Flags { - disableXom := false - - if !ctx.Config().EnableXOM() || ctx.Config().XOMDisabledForPath(ctx.ModuleDir()) { - disableXom = true - } - - if xom.Properties.Xom != nil && !*xom.Properties.Xom { - return flags - } - - // If any static dependencies have XOM disabled, we should disable XOM in this module, - // the assumption being if it's been explicitly disabled then there's probably incompatible - // code in the library which may get pulled in. - if !disableXom { - ctx.VisitDirectDeps(func(m android.Module) { - cc, ok := m.(*Module) - if !ok || cc.xom == nil || !cc.static() { - return - } - if cc.xom.Properties.Xom != nil && !*cc.xom.Properties.Xom { - disableXom = true - return - } - }) - } - - // Enable execute-only if none of the dependencies disable it, - // also if it's explicitly set true (allows overriding dependencies disabling it). - if !disableXom || (xom.Properties.Xom != nil && *xom.Properties.Xom) { - // XOM is only supported on AArch64 when using lld. - if ctx.Arch().ArchType == android.Arm64 && ctx.useClangLld(ctx) { - flags.Local.LdFlags = append(flags.Local.LdFlags, - "-Wl,--execute-only", - "-Wl,-z,separate-code", - ) - } - } - - return flags -} |