Merge "Add tests for converting license in androidmk"
diff --git a/android/androidmk.go b/android/androidmk.go
index 0adc2a6..1f03aa8 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -887,6 +887,10 @@
return nil
}
+func ShouldSkipAndroidMkProcessing(module Module) bool {
+ return shouldSkipAndroidMkProcessing(module.base())
+}
+
func shouldSkipAndroidMkProcessing(module *ModuleBase) bool {
if !module.commonProperties.NamespaceExportedToMake {
// TODO(jeffrygaston) do we want to validate that there are no modules being
diff --git a/android/apex.go b/android/apex.go
index 461faf7..cf1bcfe 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -908,16 +908,18 @@
//
// Return true if the `to` module should be visited, false otherwise.
type PayloadDepsCallback func(ctx ModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool
+type WalkPayloadDepsFunc func(ctx ModuleContext, do PayloadDepsCallback)
-// UpdatableModule represents updatable APEX/APK
-type UpdatableModule interface {
+// ModuleWithMinSdkVersionCheck represents a module that implements min_sdk_version checks
+type ModuleWithMinSdkVersionCheck interface {
Module
- WalkPayloadDeps(ctx ModuleContext, do PayloadDepsCallback)
+ MinSdkVersion(ctx EarlyModuleContext) SdkSpec
+ CheckMinSdkVersion(ctx ModuleContext)
}
// CheckMinSdkVersion checks if every dependency of an updatable module sets min_sdk_version
// accordingly
-func CheckMinSdkVersion(m UpdatableModule, ctx ModuleContext, minSdkVersion ApiLevel) {
+func CheckMinSdkVersion(ctx ModuleContext, minSdkVersion ApiLevel, walk WalkPayloadDepsFunc) {
// do not enforce min_sdk_version for host
if ctx.Host() {
return
@@ -933,7 +935,7 @@
return
}
- m.WalkPayloadDeps(ctx, func(ctx ModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool {
+ walk(ctx, func(ctx ModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool {
if externalDep {
// external deps are outside the payload boundary, which is "stable"
// interface. We don't have to check min_sdk_version for external
@@ -943,6 +945,14 @@
if am, ok := from.(DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
return false
}
+ if m, ok := to.(ModuleWithMinSdkVersionCheck); ok {
+ // This dependency performs its own min_sdk_version check, just make sure it sets min_sdk_version
+ // to trigger the check.
+ if !m.MinSdkVersion(ctx).Specified() {
+ ctx.OtherModuleErrorf(m, "must set min_sdk_version")
+ }
+ return false
+ }
if err := to.ShouldSupportSdkVersion(ctx, minSdkVersion); err != nil {
toName := ctx.OtherModuleName(to)
if ver, ok := minSdkVersionAllowlist[toName]; !ok || ver.GreaterThan(minSdkVersion) {
diff --git a/android/bazel.go b/android/bazel.go
index 40c971f..169f6ba 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -226,13 +226,50 @@
// Configure modules in these directories to enable bp2build_available: true or false by default.
bp2buildDefaultConfig = Bp2BuildConfig{
- "art/libdexfile": Bp2BuildDefaultTrueRecursively,
- "bionic": Bp2BuildDefaultTrueRecursively,
+ "art/libdexfile": Bp2BuildDefaultTrueRecursively,
+ "bionic": Bp2BuildDefaultTrueRecursively,
+ "bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
"build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively,
"build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
"build/soong": Bp2BuildDefaultTrue,
"build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir
+ "build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue,
+ "build/soong/cc/symbolfile": Bp2BuildDefaultTrue,
"cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively,
+ "development/apps/DevelopmentSettings": Bp2BuildDefaultTrue,
+ "development/apps/Fallback": Bp2BuildDefaultTrue,
+ "development/apps/WidgetPreview": Bp2BuildDefaultTrue,
+ "development/samples/BasicGLSurfaceView": Bp2BuildDefaultTrue,
+ "development/samples/BluetoothChat": Bp2BuildDefaultTrue,
+ "development/samples/BrokenKeyDerivation": Bp2BuildDefaultTrue,
+ "development/samples/Compass": Bp2BuildDefaultTrue,
+ "development/samples/ContactManager": Bp2BuildDefaultTrue,
+ "development/samples/FixedGridLayout": Bp2BuildDefaultTrue,
+ "development/samples/HelloEffects": Bp2BuildDefaultTrue,
+ "development/samples/Home": Bp2BuildDefaultTrue,
+ "development/samples/HoneycombGallery": Bp2BuildDefaultTrue,
+ "development/samples/JetBoy": Bp2BuildDefaultTrue,
+ "development/samples/KeyChainDemo": Bp2BuildDefaultTrue,
+ "development/samples/LceDemo": Bp2BuildDefaultTrue,
+ "development/samples/LunarLander": Bp2BuildDefaultTrue,
+ "development/samples/MultiResolution": Bp2BuildDefaultTrue,
+ "development/samples/MultiWindow": Bp2BuildDefaultTrue,
+ "development/samples/NotePad": Bp2BuildDefaultTrue,
+ "development/samples/Obb": Bp2BuildDefaultTrue,
+ "development/samples/RSSReader": Bp2BuildDefaultTrue,
+ "development/samples/ReceiveShareDemo": Bp2BuildDefaultTrue,
+ "development/samples/SearchableDictionary": Bp2BuildDefaultTrue,
+ "development/samples/SipDemo": Bp2BuildDefaultTrue,
+ "development/samples/SkeletonApp": Bp2BuildDefaultTrue,
+ "development/samples/Snake": Bp2BuildDefaultTrue,
+ "development/samples/SpellChecker/": Bp2BuildDefaultTrueRecursively,
+ "development/samples/ThemedNavBarKeyboard": Bp2BuildDefaultTrue,
+ "development/samples/ToyVpn": Bp2BuildDefaultTrue,
+ "development/samples/TtsEngine": Bp2BuildDefaultTrue,
+ "development/samples/USB/AdbTest": Bp2BuildDefaultTrue,
+ "development/samples/USB/MissileLauncher": Bp2BuildDefaultTrue,
+ "development/samples/VoiceRecognitionService": Bp2BuildDefaultTrue,
+ "development/samples/VoicemailProviderDemo": Bp2BuildDefaultTrue,
"development/sdk": Bp2BuildDefaultTrueRecursively,
"external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively,
"external/boringssl": Bp2BuildDefaultTrueRecursively,
@@ -259,9 +296,19 @@
"external/selinux/libselinux": Bp2BuildDefaultTrueRecursively,
"external/zlib": Bp2BuildDefaultTrueRecursively,
"external/zstd": Bp2BuildDefaultTrueRecursively,
+ "frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue,
+ "frameworks/base/startop/apps/test": Bp2BuildDefaultTrue,
"frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively,
+ "frameworks/native/opengl/tests/gl2_cameraeye": Bp2BuildDefaultTrue,
+ "frameworks/native/opengl/tests/gl2_java": Bp2BuildDefaultTrue,
+ "frameworks/native/opengl/tests/testLatency": Bp2BuildDefaultTrue,
+ "frameworks/native/opengl/tests/testPauseResume": Bp2BuildDefaultTrue,
+ "frameworks/native/opengl/tests/testViewport": Bp2BuildDefaultTrue,
"frameworks/proto_logging/stats/stats_log_api_gen": Bp2BuildDefaultTrueRecursively,
"libnativehelper": Bp2BuildDefaultTrueRecursively,
+ "packages/apps/DevCamera": Bp2BuildDefaultTrue,
+ "packages/apps/HTMLViewer": Bp2BuildDefaultTrue,
+ "packages/apps/Protips": Bp2BuildDefaultTrue,
"packages/modules/adb": Bp2BuildDefaultTrue,
"packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively,
"packages/modules/adb/libs": Bp2BuildDefaultTrueRecursively,
@@ -269,6 +316,9 @@
"packages/modules/adb/pairing_connection": Bp2BuildDefaultTrueRecursively,
"packages/modules/adb/proto": Bp2BuildDefaultTrueRecursively,
"packages/modules/adb/tls": Bp2BuildDefaultTrueRecursively,
+ "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultTrue,
+ "packages/screensavers/Basic": Bp2BuildDefaultTrue,
+ "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultTrue,
"prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively,
"system/apex": Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures
"system/core/debuggerd": Bp2BuildDefaultTrue,
@@ -336,9 +386,8 @@
"host_bionic_linker_asm", // depends on extract_linker, a go binary.
"host_bionic_linker_script", // depends on extract_linker, a go binary.
- "pbtombstone", // depends on libprotobuf-cpp-lite, libtombstone_proto
- "crash_dump", // depends on unconverted module libprotobuf-cpp-lite
- "libprotobuf-cpp-full", "libprotobuf-cpp-lite", // Unsupported product&vendor suffix. b/204811222 and b/204810610.
+ "pbtombstone", // depends on libprotobuf-cpp-lite, libtombstone_proto
+ "crash_dump", // depends on unconverted module libprotobuf-cpp-lite
"libunwindstack_local", "libunwindstack_utils", // depends on unconverted module libunwindstack
"libunwindstack", // depends on libdexfile_support, of unsupported module type art_cc_library_static
@@ -373,19 +422,10 @@
// APEX support
"com.android.runtime", // http://b/194746715, apex, depends on 'libc_malloc_debug'
- "libadb_crypto", // Depends on libadb_protos
- "libadb_crypto_static", // Depends on libadb_protos_static
- "libadb_pairing_connection", // Depends on libadb_protos
- "libadb_pairing_connection_static", // Depends on libadb_protos_static
- "libadb_pairing_server", // Depends on libadb_protos
- "libadb_pairing_server_static", // Depends on libadb_protos_static
- "libadbd", // Depends on libadbd_core
- "libadbd_core", // Depends on libadb_protos
- "libadbd_services", // Depends on libadb_protos
+ "libadbd_core", // http://b/208481704: requijres use_version_lib
+ "libadbd_services", // http://b/208481704: requires use_version_lib
- "libadb_protos_static", // b/200601772: Requires cc_library proto support
- "libadb_protos", // b/200601772: Requires cc_library proto support
- "libapp_processes_protos_lite", // b/200601772: Requires cc_library proto support
+ "libadbd", // depends on unconverted modules: libadbd_core, libadbd_services
"libgtest_ndk_c++", // b/201816222: Requires sdk_version support.
"libgtest_main_ndk_c++", // b/201816222: Requires sdk_version support.
@@ -401,6 +441,7 @@
"mdnsd", // http://b/202876379 has arch-variant static_executable
"acvp_modulewrapper", // disabled for android x86/x86_64
+ "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
}
// Per-module denylist of cc_library modules to only generate the static
@@ -418,6 +459,11 @@
"cap_names.h", // TODO(b/204913827) runfiles need to be handled in mixed builds
"libcap", // TODO(b/204913827) runfiles need to be handled in mixed builds
"libprotobuf-cpp-full", "libprotobuf-cpp-lite", // Unsupported product&vendor suffix. b/204811222 and b/204810610.
+
+ // Depends on libprotobuf-cpp-*
+ "libadb_pairing_connection",
+ "libadb_pairing_connection_static",
+ "libadb_pairing_server", "libadb_pairing_server_static",
}
// Used for quicker lookups
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 729c73c..62e6156 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -279,6 +279,16 @@
return newPaths
}
+// Converts root-relative Paths to a list of bazel.Label relative to the module in ctx.
+func RootToModuleRelativePaths(ctx BazelConversionPathContext, paths Paths) []bazel.Label {
+ var newPaths []bazel.Label
+ for _, path := range PathsWithModuleSrcSubDir(ctx, paths, "") {
+ s := path.Rel()
+ newPaths = append(newPaths, bazel.Label{Label: s})
+ }
+ return newPaths
+}
+
// expandSrcsForBazel returns bazel.LabelList with paths rooted from the module's local source
// directory and Bazel target labels, excluding those included in the excludes argument (which
// should already be expanded to resolve references to Soong-modules). Valid elements of paths
@@ -328,12 +338,7 @@
// e.g. turn "math/*.c" in
// external/arm-optimized-routines to external/arm-optimized-routines/math/*.c
rootRelativeGlobPath := pathForModuleSrc(ctx, p).String()
- globbedPaths := GlobFiles(ctx, rootRelativeGlobPath, rootRelativeExpandedExcludes)
- globbedPaths = PathsWithModuleSrcSubDir(ctx, globbedPaths, "")
- for _, path := range globbedPaths {
- s := path.Rel()
- expandedPaths = append(expandedPaths, bazel.Label{Label: s})
- }
+ expandedPaths = RootToModuleRelativePaths(ctx, GlobFiles(ctx, rootRelativeGlobPath, rootRelativeExpandedExcludes))
} else {
if !InList(p, expandedExcludes) {
expandedPaths = append(expandedPaths, bazel.Label{Label: p})
diff --git a/android/config.go b/android/config.go
index ddad1f5..8e01e18 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1194,10 +1194,6 @@
return c.config.productVariables.DeviceKernelHeaders
}
-func (c *deviceConfig) SamplingPGO() bool {
- return Bool(c.config.productVariables.SamplingPGO)
-}
-
// JavaCoverageEnabledForPath returns whether Java code coverage is enabled for
// path. Coverage is enabled by default when the product variable
// JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is
diff --git a/android/module.go b/android/module.go
index b500f01..c2cb617 100644
--- a/android/module.go
+++ b/android/module.go
@@ -419,7 +419,6 @@
PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec
CheckbuildFile(srcPath Path)
- TidyFile(srcPath WritablePath)
InstallInData() bool
InstallInTestcases() bool
@@ -1200,7 +1199,6 @@
installFiles InstallPaths
installFilesDepSet *installPathsDepSet
checkbuildFiles Paths
- tidyFiles WritablePaths
packagingSpecs []PackagingSpec
packagingSpecsDepSet *packagingSpecsDepSet
noticeFiles Paths
@@ -1216,7 +1214,6 @@
// Only set on the final variant of each module
installTarget WritablePath
checkbuildTarget WritablePath
- tidyTarget WritablePath
blueprintDir string
hooks hooks
@@ -1779,17 +1776,15 @@
func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
var allInstalledFiles InstallPaths
var allCheckbuildFiles Paths
- var allTidyFiles WritablePaths
ctx.VisitAllModuleVariants(func(module Module) {
a := module.base()
allInstalledFiles = append(allInstalledFiles, a.installFiles...)
- // A module's -{checkbuild,tidy} phony targets should
+ // A module's -checkbuild phony targets should
// not be created if the module is not exported to make.
// Those could depend on the build target and fail to compile
// for the current build target.
if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(a) {
allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
- allTidyFiles = append(allTidyFiles, a.tidyFiles...)
}
})
@@ -1814,13 +1809,6 @@
deps = append(deps, m.checkbuildTarget)
}
- if len(allTidyFiles) > 0 {
- name := namespacePrefix + ctx.ModuleName() + "-tidy"
- ctx.Phony(name, allTidyFiles.Paths()...)
- m.tidyTarget = PathForPhony(ctx, name)
- deps = append(deps, m.tidyTarget)
- }
-
if len(deps) > 0 {
suffix := ""
if ctx.Config().KatiEnabled() {
@@ -2029,7 +2017,6 @@
m.installFiles = append(m.installFiles, ctx.installFiles...)
m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
- m.tidyFiles = append(m.tidyFiles, ctx.tidyFiles...)
m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...)
m.katiInstalls = append(m.katiInstalls, ctx.katiInstalls...)
m.katiSymlinks = append(m.katiSymlinks, ctx.katiSymlinks...)
@@ -2227,7 +2214,6 @@
packagingSpecs []PackagingSpec
installFiles InstallPaths
checkbuildFiles Paths
- tidyFiles WritablePaths
module Module
phonies map[string]Paths
@@ -3065,10 +3051,6 @@
m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
}
-func (m *moduleContext) TidyFile(srcPath WritablePath) {
- m.tidyFiles = append(m.tidyFiles, srcPath)
-}
-
func (m *moduleContext) blueprintModuleContext() blueprint.ModuleContext {
return m.bp
}
@@ -3327,9 +3309,10 @@
type buildTargetSingleton struct{}
-func addAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) []string {
+func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) {
// Ensure ancestor directories are in dirMap
// Make directories build their direct subdirectories
+ // Returns a slice of all directories and a slice of top-level directories.
dirs := SortedStringKeys(dirMap)
for _, dir := range dirs {
dir := parentDir(dir)
@@ -3342,34 +3325,31 @@
}
}
dirs = SortedStringKeys(dirMap)
+ var topDirs []string
for _, dir := range dirs {
p := parentDir(dir)
if p != "." && p != "/" {
dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir)))
+ } else if dir != "." && dir != "/" && dir != "" {
+ topDirs = append(topDirs, dir)
}
}
- return SortedStringKeys(dirMap)
+ return SortedStringKeys(dirMap), topDirs
}
func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
var checkbuildDeps Paths
- var tidyDeps Paths
mmTarget := func(dir string) string {
return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
}
- mmTidyTarget := func(dir string) string {
- return "tidy-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
- }
modulesInDir := make(map[string]Paths)
- tidyModulesInDir := make(map[string]Paths)
ctx.VisitAllModules(func(module Module) {
blueprintDir := module.base().blueprintDir
installTarget := module.base().installTarget
checkbuildTarget := module.base().checkbuildTarget
- tidyTarget := module.base().tidyTarget
if checkbuildTarget != nil {
checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
@@ -3379,16 +3359,6 @@
if installTarget != nil {
modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
}
-
- if tidyTarget != nil {
- tidyDeps = append(tidyDeps, tidyTarget)
- // tidyTarget is in modulesInDir so it will be built with "mm".
- modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], tidyTarget)
- // tidyModulesInDir contains tidyTarget but not checkbuildTarget
- // or installTarget, so tidy targets in a directory can be built
- // without other checkbuild or install targets.
- tidyModulesInDir[blueprintDir] = append(tidyModulesInDir[blueprintDir], tidyTarget)
- }
})
suffix := ""
@@ -3399,24 +3369,12 @@
// Create a top-level checkbuild target that depends on all modules
ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
- // Create a top-level tidy target that depends on all modules
- ctx.Phony("tidy"+suffix, tidyDeps...)
-
- dirs := addAncestors(ctx, tidyModulesInDir, mmTidyTarget)
-
- // Kati does not generate tidy-* phony targets yet.
- // Create a tidy-<directory> target that depends on all subdirectories
- // and modules in the directory.
- for _, dir := range dirs {
- ctx.Phony(mmTidyTarget(dir), tidyModulesInDir[dir]...)
- }
-
// Make will generate the MODULES-IN-* targets
if ctx.Config().KatiEnabled() {
return
}
- dirs = addAncestors(ctx, modulesInDir, mmTarget)
+ dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget)
// Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
// depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
diff --git a/android/mutator.go b/android/mutator.go
index 0a93517..bf1cf80 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -221,6 +221,13 @@
// See http://b/192523357
var bp2buildLock sync.Mutex
+// A minimal context for Bp2build conversion
+type Bp2buildMutatorContext interface {
+ BazelConversionPathContext
+
+ CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{})
+}
+
// RegisterBp2BuildMutator registers specially crafted mutators for
// converting Blueprint/Android modules into special modules that can
// be code-generated into Bazel BUILD targets.
diff --git a/android/proto.go b/android/proto.go
index 0be7893..64d4d05 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -15,12 +15,17 @@
package android
import (
+ "android/soong/bazel"
"strings"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
+const (
+ canonicalPathFromRootDefault = true
+)
+
// TODO(ccross): protos are often used to communicate between multiple modules. If the only
// way to convert a proto to source is to reference it as a source file, and external modules cannot
// reference source files in other modules, then every module that owns a proto file will need to
@@ -90,7 +95,7 @@
Flags: flags,
Deps: deps,
OutTypeFlag: protoOutFlag,
- CanonicalPathFromRoot: proptools.BoolDefault(p.Proto.Canonical_path_from_root, true),
+ CanonicalPathFromRoot: proptools.BoolDefault(p.Proto.Canonical_path_from_root, canonicalPathFromRootDefault),
Dir: PathForModuleGen(ctx, "proto"),
SubDir: PathForModuleGen(ctx, "proto", ctx.ModuleDir()),
}
@@ -146,3 +151,57 @@
rule.Command().
BuiltTool("dep_fixer").Flag(depFile.String())
}
+
+// Bp2buildProtoInfo contains information necessary to pass on to language specific conversion.
+type Bp2buildProtoInfo struct {
+ Type *string
+ Name string
+}
+
+type protoAttrs struct {
+ Srcs bazel.LabelListAttribute
+ Strip_import_prefix *string
+}
+
+// Bp2buildProtoProperties converts proto properties, creating a proto_library and returning the
+// information necessary for language-specific handling.
+func Bp2buildProtoProperties(ctx Bp2buildMutatorContext, module Module, srcs bazel.LabelListAttribute) (Bp2buildProtoInfo, bool) {
+ var info Bp2buildProtoInfo
+ if srcs.IsEmpty() {
+ return info, false
+ }
+ m := module.base()
+
+ info.Name = m.Name() + "_proto"
+ attrs := protoAttrs{
+ Srcs: srcs,
+ }
+
+ for axis, configToProps := range m.GetArchVariantProperties(ctx, &ProtoProperties{}) {
+ for _, rawProps := range configToProps {
+ var props *ProtoProperties
+ var ok bool
+ if props, ok = rawProps.(*ProtoProperties); !ok {
+ ctx.ModuleErrorf("Could not cast ProtoProperties to expected type")
+ }
+ if axis == bazel.NoConfigAxis {
+ info.Type = props.Proto.Type
+
+ if proptools.BoolDefault(props.Proto.Canonical_path_from_root, canonicalPathFromRootDefault) {
+ // an empty string indicates to strips the package path
+ path := ""
+ attrs.Strip_import_prefix = &path
+ }
+ } else if props.Proto.Type != info.Type && props.Proto.Type != nil {
+ ctx.ModuleErrorf("Cannot handle arch-variant types for protos at this time.")
+ }
+ }
+ }
+
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
+ CommonAttributes{Name: info.Name},
+ &attrs)
+
+ return info, true
+}
diff --git a/android/variable.go b/android/variable.go
index a29c6f8..158d264 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -299,8 +299,6 @@
ClangTidy *bool `json:",omitempty"`
TidyChecks *string `json:",omitempty"`
- SamplingPGO *bool `json:",omitempty"`
-
JavaCoveragePaths []string `json:",omitempty"`
JavaCoverageExcludePaths []string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 89b5f21..bb9207d 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -130,6 +130,13 @@
// symlinking to the system libs. Default is true.
Updatable *bool
+ // Marks that this APEX is designed to be updatable in the future, although it's not
+ // updatable yet. This is used to mimic some of the build behaviors that are applied only to
+ // updatable APEXes. Currently, this disables the size optimization, so that the size of
+ // APEX will not increase when the APEX is actually marked as truly updatable. Default is
+ // false.
+ Future_updatable *bool
+
// Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
// false`. Default is false.
Platform_apis *bool
@@ -1306,6 +1313,10 @@
return proptools.BoolDefault(a.properties.Updatable, true)
}
+func (a *apexBundle) FutureUpdatable() bool {
+ return proptools.BoolDefault(a.properties.Future_updatable, false)
+}
+
func (a *apexBundle) UsePlatformApis() bool {
return proptools.BoolDefault(a.properties.Platform_apis, false)
}
@@ -1670,7 +1681,7 @@
// 1) do some validity checks such as apex_available, min_sdk_version, etc.
a.checkApexAvailability(ctx)
a.checkUpdatable(ctx)
- a.checkMinSdkVersion(ctx)
+ a.CheckMinSdkVersion(ctx)
a.checkStaticLinkingToStubLibraries(ctx)
a.checkStaticExecutables(ctx)
if len(a.properties.Tests) > 0 && !a.testApex {
@@ -2105,10 +2116,11 @@
}
forced := ctx.Config().ForceApexSymlinkOptimization()
+ updatable := a.Updatable() || a.FutureUpdatable()
// We don't need the optimization for updatable APEXes, as it might give false signal
// to the system health when the APEXes are still bundled (b/149805758).
- if !forced && a.Updatable() && a.properties.ApexType == imageApex {
+ if !forced && updatable && a.properties.ApexType == imageApex {
a.linkToSystemLib = false
}
@@ -2174,6 +2186,40 @@
filesToAdd = append(filesToAdd, *af)
}
+ if pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex(); pathInApex != "" {
+ pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
+ tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
+
+ if pathOnHost != nil {
+ // We need to copy the profile to a temporary path with the right filename because the apexer
+ // will take the filename as is.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: pathOnHost,
+ Output: tempPath,
+ })
+ } else {
+ // At this point, the boot image profile cannot be generated. It is probably because the boot
+ // image profile source file does not exist on the branch, or it is not available for the
+ // current build target.
+ // However, we cannot enforce the boot image profile to be generated because some build
+ // targets (such as module SDK) do not need it. It is only needed when the APEX is being
+ // built. Therefore, we create an error rule so that an error will occur at the ninja phase
+ // only if the APEX is being built.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.ErrorRule,
+ Output: tempPath,
+ Args: map[string]string{
+ "error": "Boot image profile cannot be generated",
+ },
+ })
+ }
+
+ androidMkModuleName := filepath.Base(pathInApex)
+ af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
+ filesToAdd = append(filesToAdd, af)
+ }
+
return filesToAdd
}
@@ -2300,18 +2346,28 @@
//
// TODO(jiyong): move these checks to a separate go file.
+var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
+
// Entures that min_sdk_version of the included modules are equal or less than the min_sdk_version
// of this apexBundle.
-func (a *apexBundle) checkMinSdkVersion(ctx android.ModuleContext) {
+func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
if a.testApex || a.vndkApex {
return
}
// apexBundle::minSdkVersion reports its own errors.
minSdkVersion := a.minSdkVersion(ctx)
- android.CheckMinSdkVersion(a, ctx, minSdkVersion)
+ android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
}
-func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) android.ApiLevel {
+func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+ return android.SdkSpec{
+ Kind: android.SdkNone,
+ ApiLevel: a.minSdkVersion(ctx),
+ Raw: String(a.properties.Min_sdk_version),
+ }
+}
+
+func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
ver := proptools.String(a.properties.Min_sdk_version)
if ver == "" {
return android.NoneApiLevel
@@ -2380,6 +2436,9 @@
if a.SocSpecific() || a.DeviceSpecific() {
ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
}
+ if a.FutureUpdatable() {
+ ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
+ }
a.checkJavaStableSdkVersion(ctx)
a.checkClasspathFragments(ctx)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b805cd9..3b9b13a 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -7037,6 +7037,7 @@
`, insert))
}
}),
+ dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"),
).
ExtendWithErrorHandler(errorHandler).
RunTestWithBp(t, bp)
@@ -8409,6 +8410,184 @@
ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += otherapex")
}
+func TestSdkLibraryCanHaveHigherMinSdkVersion(t *testing.T) {
+ preparer := android.GroupFixturePreparers(
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithMyapex,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAndroidBuildComponents,
+ dexpreopt.FixtureSetApexBootJars("myapex:mybootclasspathlib"),
+ dexpreopt.FixtureSetApexSystemServerJars("myapex:mysystemserverclasspathlib"),
+ )
+
+ // Test java_sdk_library in bootclasspath_fragment may define higher min_sdk_version than the apex
+ t.Run("bootclasspath_fragment jar has higher min_sdk_version than apex", func(t *testing.T) {
+ preparer.RunTestWithBp(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ min_sdk_version: "30",
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: ["mybootclasspathlib"],
+ apex_available: ["myapex"],
+ }
+
+ java_sdk_library {
+ name: "mybootclasspathlib",
+ srcs: ["mybootclasspathlib.java"],
+ apex_available: ["myapex"],
+ compile_dex: true,
+ unsafe_ignore_missing_latest_api: true,
+ min_sdk_version: "31",
+ static_libs: ["util"],
+ }
+
+ java_library {
+ name: "util",
+ srcs: ["a.java"],
+ apex_available: ["myapex"],
+ min_sdk_version: "31",
+ static_libs: ["another_util"],
+ }
+
+ java_library {
+ name: "another_util",
+ srcs: ["a.java"],
+ min_sdk_version: "31",
+ apex_available: ["myapex"],
+ }
+ `)
+ })
+
+ // Test java_sdk_library in systemserverclasspath_fragment may define higher min_sdk_version than the apex
+ t.Run("systemserverclasspath_fragment jar has higher min_sdk_version than apex", func(t *testing.T) {
+ preparer.RunTestWithBp(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
+ min_sdk_version: "30",
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ contents: ["mysystemserverclasspathlib"],
+ apex_available: ["myapex"],
+ }
+
+ java_sdk_library {
+ name: "mysystemserverclasspathlib",
+ srcs: ["mysystemserverclasspathlib.java"],
+ apex_available: ["myapex"],
+ compile_dex: true,
+ min_sdk_version: "32",
+ unsafe_ignore_missing_latest_api: true,
+ static_libs: ["util"],
+ }
+
+ java_library {
+ name: "util",
+ srcs: ["a.java"],
+ apex_available: ["myapex"],
+ min_sdk_version: "31",
+ static_libs: ["another_util"],
+ }
+
+ java_library {
+ name: "another_util",
+ srcs: ["a.java"],
+ min_sdk_version: "31",
+ apex_available: ["myapex"],
+ }
+ `)
+ })
+
+ t.Run("bootclasspath_fragment jar must set min_sdk_version", func(t *testing.T) {
+ preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "mybootclasspathlib".*must set min_sdk_version`)).
+ RunTestWithBp(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ min_sdk_version: "30",
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: ["mybootclasspathlib"],
+ apex_available: ["myapex"],
+ }
+
+ java_sdk_library {
+ name: "mybootclasspathlib",
+ srcs: ["mybootclasspathlib.java"],
+ apex_available: ["myapex"],
+ compile_dex: true,
+ unsafe_ignore_missing_latest_api: true,
+ }
+ `)
+ })
+
+ t.Run("systemserverclasspath_fragment jar must set min_sdk_version", func(t *testing.T) {
+ preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "mysystemserverclasspathlib".*must set min_sdk_version`)).
+ RunTestWithBp(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
+ min_sdk_version: "30",
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ contents: ["mysystemserverclasspathlib"],
+ apex_available: ["myapex"],
+ }
+
+ java_sdk_library {
+ name: "mysystemserverclasspathlib",
+ srcs: ["mysystemserverclasspathlib.java"],
+ apex_available: ["myapex"],
+ compile_dex: true,
+ unsafe_ignore_missing_latest_api: true,
+ }
+ `)
+ })
+}
+
func TestMain(m *testing.M) {
os.Exit(m.Run())
}
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index cb7d3d1..9e030f1 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -21,6 +21,7 @@
"testing"
"android/soong/android"
+ "android/soong/dexpreopt"
"android/soong/java"
"github.com/google/blueprint/proptools"
@@ -35,11 +36,14 @@
)
// Some additional files needed for the art apex.
-var prepareForTestWithArtApex = android.FixtureMergeMockFs(android.MockFS{
- "com.android.art.avbpubkey": nil,
- "com.android.art.pem": nil,
- "system/sepolicy/apex/com.android.art-file_contexts": nil,
-})
+var prepareForTestWithArtApex = android.GroupFixturePreparers(
+ android.FixtureMergeMockFs(android.MockFS{
+ "com.android.art.avbpubkey": nil,
+ "com.android.art.pem": nil,
+ "system/sepolicy/apex/com.android.art-file_contexts": nil,
+ }),
+ dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"),
+)
func TestBootclasspathFragments(t *testing.T) {
result := android.GroupFixturePreparers(
@@ -408,6 +412,7 @@
).RunTest(t)
ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
+ "etc/boot-image.prof",
"etc/classpaths/bootclasspath.pb",
"javalib/arm/boot.art",
"javalib/arm/boot.oat",
@@ -451,6 +456,7 @@
).RunTest(t)
ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
+ "etc/boot-image.prof",
"etc/classpaths/bootclasspath.pb",
"javalib/arm/boot.art",
"javalib/arm/boot.oat",
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index 0bd71c6..41f9886 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -17,6 +17,7 @@
CcStaticLibraryFiles []string
Includes []string
SystemIncludes []string
+ Headers []string
// Archives owned by the current target (not by its dependencies). These will
// be a subset of OutputFiles. (or static libraries, this will be equal to OutputFiles,
// but general cc_library will also have dynamic libraries in output files).
@@ -105,6 +106,7 @@
includes = cc_info.compilation_context.includes.to_list()
system_includes = cc_info.compilation_context.system_includes.to_list()
+headers = [f.path for f in cc_info.compilation_context.headers.to_list()]
ccObjectFiles = []
staticLibraries = []
@@ -145,6 +147,7 @@
ccObjectFiles,
includes,
system_includes,
+ headers,
rootStaticArchives,
rootDynamicLibraries,
[toc_file]
@@ -161,7 +164,7 @@
var ccObjects []string
splitString := strings.Split(rawString, "|")
- if expectedLen := 8; len(splitString) != expectedLen {
+ if expectedLen := 9; len(splitString) != expectedLen {
return CcInfo{}, fmt.Errorf("Expected %d items, got %q", expectedLen, splitString)
}
outputFilesString := splitString[0]
@@ -172,15 +175,17 @@
ccObjects = splitOrEmpty(ccObjectsString, ", ")
includes := splitOrEmpty(splitString[3], ", ")
systemIncludes := splitOrEmpty(splitString[4], ", ")
- rootStaticArchives := splitOrEmpty(splitString[5], ", ")
- rootDynamicLibraries := splitOrEmpty(splitString[6], ", ")
- tocFile := splitString[7] // NOTE: Will be the empty string if there wasn't
+ headers := splitOrEmpty(splitString[5], ", ")
+ rootStaticArchives := splitOrEmpty(splitString[6], ", ")
+ rootDynamicLibraries := splitOrEmpty(splitString[7], ", ")
+ tocFile := splitString[8] // NOTE: Will be the empty string if there wasn't
return CcInfo{
OutputFiles: outputFiles,
CcObjectFiles: ccObjects,
CcStaticLibraryFiles: ccStaticLibraries,
Includes: includes,
SystemIncludes: systemIncludes,
+ Headers: headers,
RootStaticArchives: rootStaticArchives,
RootDynamicLibraries: rootDynamicLibraries,
TocFile: tocFile,
diff --git a/bazel/cquery/request_type_test.go b/bazel/cquery/request_type_test.go
index 34d0832..d3bcb45 100644
--- a/bazel/cquery/request_type_test.go
+++ b/bazel/cquery/request_type_test.go
@@ -71,13 +71,14 @@
}{
{
description: "no result",
- input: "|||||||",
+ input: "||||||||",
expectedOutput: CcInfo{
OutputFiles: []string{},
CcObjectFiles: []string{},
CcStaticLibraryFiles: []string{},
Includes: []string{},
SystemIncludes: []string{},
+ Headers: []string{},
RootStaticArchives: []string{},
RootDynamicLibraries: []string{},
TocFile: "",
@@ -85,13 +86,14 @@
},
{
description: "only output",
- input: "test|||||||",
+ input: "test||||||||",
expectedOutput: CcInfo{
OutputFiles: []string{"test"},
CcObjectFiles: []string{},
CcStaticLibraryFiles: []string{},
Includes: []string{},
SystemIncludes: []string{},
+ Headers: []string{},
RootStaticArchives: []string{},
RootDynamicLibraries: []string{},
TocFile: "",
@@ -99,13 +101,14 @@
},
{
description: "all items set",
- input: "out1, out2|static_lib1, static_lib2|object1, object2|., dir/subdir|system/dir, system/other/dir|rootstaticarchive1|rootdynamiclibrary1|lib.so.toc",
+ input: "out1, out2|static_lib1, static_lib2|object1, object2|., dir/subdir|system/dir, system/other/dir|dir/subdir/hdr.h|rootstaticarchive1|rootdynamiclibrary1|lib.so.toc",
expectedOutput: CcInfo{
OutputFiles: []string{"out1", "out2"},
CcObjectFiles: []string{"object1", "object2"},
CcStaticLibraryFiles: []string{"static_lib1", "static_lib2"},
Includes: []string{".", "dir/subdir"},
SystemIncludes: []string{"system/dir", "system/other/dir"},
+ Headers: []string{"dir/subdir/hdr.h"},
RootStaticArchives: []string{"rootstaticarchive1"},
RootDynamicLibraries: []string{"rootdynamiclibrary1"},
TocFile: "lib.so.toc",
@@ -115,13 +118,13 @@
description: "too few result splits",
input: "|",
expectedOutput: CcInfo{},
- expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 8, []string{"", ""}),
+ expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 9, []string{"", ""}),
},
{
description: "too many result splits",
- input: strings.Repeat("|", 8),
+ input: strings.Repeat("|", 50),
expectedOutput: CcInfo{},
- expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 8, make([]string, 9)),
+ expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 9, make([]string, 51)),
},
}
for _, tc := range testCases {
diff --git a/bazel/properties.go b/bazel/properties.go
index b370bbf..76be058 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -107,6 +107,14 @@
return dirs
}
+// Add inserts the label Label at the end of the LabelList.
+func (ll *LabelList) Add(label *Label) {
+ if label == nil {
+ return
+ }
+ ll.Includes = append(ll.Includes, *label)
+}
+
// Append appends the fields of other labelList to the corresponding fields of ll.
func (ll *LabelList) Append(other LabelList) {
if len(ll.Includes) > 0 || len(other.Includes) > 0 {
@@ -366,9 +374,23 @@
// labelListSelectValues supports config-specific label_list typed Bazel attribute values.
type labelListSelectValues map[string]LabelList
-func (ll labelListSelectValues) appendSelects(other labelListSelectValues) {
+func (ll labelListSelectValues) addSelects(label labelSelectValues) {
+ for k, v := range label {
+ if label == nil {
+ continue
+ }
+ l := ll[k]
+ (&l).Add(v)
+ ll[k] = l
+ }
+}
+
+func (ll labelListSelectValues) appendSelects(other labelListSelectValues, forceSpecifyEmptyList bool) {
for k, v := range other {
l := ll[k]
+ if forceSpecifyEmptyList && l.IsNil() && !v.IsNil() {
+ l.Includes = []Label{}
+ }
(&l).Append(v)
ll[k] = l
}
@@ -424,17 +446,22 @@
cll[axis][config] = list
}
-func (cll configurableLabelLists) Append(other configurableLabelLists) {
+func (cll configurableLabelLists) Append(other configurableLabelLists, forceSpecifyEmptyList bool) {
for axis, otherSelects := range other {
selects := cll[axis]
if selects == nil {
selects = make(labelListSelectValues, len(otherSelects))
}
- selects.appendSelects(otherSelects)
+ selects.appendSelects(otherSelects, forceSpecifyEmptyList)
cll[axis] = selects
}
}
+func (lla *LabelListAttribute) Clone() *LabelListAttribute {
+ result := &LabelListAttribute{ForceSpecifyEmptyList: lla.ForceSpecifyEmptyList}
+ return result.Append(*lla)
+}
+
// MakeLabelListAttribute initializes a LabelListAttribute with the non-arch specific value.
func MakeLabelListAttribute(value LabelList) LabelListAttribute {
return LabelListAttribute{
@@ -488,16 +515,37 @@
}
// Append all values, including os and arch specific ones, from another
-// LabelListAttribute to this LabelListAttribute.
-func (lla *LabelListAttribute) Append(other LabelListAttribute) {
- if lla.ForceSpecifyEmptyList && !other.Value.IsNil() {
+// LabelListAttribute to this LabelListAttribute. Returns this LabelListAttribute.
+func (lla *LabelListAttribute) Append(other LabelListAttribute) *LabelListAttribute {
+ forceSpecifyEmptyList := lla.ForceSpecifyEmptyList || other.ForceSpecifyEmptyList
+ if forceSpecifyEmptyList && lla.Value.IsNil() && !other.Value.IsNil() {
lla.Value.Includes = []Label{}
}
lla.Value.Append(other.Value)
if lla.ConfigurableValues == nil {
lla.ConfigurableValues = make(configurableLabelLists)
}
- lla.ConfigurableValues.Append(other.ConfigurableValues)
+ lla.ConfigurableValues.Append(other.ConfigurableValues, forceSpecifyEmptyList)
+ return lla
+}
+
+// Add inserts the labels for each axis of LabelAttribute at the end of corresponding axis's
+// LabelList within the LabelListAttribute
+func (lla *LabelListAttribute) Add(label *LabelAttribute) {
+ if label == nil {
+ return
+ }
+
+ lla.Value.Add(label.Value)
+ if lla.ConfigurableValues == nil && label.ConfigurableValues != nil {
+ lla.ConfigurableValues = make(configurableLabelLists)
+ }
+ for axis, _ := range label.ConfigurableValues {
+ if _, exists := lla.ConfigurableValues[axis]; !exists {
+ lla.ConfigurableValues[axis] = make(labelListSelectValues)
+ }
+ lla.ConfigurableValues[axis].addSelects(label.ConfigurableValues[axis])
+ }
}
// HasConfigurableValues returns true if the attribute contains axis-specific label list values.
@@ -566,7 +614,7 @@
// LabelMapper is a function that takes a OtherModuleContext and returns a (potentially changed)
// label and whether it was changed.
-type LabelMapper func(OtherModuleContext, string) (string, bool)
+type LabelMapper func(OtherModuleContext, Label) (string, bool)
// LabelPartition contains descriptions of a partition for labels
type LabelPartition struct {
@@ -588,7 +636,7 @@
// not.
func (lf LabelPartition) filter(ctx OtherModuleContext, label Label) *Label {
if lf.LabelMapper != nil {
- if newLabel, changed := lf.LabelMapper(ctx, label.Label); changed {
+ if newLabel, changed := lf.LabelMapper(ctx, label); changed {
return &Label{newLabel, label.OriginalModuleName}
}
}
@@ -757,12 +805,18 @@
// Append appends all values, including os and arch specific ones, from another
// StringListAttribute to this StringListAttribute
-func (sla *StringListAttribute) Append(other StringListAttribute) {
+func (sla *StringListAttribute) Append(other StringListAttribute) *StringListAttribute {
sla.Value = append(sla.Value, other.Value...)
if sla.ConfigurableValues == nil {
sla.ConfigurableValues = make(configurableStringLists)
}
sla.ConfigurableValues.Append(other.ConfigurableValues)
+ return sla
+}
+
+func (sla *StringListAttribute) Clone() *StringListAttribute {
+ result := &StringListAttribute{}
+ return result.Append(*sla)
}
// SetSelectValue set a value for a bazel select for the given axis, config and value.
diff --git a/bazel/properties_test.go b/bazel/properties_test.go
index 7a7d6f3..c7f9776 100644
--- a/bazel/properties_test.go
+++ b/bazel/properties_test.go
@@ -313,16 +313,16 @@
// labelAddSuffixForTypeMapper returns a LabelMapper that adds suffix to label name for modules of
// typ
func labelAddSuffixForTypeMapper(suffix, typ string) LabelMapper {
- return func(omc OtherModuleContext, label string) (string, bool) {
- m, ok := omc.ModuleFromName(label)
+ return func(omc OtherModuleContext, label Label) (string, bool) {
+ m, ok := omc.ModuleFromName(label.Label)
if !ok {
- return label, false
+ return label.Label, false
}
mTyp := omc.OtherModuleType(m)
if typ == mTyp {
- return label + suffix, true
+ return label.Label + suffix, true
}
- return label, false
+ return label.Label, false
}
}
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
new file mode 100644
index 0000000..b12b567
--- /dev/null
+++ b/bp2build/android_app_conversion_test.go
@@ -0,0 +1,92 @@
+// Copyright 2021 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 bp2build
+
+import (
+ "android/soong/android"
+ "android/soong/java"
+
+ "testing"
+)
+
+func runAndroidAppTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, registerAndroidAppModuleTypes, tc)
+}
+
+func registerAndroidAppModuleTypes(ctx android.RegistrationContext) {
+}
+
+func TestMinimalAndroidApp(t *testing.T) {
+ runAndroidAppTestCase(t, bp2buildTestCase{
+ description: "Android app - simple example",
+ moduleTypeUnderTest: "android_app",
+ moduleTypeUnderTestFactory: java.AndroidAppFactory,
+ moduleTypeUnderTestBp2BuildMutator: java.AppBp2Build,
+ filesystem: map[string]string{
+ "app.java": "",
+ "res/res.png": "",
+ "AndroidManifest.xml": "",
+ },
+ blueprint: `
+android_app {
+ name: "TestApp",
+ srcs: ["app.java"],
+ sdk_version: "current",
+}
+`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("android_binary", "TestApp", attrNameToString{
+ "srcs": `["app.java"]`,
+ "manifest": `"AndroidManifest.xml"`,
+ "resource_files": `["res/res.png"]`,
+ }),
+ }})
+}
+
+func TestAndroidAppAllSupportedFields(t *testing.T) {
+ runAndroidAppTestCase(t, bp2buildTestCase{
+ description: "Android app - all supported fields",
+ moduleTypeUnderTest: "android_app",
+ moduleTypeUnderTestFactory: java.AndroidAppFactory,
+ moduleTypeUnderTestBp2BuildMutator: java.AppBp2Build,
+ filesystem: map[string]string{
+ "app.java": "",
+ "resa/res.png": "",
+ "resb/res.png": "",
+ "manifest/AndroidManifest.xml": "",
+ },
+ blueprint: `
+android_app {
+ name: "TestApp",
+ srcs: ["app.java"],
+ sdk_version: "current",
+ package_name: "com.google",
+ resource_dirs: ["resa", "resb"],
+ manifest: "manifest/AndroidManifest.xml",
+}
+`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("android_binary", "TestApp", attrNameToString{
+ "srcs": `["app.java"]`,
+ "manifest": `"manifest/AndroidManifest.xml"`,
+ "resource_files": `[
+ "resa/res.png",
+ "resb/res.png",
+ ]`,
+ "custom_package": `"com.google"`,
+ }),
+ }})
+}
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
index f9abcba..2446850 100644
--- a/bp2build/cc_binary_conversion_test.go
+++ b/bp2build/cc_binary_conversion_test.go
@@ -24,8 +24,7 @@
)
const (
- ccBinaryTypePlaceHolder = "{rule_name}"
- compatibleWithPlaceHolder = "{target_compatible_with}"
+ ccBinaryTypePlaceHolder = "{rule_name}"
)
type testBazelTarget struct {
@@ -84,12 +83,15 @@
func runCcHostBinaryTestCase(t *testing.T, tc ccBinaryBp2buildTestCase) {
t.Helper()
testCase := tc
- for i, t := range testCase.targets {
- t.attrs["target_compatible_with"] = `select({
+ for i, tar := range testCase.targets {
+ if tar.typ != "cc_binary" {
+ continue
+ }
+ tar.attrs["target_compatible_with"] = `select({
"//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
"//conditions:default": [],
})`
- testCase.targets[i] = t
+ testCase.targets[i] = tar
}
moduleTypeUnderTest := "cc_binary_host"
t.Run(testCase.description, func(t *testing.T) {
@@ -448,3 +450,51 @@
})
}
}
+
+func TestCcBinarySharedProto(t *testing.T) {
+ runCcBinaryTests(t, ccBinaryBp2buildTestCase{
+ blueprint: soongCcProtoLibraries + `{rule_name} {
+ name: "foo",
+ srcs: ["foo.proto"],
+ proto: {
+ canonical_path_from_root: false,
+ },
+ include_build_directory: false,
+}`,
+ targets: []testBazelTarget{
+ {"proto_library", "foo_proto", attrNameToString{
+ "srcs": `["foo.proto"]`,
+ }}, {"cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
+ "deps": `[":foo_proto"]`,
+ }}, {"cc_binary", "foo", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ }},
+ },
+ })
+}
+
+func TestCcBinaryStaticProto(t *testing.T) {
+ runCcBinaryTests(t, ccBinaryBp2buildTestCase{
+ blueprint: soongCcProtoLibraries + `{rule_name} {
+ name: "foo",
+ srcs: ["foo.proto"],
+ static_executable: true,
+ proto: {
+ canonical_path_from_root: false,
+ },
+ include_build_directory: false,
+}`,
+ targets: []testBazelTarget{
+ {"proto_library", "foo_proto", attrNameToString{
+ "srcs": `["foo.proto"]`,
+ }}, {"cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
+ "deps": `[":foo_proto"]`,
+ }}, {"cc_binary", "foo", attrNameToString{
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ "linkshared": `False`,
+ }},
+ },
+ })
+}
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index d23ea01..dcbe326 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -39,6 +39,19 @@
native_bridge_supported: true,
src: "",
}`
+
+ soongCcProtoLibraries = `
+cc_library {
+ name: "libprotobuf-cpp-lite",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "libprotobuf-cpp-full",
+ bazel_module: { bp2build_available: false },
+}`
+
+ soongCcProtoPreamble = soongCcLibraryPreamble + soongCcProtoLibraries
)
func runCcLibraryTestCase(t *testing.T, tc bp2buildTestCase) {
@@ -117,17 +130,16 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "foo-lib", attrNameToString{
- "copts": `["-Wall"]`,
- "export_includes": `["foo-dir"]`,
- "implementation_deps": `[":some-headers"]`,
- "linkopts": `["-Wl,--exclude-libs=bar.a"] + select({
+ expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+ "copts": `["-Wall"]`,
+ "export_includes": `["foo-dir"]`,
+ "implementation_deps": `[":some-headers"]`,
+ "linkopts": `["-Wl,--exclude-libs=bar.a"] + select({
"//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=baz.a"],
"//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=qux.a"],
"//conditions:default": [],
})`,
- "srcs": `["impl.cpp"] + select({
+ "srcs": `["impl.cpp"] + select({
"//build/bazel/platforms/arch:x86": ["x86.cpp"],
"//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
"//conditions:default": [],
@@ -141,8 +153,7 @@
"//build/bazel/platforms/os:linux_bionic": ["bionic.cpp"],
"//conditions:default": [],
})`,
- }),
- },
+ }),
})
}
@@ -190,17 +201,16 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "fake-ld-android", attrNameToString{
- "srcs": `["ld_android.cpp"]`,
- "copts": `[
+ expectedBazelTargets: makeCcLibraryTargets("fake-ld-android", attrNameToString{
+ "srcs": `["ld_android.cpp"]`,
+ "copts": `[
"-Wall",
"-Wextra",
"-Wunused",
"-Werror",
]`,
- "implementation_deps": `[":libc_headers"]`,
- "linkopts": `[
+ "implementation_deps": `[":libc_headers"]`,
+ "linkopts": `[
"-Wl,--exclude-libs=libgcc.a",
"-Wl,--exclude-libs=libgcc_stripped.a",
"-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
@@ -212,8 +222,7 @@
"//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=libgcc_eh.a"],
"//conditions:default": [],
})`,
- }),
- },
+ }),
})
}
@@ -258,16 +267,14 @@
`,
},
blueprint: soongCcLibraryPreamble,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "fake-libarm-optimized-routines-math", attrNameToString{
- "copts": `select({
+ expectedBazelTargets: makeCcLibraryTargets("fake-libarm-optimized-routines-math", attrNameToString{
+ "copts": `select({
"//build/bazel/platforms/arch:arm64": ["-DHAVE_FAST_FMA=1"],
"//conditions:default": [],
})`,
- "local_includes": `["."]`,
- "srcs_c": `["math/cosf.c"]`,
- }),
- },
+ "local_includes": `["."]`,
+ "srcs_c": `["math/cosf.c"]`,
+ }),
})
}
@@ -353,26 +360,48 @@
}
`,
expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
- "copts": `["bothflag"]`,
- "implementation_deps": `[":static_dep_for_both"]`,
- "implementation_dynamic_deps": `[":shared_dep_for_both"]`,
- "shared": `{
- "copts": ["sharedflag"],
- "implementation_deps": [":static_dep_for_shared"],
- "implementation_dynamic_deps": [":shared_dep_for_shared"],
- "srcs": ["sharedonly.cpp"],
- "whole_archive_deps": [":whole_static_lib_for_shared"],
- }`,
- "srcs": `["both.cpp"]`,
- "static": `{
- "copts": ["staticflag"],
- "implementation_deps": [":static_dep_for_static"],
- "implementation_dynamic_deps": [":shared_dep_for_static"],
- "srcs": ["staticonly.cpp"],
- "whole_archive_deps": [":whole_static_lib_for_static"],
- }`,
- "whole_archive_deps": `[":whole_static_lib_for_both"]`,
+ makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
+ "copts": `[
+ "bothflag",
+ "staticflag",
+ ]`,
+ "implementation_deps": `[
+ ":static_dep_for_both",
+ ":static_dep_for_static",
+ ]`,
+ "implementation_dynamic_deps": `[
+ ":shared_dep_for_both",
+ ":shared_dep_for_static",
+ ]`,
+ "srcs": `[
+ "both.cpp",
+ "staticonly.cpp",
+ ]`,
+ "whole_archive_deps": `[
+ ":whole_static_lib_for_both",
+ ":whole_static_lib_for_static",
+ ]`}),
+ makeBazelTarget("cc_library_shared", "a", attrNameToString{
+ "copts": `[
+ "bothflag",
+ "sharedflag",
+ ]`,
+ "implementation_deps": `[
+ ":static_dep_for_both",
+ ":static_dep_for_shared",
+ ]`,
+ "implementation_dynamic_deps": `[
+ ":shared_dep_for_both",
+ ":shared_dep_for_shared",
+ ]`,
+ "srcs": `[
+ "both.cpp",
+ "sharedonly.cpp",
+ ]`,
+ "whole_archive_deps": `[
+ ":whole_static_lib_for_both",
+ ":whole_static_lib_for_shared",
+ ]`,
}),
},
})
@@ -438,44 +467,72 @@
simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_both") +
simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_both"),
expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
- "copts": `["bothflag"]`,
- "deps": `[":static_dep_for_both"]`,
- "dynamic_deps": `[":shared_dep_for_both"]`,
- "implementation_deps": `[":implementation_static_dep_for_both"]`,
- "implementation_dynamic_deps": `[":implementation_shared_dep_for_both"]`,
- "shared": `{
- "copts": ["sharedflag"],
- "deps": [":static_dep_for_shared"],
- "dynamic_deps": [":shared_dep_for_shared"],
- "implementation_deps": [":implementation_static_dep_for_shared"],
- "implementation_dynamic_deps": [":implementation_shared_dep_for_shared"],
- "srcs": ["sharedonly.cpp"],
- "whole_archive_deps": [
- ":not_explicitly_exported_whole_static_dep_for_shared",
- ":whole_static_dep_for_shared",
- ],
- }`,
- "srcs": `["both.cpp"]`,
- "static": `{
- "copts": ["staticflag"],
- "deps": [":static_dep_for_static"],
- "dynamic_deps": [":shared_dep_for_static"],
- "implementation_deps": [":implementation_static_dep_for_static"],
- "implementation_dynamic_deps": [":implementation_shared_dep_for_static"],
- "srcs": ["staticonly.cpp"],
- "whole_archive_deps": [
- ":not_explicitly_exported_whole_static_dep_for_static",
- ":whole_static_dep_for_static",
- ],
- }`,
+ makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
+ "copts": `[
+ "bothflag",
+ "staticflag",
+ ]`,
+ "deps": `[
+ ":static_dep_for_both",
+ ":static_dep_for_static",
+ ]`,
+ "dynamic_deps": `[
+ ":shared_dep_for_both",
+ ":shared_dep_for_static",
+ ]`,
+ "implementation_deps": `[
+ ":implementation_static_dep_for_both",
+ ":implementation_static_dep_for_static",
+ ]`,
+ "implementation_dynamic_deps": `[
+ ":implementation_shared_dep_for_both",
+ ":implementation_shared_dep_for_static",
+ ]`,
+ "srcs": `[
+ "both.cpp",
+ "staticonly.cpp",
+ ]`,
"whole_archive_deps": `[
":not_explicitly_exported_whole_static_dep_for_both",
":whole_static_dep_for_both",
+ ":not_explicitly_exported_whole_static_dep_for_static",
+ ":whole_static_dep_for_static",
]`,
}),
- },
- })
+ makeBazelTarget("cc_library_shared", "a", attrNameToString{
+ "copts": `[
+ "bothflag",
+ "sharedflag",
+ ]`,
+ "deps": `[
+ ":static_dep_for_both",
+ ":static_dep_for_shared",
+ ]`,
+ "dynamic_deps": `[
+ ":shared_dep_for_both",
+ ":shared_dep_for_shared",
+ ]`,
+ "implementation_deps": `[
+ ":implementation_static_dep_for_both",
+ ":implementation_static_dep_for_shared",
+ ]`,
+ "implementation_dynamic_deps": `[
+ ":implementation_shared_dep_for_both",
+ ":implementation_shared_dep_for_shared",
+ ]`,
+ "srcs": `[
+ "both.cpp",
+ "sharedonly.cpp",
+ ]`,
+ "whole_archive_deps": `[
+ ":not_explicitly_exported_whole_static_dep_for_both",
+ ":whole_static_dep_for_both",
+ ":not_explicitly_exported_whole_static_dep_for_shared",
+ ":whole_static_dep_for_shared",
+ ]`,
+ })},
+ },
+ )
}
func TestCcLibraryWholeStaticLibsAlwaysLink(t *testing.T) {
@@ -508,17 +565,21 @@
},
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
- "shared": `{
- "whole_archive_deps": [":whole_static_lib_for_shared_alwayslink"],
- }`,
- "static": `{
- "whole_archive_deps": [":whole_static_lib_for_static_alwayslink"],
- }`,
- "whole_archive_deps": `[":whole_static_lib_for_both_alwayslink"]`,
+ makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
+ "whole_archive_deps": `[
+ ":whole_static_lib_for_both_alwayslink",
+ ":whole_static_lib_for_static_alwayslink",
+ ]`,
+ }),
+ makeBazelTarget("cc_library_shared", "a", attrNameToString{
+ "whole_archive_deps": `[
+ ":whole_static_lib_for_both_alwayslink",
+ ":whole_static_lib_for_shared_alwayslink",
+ ]`,
}),
},
- })
+ },
+ )
}
func TestCcLibrarySharedStaticPropsInArch(t *testing.T) {
@@ -599,62 +660,77 @@
},
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
- "copts": `["bothflag"]`,
- "implementation_deps": `[":static_dep_for_both"]`,
- "local_includes": `["."]`,
- "shared": `{
- "copts": ["sharedflag"] + select({
- "//build/bazel/platforms/arch:arm": ["-DARM_SHARED"],
- "//conditions:default": [],
- }) + select({
- "//build/bazel/platforms/os:android": ["-DANDROID_SHARED"],
- "//conditions:default": [],
- }) + select({
- "//build/bazel/platforms/os_arch:android_arm": ["-DANDROID_ARM_SHARED"],
- "//conditions:default": [],
- }),
- "implementation_deps": [":static_dep_for_shared"] + select({
- "//build/bazel/platforms/arch:arm": [":arm_static_dep_for_shared"],
- "//conditions:default": [],
- }) + select({
- "//build/bazel/platforms/os:android": [":android_dep_for_shared"],
- "//conditions:default": [],
- }),
- "implementation_dynamic_deps": select({
- "//build/bazel/platforms/arch:arm": [":arm_shared_dep_for_shared"],
- "//conditions:default": [],
- }),
- "srcs": ["sharedonly.cpp"] + select({
- "//build/bazel/platforms/arch:arm": ["arm_shared.cpp"],
- "//conditions:default": [],
- }) + select({
- "//build/bazel/platforms/os:android": ["android_shared.cpp"],
- "//conditions:default": [],
- }),
- "whole_archive_deps": select({
- "//build/bazel/platforms/arch:arm": [":arm_whole_static_dep_for_shared"],
- "//conditions:default": [],
- }),
- }`,
- "srcs": `["both.cpp"]`,
- "static": `{
- "copts": ["staticflag"] + select({
- "//build/bazel/platforms/arch:x86": ["-DX86_STATIC"],
- "//conditions:default": [],
- }),
- "implementation_deps": [":static_dep_for_static"] + select({
- "//build/bazel/platforms/arch:x86": [":x86_dep_for_static"],
- "//conditions:default": [],
- }),
- "srcs": ["staticonly.cpp"] + select({
- "//build/bazel/platforms/arch:x86": ["x86_static.cpp"],
- "//conditions:default": [],
- }),
- }`,
+ makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
+ "copts": `[
+ "bothflag",
+ "staticflag",
+ ] + select({
+ "//build/bazel/platforms/arch:x86": ["-DX86_STATIC"],
+ "//conditions:default": [],
+ })`,
+ "implementation_deps": `[
+ ":static_dep_for_both",
+ ":static_dep_for_static",
+ ] + select({
+ "//build/bazel/platforms/arch:x86": [":x86_dep_for_static"],
+ "//conditions:default": [],
+ })`,
+ "local_includes": `["."]`,
+ "srcs": `[
+ "both.cpp",
+ "staticonly.cpp",
+ ] + select({
+ "//build/bazel/platforms/arch:x86": ["x86_static.cpp"],
+ "//conditions:default": [],
+ })`,
+ }),
+ makeBazelTarget("cc_library_shared", "a", attrNameToString{
+ "copts": `[
+ "bothflag",
+ "sharedflag",
+ ] + select({
+ "//build/bazel/platforms/arch:arm": ["-DARM_SHARED"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": ["-DANDROID_SHARED"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os_arch:android_arm": ["-DANDROID_ARM_SHARED"],
+ "//conditions:default": [],
+ })`,
+ "implementation_deps": `[
+ ":static_dep_for_both",
+ ":static_dep_for_shared",
+ ] + select({
+ "//build/bazel/platforms/arch:arm": [":arm_static_dep_for_shared"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": [":android_dep_for_shared"],
+ "//conditions:default": [],
+ })`,
+ "implementation_dynamic_deps": `select({
+ "//build/bazel/platforms/arch:arm": [":arm_shared_dep_for_shared"],
+ "//conditions:default": [],
+ })`,
+ "local_includes": `["."]`,
+ "srcs": `[
+ "both.cpp",
+ "sharedonly.cpp",
+ ] + select({
+ "//build/bazel/platforms/arch:arm": ["arm_shared.cpp"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": ["android_shared.cpp"],
+ "//conditions:default": [],
+ })`,
+ "whole_archive_deps": `select({
+ "//build/bazel/platforms/arch:arm": [":arm_whole_static_dep_for_shared"],
+ "//conditions:default": [],
+ })`,
}),
},
- })
+ },
+ )
}
func TestCcLibrarySharedStaticPropsWithMixedSources(t *testing.T) {
@@ -738,57 +814,56 @@
},
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
+ makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
"local_includes": `["."]`,
- "shared": `{
- "srcs": [
- "shared_source.cpp",
- "shared_source.cc",
- ":shared_filegroup_cpp_srcs",
- ],
- "srcs_as": [
- "shared_source.s",
- "shared_source.S",
- ":shared_filegroup_as_srcs",
- ],
- "srcs_c": [
- "shared_source.c",
- ":shared_filegroup_c_srcs",
- ],
- }`,
"srcs": `[
"both_source.cpp",
"both_source.cc",
":both_filegroup_cpp_srcs",
+ "static_source.cpp",
+ "static_source.cc",
+ ":static_filegroup_cpp_srcs",
]`,
"srcs_as": `[
"both_source.s",
"both_source.S",
":both_filegroup_as_srcs",
+ "static_source.s",
+ "static_source.S",
+ ":static_filegroup_as_srcs",
]`,
"srcs_c": `[
"both_source.c",
":both_filegroup_c_srcs",
+ "static_source.c",
+ ":static_filegroup_c_srcs",
]`,
- "static": `{
- "srcs": [
- "static_source.cpp",
- "static_source.cc",
- ":static_filegroup_cpp_srcs",
- ],
- "srcs_as": [
- "static_source.s",
- "static_source.S",
- ":static_filegroup_as_srcs",
- ],
- "srcs_c": [
- "static_source.c",
- ":static_filegroup_c_srcs",
- ],
- }`,
}),
- },
- })
+ makeBazelTarget("cc_library_shared", "a", attrNameToString{
+ "local_includes": `["."]`,
+ "srcs": `[
+ "both_source.cpp",
+ "both_source.cc",
+ ":both_filegroup_cpp_srcs",
+ "shared_source.cpp",
+ "shared_source.cc",
+ ":shared_filegroup_cpp_srcs",
+ ]`,
+ "srcs_as": `[
+ "both_source.s",
+ "both_source.S",
+ ":both_filegroup_as_srcs",
+ "shared_source.s",
+ "shared_source.S",
+ ":shared_filegroup_as_srcs",
+ ]`,
+ "srcs_c": `[
+ "both_source.c",
+ ":both_filegroup_c_srcs",
+ "shared_source.c",
+ ":shared_filegroup_c_srcs",
+ ]`,
+ })}})
}
func TestCcLibraryNonConfiguredVersionScript(t *testing.T) {
@@ -810,14 +885,13 @@
`,
},
blueprint: soongCcLibraryPreamble,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
- "additional_linker_inputs": `["v.map"]`,
- "linkopts": `["-Wl,--version-script,$(location v.map)"]`,
- "srcs": `["a.cpp"]`,
- }),
- },
- })
+ expectedBazelTargets: makeCcLibraryTargets("a", attrNameToString{
+ "additional_linker_inputs": `["v.map"]`,
+ "linkopts": `["-Wl,--version-script,$(location v.map)"]`,
+ "srcs": `["a.cpp"]`,
+ }),
+ },
+ )
}
func TestCcLibraryConfiguredVersionScript(t *testing.T) {
@@ -847,22 +921,21 @@
`,
},
blueprint: soongCcLibraryPreamble,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
- "additional_linker_inputs": `select({
+ expectedBazelTargets: makeCcLibraryTargets("a", attrNameToString{
+ "additional_linker_inputs": `select({
"//build/bazel/platforms/arch:arm": ["arm.map"],
"//build/bazel/platforms/arch:arm64": ["arm64.map"],
"//conditions:default": [],
})`,
- "linkopts": `select({
+ "linkopts": `select({
"//build/bazel/platforms/arch:arm": ["-Wl,--version-script,$(location arm.map)"],
"//build/bazel/platforms/arch:arm64": ["-Wl,--version-script,$(location arm64.map)"],
"//conditions:default": [],
})`,
- "srcs": `["a.cpp"]`,
- }),
- },
- })
+ "srcs": `["a.cpp"]`,
+ }),
+ },
+ )
}
func TestCcLibrarySharedLibs(t *testing.T) {
@@ -883,15 +956,43 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
- "implementation_dynamic_deps": `[":mylib"]`,
- }),
- },
- })
+ expectedBazelTargets: makeCcLibraryTargets("a", attrNameToString{
+ "implementation_dynamic_deps": `[":mylib"]`,
+ }),
+ },
+ )
}
func TestCcLibraryFeatures(t *testing.T) {
+ expected_targets := []string{}
+ expected_targets = append(expected_targets, makeCcLibraryTargets("a", attrNameToString{
+ "features": `[
+ "disable_pack_relocations",
+ "-no_undefined_symbols",
+ ]`,
+ "srcs": `["a.cpp"]`,
+ })...)
+ expected_targets = append(expected_targets, makeCcLibraryTargets("b", attrNameToString{
+ "features": `select({
+ "//build/bazel/platforms/arch:x86_64": [
+ "disable_pack_relocations",
+ "-no_undefined_symbols",
+ ],
+ "//conditions:default": [],
+ })`,
+ "srcs": `["b.cpp"]`,
+ })...)
+ expected_targets = append(expected_targets, makeCcLibraryTargets("c", attrNameToString{
+ "features": `select({
+ "//build/bazel/platforms/os:darwin": [
+ "disable_pack_relocations",
+ "-no_undefined_symbols",
+ ],
+ "//conditions:default": [],
+ })`,
+ "srcs": `["c.cpp"]`,
+ })...)
+
runCcLibraryTestCase(t, bp2buildTestCase{
description: "cc_library pack_relocations test",
moduleTypeUnderTest: "cc_library",
@@ -929,33 +1030,7 @@
},
include_build_directory: false,
}`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
- "features": `[
- "disable_pack_relocations",
- "-no_undefined_symbols",
- ]`,
- "srcs": `["a.cpp"]`,
- }), makeBazelTarget("cc_library", "b", attrNameToString{
- "features": `select({
- "//build/bazel/platforms/arch:x86_64": [
- "disable_pack_relocations",
- "-no_undefined_symbols",
- ],
- "//conditions:default": [],
- })`,
- "srcs": `["b.cpp"]`,
- }), makeBazelTarget("cc_library", "c", attrNameToString{
- "features": `select({
- "//build/bazel/platforms/os:darwin": [
- "disable_pack_relocations",
- "-no_undefined_symbols",
- ],
- "//conditions:default": [],
- })`,
- "srcs": `["c.cpp"]`,
- }),
- },
+ expectedBazelTargets: expected_targets,
})
}
@@ -972,15 +1047,14 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
- "copts": `[
+ expectedBazelTargets: makeCcLibraryTargets("a", attrNameToString{
+ "copts": `[
"-include",
"header.h",
]`,
- }),
- },
- })
+ }),
+ },
+ )
}
func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) {
@@ -1010,10 +1084,9 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "a", attrNameToString{
- "copts": `["-Wall"]`,
- "cppflags": `[
+ expectedBazelTargets: makeCcLibraryTargets("a", attrNameToString{
+ "copts": `["-Wall"]`,
+ "cppflags": `[
"-fsigned-char",
"-pedantic",
] + select({
@@ -1023,10 +1096,10 @@
"//build/bazel/platforms/os:android": ["-DANDROID=1"],
"//conditions:default": [],
})`,
- "srcs": `["a.cpp"]`,
- }),
- },
- })
+ "srcs": `["a.cpp"]`,
+ }),
+ },
+ )
}
func TestCcLibraryExcludeLibs(t *testing.T) {
@@ -1109,33 +1182,32 @@
bazel_module: { bp2build_available: false },
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "foo_static", attrNameToString{
- "implementation_deps": `select({
+ expectedBazelTargets: makeCcLibraryTargets("foo_static", attrNameToString{
+ "implementation_deps": `select({
"//build/bazel/platforms/arch:arm": [],
"//conditions:default": [":arm_static_lib_excludes_bp2build_cc_library_static"],
}) + select({
"//build/bazel/product_variables:malloc_not_svelte": [],
"//conditions:default": [":malloc_not_svelte_static_lib_excludes_bp2build_cc_library_static"],
})`,
- "implementation_dynamic_deps": `select({
+ "implementation_dynamic_deps": `select({
"//build/bazel/platforms/arch:arm": [],
"//conditions:default": [":arm_shared_lib_excludes"],
}) + select({
"//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_shared_lib"],
"//conditions:default": [],
})`,
- "srcs_c": `["common.c"]`,
- "whole_archive_deps": `select({
+ "srcs_c": `["common.c"]`,
+ "whole_archive_deps": `select({
"//build/bazel/platforms/arch:arm": [],
"//conditions:default": [":arm_whole_static_lib_excludes_bp2build_cc_library_static"],
}) + select({
"//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_whole_static_lib_bp2build_cc_library_static"],
"//conditions:default": [":malloc_not_svelte_whole_static_lib_excludes_bp2build_cc_library_static"],
})`,
- }),
- },
- })
+ }),
+ },
+ )
}
func TestCCLibraryNoCrtTrue(t *testing.T) {
@@ -1155,13 +1227,12 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "foo-lib", attrNameToString{
- "link_crt": `False`,
- "srcs": `["impl.cpp"]`,
- }),
- },
- })
+ expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+ "link_crt": `False`,
+ "srcs": `["impl.cpp"]`,
+ }),
+ },
+ )
}
func TestCCLibraryNoCrtFalse(t *testing.T) {
@@ -1181,11 +1252,9 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "foo-lib", attrNameToString{
- "srcs": `["impl.cpp"]`,
- }),
- },
+ expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+ "srcs": `["impl.cpp"]`,
+ }),
})
}
@@ -1235,12 +1304,35 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "foo-lib", attrNameToString{
- "srcs": `["impl.cpp"]`,
- "use_libcrt": `False`,
- }),
- }})
+ expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+ "srcs": `["impl.cpp"]`,
+ "use_libcrt": `False`,
+ }),
+ })
+}
+
+func makeCcLibraryTargets(name string, attrs attrNameToString) []string {
+ STATIC_ONLY_ATTRS := map[string]bool{}
+ SHARED_ONLY_ATTRS := map[string]bool{
+ "link_crt": true,
+ "additional_linker_inputs": true,
+ "linkopts": true,
+ "strip": true,
+ }
+ sharedAttrs := attrNameToString{}
+ staticAttrs := attrNameToString{}
+ for key, val := range attrs {
+ if _, staticOnly := STATIC_ONLY_ATTRS[key]; !staticOnly {
+ sharedAttrs[key] = val
+ }
+ if _, sharedOnly := SHARED_ONLY_ATTRS[key]; !sharedOnly {
+ staticAttrs[key] = val
+ }
+ }
+ sharedTarget := makeBazelTarget("cc_library_shared", name, sharedAttrs)
+ staticTarget := makeBazelTarget("cc_library_static", name+"_bp2build_cc_library_static", staticAttrs)
+
+ return []string{staticTarget, sharedTarget}
}
func TestCCLibraryNoLibCrtFalse(t *testing.T) {
@@ -1260,12 +1352,11 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "foo-lib", attrNameToString{
- "srcs": `["impl.cpp"]`,
- "use_libcrt": `True`,
- }),
- }})
+ expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+ "srcs": `["impl.cpp"]`,
+ "use_libcrt": `True`,
+ }),
+ })
}
func TestCCLibraryNoLibCrtArchVariant(t *testing.T) {
@@ -1291,19 +1382,46 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "foo-lib", attrNameToString{
- "srcs": `["impl.cpp"]`,
- "use_libcrt": `select({
+ expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+ "srcs": `["impl.cpp"]`,
+ "use_libcrt": `select({
"//build/bazel/platforms/arch:arm": False,
"//build/bazel/platforms/arch:x86": False,
"//conditions:default": None,
})`,
- }),
- }})
+ }),
+ })
}
func TestCcLibraryStrip(t *testing.T) {
+ expectedTargets := []string{}
+ expectedTargets = append(expectedTargets, makeCcLibraryTargets("all", attrNameToString{
+ "strip": `{
+ "all": True,
+ }`,
+ })...)
+ expectedTargets = append(expectedTargets, makeCcLibraryTargets("keep_symbols", attrNameToString{
+ "strip": `{
+ "keep_symbols": True,
+ }`,
+ })...)
+ expectedTargets = append(expectedTargets, makeCcLibraryTargets("keep_symbols_and_debug_frame", attrNameToString{
+ "strip": `{
+ "keep_symbols_and_debug_frame": True,
+ }`,
+ })...)
+ expectedTargets = append(expectedTargets, makeCcLibraryTargets("keep_symbols_list", attrNameToString{
+ "strip": `{
+ "keep_symbols_list": ["symbol"],
+ }`,
+ })...)
+ expectedTargets = append(expectedTargets, makeCcLibraryTargets("none", attrNameToString{
+ "strip": `{
+ "none": True,
+ }`,
+ })...)
+ expectedTargets = append(expectedTargets, makeCcLibraryTargets("nothing", attrNameToString{})...)
+
runCcLibraryTestCase(t, bp2buildTestCase{
description: "cc_library strip args",
moduleTypeUnderTest: "cc_library",
@@ -1350,29 +1468,7 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "all", attrNameToString{
- "strip": `{
- "all": True,
- }`,
- }), makeBazelTarget("cc_library", "keep_symbols", attrNameToString{
- "strip": `{
- "keep_symbols": True,
- }`,
- }), makeBazelTarget("cc_library", "keep_symbols_and_debug_frame", attrNameToString{
- "strip": `{
- "keep_symbols_and_debug_frame": True,
- }`,
- }), makeBazelTarget("cc_library", "keep_symbols_list", attrNameToString{
- "strip": `{
- "keep_symbols_list": ["symbol"],
- }`,
- }), makeBazelTarget("cc_library", "none", attrNameToString{
- "strip": `{
- "none": True,
- }`,
- }), makeBazelTarget("cc_library", "nothing", attrNameToString{}),
- },
+ expectedBazelTargets: expectedTargets,
})
}
@@ -1407,9 +1503,8 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "multi-arch", attrNameToString{
- "strip": `{
+ expectedBazelTargets: makeCcLibraryTargets("multi-arch", attrNameToString{
+ "strip": `{
"keep_symbols": select({
"//build/bazel/platforms/arch:arm64": True,
"//conditions:default": None,
@@ -1426,9 +1521,9 @@
"//conditions:default": [],
}),
}`,
- }),
- },
- })
+ }),
+ },
+ )
}
func TestCcLibrary_SystemSharedLibsRootEmpty(t *testing.T) {
@@ -1444,12 +1539,11 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "root_empty", attrNameToString{
- "system_dynamic_deps": `[]`,
- }),
- },
- })
+ expectedBazelTargets: makeCcLibraryTargets("root_empty", attrNameToString{
+ "system_dynamic_deps": `[]`,
+ }),
+ },
+ )
}
func TestCcLibrary_SystemSharedLibsStaticEmpty(t *testing.T) {
@@ -1468,11 +1562,10 @@
}
`,
expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "static_empty", attrNameToString{
- "static": `{
- "system_dynamic_deps": [],
- }`,
+ makeBazelTarget("cc_library_static", "static_empty_bp2build_cc_library_static", attrNameToString{
+ "system_dynamic_deps": "[]",
}),
+ makeBazelTarget("cc_library_shared", "static_empty", attrNameToString{}),
},
})
}
@@ -1493,10 +1586,9 @@
}
`,
expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "shared_empty", attrNameToString{
- "shared": `{
- "system_dynamic_deps": [],
- }`,
+ makeBazelTarget("cc_library_static", "shared_empty_bp2build_cc_library_static", attrNameToString{}),
+ makeBazelTarget("cc_library_shared", "shared_empty", attrNameToString{
+ "system_dynamic_deps": "[]",
}),
},
})
@@ -1522,10 +1614,9 @@
}
`,
expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "shared_empty", attrNameToString{
- "shared": `{
- "system_dynamic_deps": [],
- }`,
+ makeBazelTarget("cc_library_static", "shared_empty_bp2build_cc_library_static", attrNameToString{}),
+ makeBazelTarget("cc_library_shared", "shared_empty", attrNameToString{
+ "system_dynamic_deps": "[]",
}),
},
})
@@ -1552,12 +1643,11 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "target_linux_bionic_empty", attrNameToString{
- "system_dynamic_deps": `[]`,
- }),
- },
- })
+ expectedBazelTargets: makeCcLibraryTargets("target_linux_bionic_empty", attrNameToString{
+ "system_dynamic_deps": `[]`,
+ }),
+ },
+ )
}
func TestCcLibrary_SystemSharedLibsBionicEmpty(t *testing.T) {
@@ -1577,12 +1667,11 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "target_bionic_empty", attrNameToString{
- "system_dynamic_deps": `[]`,
- }),
- },
- })
+ expectedBazelTargets: makeCcLibraryTargets("target_bionic_empty", attrNameToString{
+ "system_dynamic_deps": `[]`,
+ }),
+ },
+ )
}
func TestCcLibrary_SystemSharedLibsSharedAndRoot(t *testing.T) {
@@ -1611,12 +1700,15 @@
}
`,
expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "foo", attrNameToString{
- "shared": `{
- "system_dynamic_deps": [":libm"],
- }`,
+ makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
"system_dynamic_deps": `[":libc"]`,
}),
+ makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "system_dynamic_deps": `[
+ ":libc",
+ ":libm",
+ ]`,
+ }),
},
})
}
@@ -1659,9 +1751,8 @@
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", "foo-lib", attrNameToString{
- "srcs": `["base.cpp"] + select({
+ expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+ "srcs": `["base.cpp"] + select({
"//build/bazel/platforms/os:android": [
"linux.cpp",
"bionic.cpp",
@@ -1683,9 +1774,9 @@
"//build/bazel/platforms/os:windows": ["windows.cpp"],
"//conditions:default": [],
})`,
- }),
- },
- })
+ }),
+ },
+ )
}
func TestCcLibraryCppStdWithGnuExtensions_ConvertsToFeatureAttr(t *testing.T) {
@@ -1783,9 +1874,7 @@
include_build_directory: false,
}
`, name_prefix, cppStdProp, cStdProp, gnuExtensionsProp),
- expectedBazelTargets: []string{
- makeBazelTarget("cc_library", name_prefix+"_full", attrs),
- },
+ expectedBazelTargets: makeCcLibraryTargets(name_prefix+"_full", attrs),
})
runCcLibraryStaticTestCase(t, bp2buildTestCase{
@@ -1829,3 +1918,170 @@
})
}
}
+
+func TestCcLibraryProtoSimple(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ blueprint: soongCcProtoPreamble + `cc_library {
+ name: "foo",
+ srcs: ["foo.proto"],
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("proto_library", "foo_proto", attrNameToString{
+ "srcs": `["foo.proto"]`,
+ "strip_import_prefix": `""`,
+ }), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
+ "deps": `[":foo_proto"]`,
+ }), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
+ "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ }), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryProtoNoCanonicalPathFromRoot(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ blueprint: soongCcProtoPreamble + `cc_library {
+ name: "foo",
+ srcs: ["foo.proto"],
+ proto: { canonical_path_from_root: false},
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("proto_library", "foo_proto", attrNameToString{
+ "srcs": `["foo.proto"]`,
+ }), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
+ "deps": `[":foo_proto"]`,
+ }), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
+ "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ }), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryProtoExplicitCanonicalPathFromRoot(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ blueprint: soongCcProtoPreamble + `cc_library {
+ name: "foo",
+ srcs: ["foo.proto"],
+ proto: { canonical_path_from_root: true},
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("proto_library", "foo_proto", attrNameToString{
+ "srcs": `["foo.proto"]`,
+ "strip_import_prefix": `""`,
+ }), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
+ "deps": `[":foo_proto"]`,
+ }), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
+ "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ }), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryProtoFull(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ blueprint: soongCcProtoPreamble + `cc_library {
+ name: "foo",
+ srcs: ["foo.proto"],
+ proto: {
+ canonical_path_from_root: false,
+ type: "full",
+ },
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("proto_library", "foo_proto", attrNameToString{
+ "srcs": `["foo.proto"]`,
+ }), makeBazelTarget("cc_proto_library", "foo_cc_proto", attrNameToString{
+ "deps": `[":foo_proto"]`,
+ }), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
+ "implementation_whole_archive_deps": `[":foo_cc_proto"]`,
+ "deps": `[":libprotobuf-cpp-full"]`,
+ }), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-full"]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryProtoLite(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ blueprint: soongCcProtoPreamble + `cc_library {
+ name: "foo",
+ srcs: ["foo.proto"],
+ proto: {
+ canonical_path_from_root: false,
+ type: "lite",
+ },
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("proto_library", "foo_proto", attrNameToString{
+ "srcs": `["foo.proto"]`,
+ }), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
+ "deps": `[":foo_proto"]`,
+ }), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
+ "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ }), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryProtoExportHeaders(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ blueprint: soongCcProtoPreamble + `cc_library {
+ name: "foo",
+ srcs: ["foo.proto"],
+ proto: {
+ canonical_path_from_root: false,
+ export_proto_headers: true,
+ },
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("proto_library", "foo_proto", attrNameToString{
+ "srcs": `["foo.proto"]`,
+ }), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
+ "deps": `[":foo_proto"]`,
+ }), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ }), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 4ec95c3..e0331be 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -33,6 +33,7 @@
ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
+ ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
}
func runCcLibrarySharedTestCase(t *testing.T, tc bp2buildTestCase) {
@@ -425,3 +426,27 @@
expectedErr: fmt.Errorf("Android.bp:16:1: module \"foo_shared\": nocrt is not supported for arch variants"),
})
}
+
+func TestCcLibrarySharedProto(t *testing.T) {
+ runCcLibrarySharedTestCase(t, bp2buildTestCase{
+ blueprint: soongCcProtoPreamble + `cc_library_shared {
+ name: "foo",
+ srcs: ["foo.proto"],
+ proto: {
+ canonical_path_from_root: false,
+ export_proto_headers: true,
+ },
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("proto_library", "foo_proto", attrNameToString{
+ "srcs": `["foo.proto"]`,
+ }), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
+ "deps": `[":foo_proto"]`,
+ }), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 2f760d2..02229e5 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1419,3 +1419,27 @@
},
})
}
+
+func TestCcLibraryStaticProto(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ blueprint: soongCcProtoPreamble + `cc_library_static {
+ name: "foo",
+ srcs: ["foo.proto"],
+ proto: {
+ canonical_path_from_root: false,
+ export_proto_headers: true,
+ },
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("proto_library", "foo_proto", attrNameToString{
+ "srcs": `["foo.proto"]`,
+ }), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
+ "deps": `[":foo_proto"]`,
+ }), makeBazelTarget("cc_library_static", "foo", attrNameToString{
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ }),
+ },
+ })
+}
diff --git a/cc/binary.go b/cc/binary.go
index a5afb07..3f951ec 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -18,6 +18,7 @@
"path/filepath"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/bazel"
@@ -388,7 +389,7 @@
}
}
- var validations android.WritablePaths
+ var validations android.Paths
// Handle host bionic linker symbols.
if ctx.Os() == android.LinuxBionic && !binary.static() {
@@ -411,6 +412,7 @@
linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
+ linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...)
}
validations = append(validations, objs.tidyFiles...)
@@ -578,9 +580,16 @@
}
baseAttrs := bp2BuildParseBaseProps(ctx, m)
+ binaryLinkerAttrs := bp2buildBinaryLinkerProps(ctx, m)
+
+ if proptools.BoolDefault(binaryLinkerAttrs.Linkshared, true) {
+ baseAttrs.implementationDynamicDeps.Add(baseAttrs.protoDependency)
+ } else {
+ baseAttrs.implementationDeps.Add(baseAttrs.protoDependency)
+ }
attrs := &binaryAttributes{
- binaryLinkerAttrs: bp2buildBinaryLinkerProps(ctx, m),
+ binaryLinkerAttrs: binaryLinkerAttrs,
Srcs: baseAttrs.srcs,
Srcs_c: baseAttrs.cSrcs,
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 888c3ba..f9bbe87 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -27,9 +27,10 @@
)
const (
- cSrcPartition = "c"
- asSrcPartition = "as"
- cppSrcPartition = "cpp"
+ cSrcPartition = "c"
+ asSrcPartition = "as"
+ cppSrcPartition = "cpp"
+ protoSrcPartition = "proto"
)
// staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
@@ -41,52 +42,53 @@
Hdrs bazel.LabelListAttribute
Copts bazel.StringListAttribute
- Deps bazel.LabelListAttribute
- Implementation_deps bazel.LabelListAttribute
- Dynamic_deps bazel.LabelListAttribute
- Implementation_dynamic_deps bazel.LabelListAttribute
- Whole_archive_deps bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Implementation_deps bazel.LabelListAttribute
+ Dynamic_deps bazel.LabelListAttribute
+ Implementation_dynamic_deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
+ Implementation_whole_archive_deps bazel.LabelListAttribute
System_dynamic_deps bazel.LabelListAttribute
}
func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
- // Check that a module is a filegroup type named <label>.
- isFilegroupNamed := func(m android.Module, fullLabel string) bool {
- if ctx.OtherModuleType(m) != "filegroup" {
- return false
- }
- labelParts := strings.Split(fullLabel, ":")
- if len(labelParts) > 2 {
- // There should not be more than one colon in a label.
- ctx.ModuleErrorf("%s is not a valid Bazel label for a filegroup", fullLabel)
- }
- return m.Name() == labelParts[len(labelParts)-1]
+ // Check that a module is a filegroup type
+ isFilegroup := func(m blueprint.Module) bool {
+ return ctx.OtherModuleType(m) == "filegroup"
}
// Convert filegroup dependencies into extension-specific filegroups filtered in the filegroup.bzl
// macro.
addSuffixForFilegroup := func(suffix string) bazel.LabelMapper {
- return func(ctx bazel.OtherModuleContext, label string) (string, bool) {
- m, exists := ctx.ModuleFromName(label)
- if !exists {
- return label, false
+ return func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
+ m, exists := ctx.ModuleFromName(label.OriginalModuleName)
+ labelStr := label.Label
+ if !exists || !isFilegroup(m) {
+ return labelStr, false
}
- aModule, _ := m.(android.Module)
- if !isFilegroupNamed(aModule, label) {
- return label, false
- }
- return label + suffix, true
+ return labelStr + suffix, true
}
}
+ isProtoFilegroup := func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
+ m, exists := ctx.ModuleFromName(label.OriginalModuleName)
+ labelStr := label.Label
+ if !exists || !isFilegroup(m) {
+ return labelStr, false
+ }
+ likelyProtos := strings.HasSuffix(labelStr, "proto") || strings.HasSuffix(labelStr, "protos")
+ return labelStr, likelyProtos
+ }
+
// TODO(b/190006308): Handle language detection of sources in a Bazel rule.
partitioned := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{
cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")},
asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")},
// C++ is the "catch-all" group, and comprises generated sources because we don't
// know the language of these sources until the genrule is executed.
- cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
+ cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
+ protoSrcPartition: bazel.LabelPartition{Extensions: []string{".proto"}, LabelMapper: isProtoFilegroup},
})
return partitioned
@@ -195,6 +197,11 @@
attrs.Srcs_c = partitionedSrcs[cSrcPartition]
attrs.Srcs_as = partitionedSrcs[asSrcPartition]
+ if !partitionedSrcs[protoSrcPartition].IsEmpty() {
+ // TODO(b/208815215): determine whether this is used and add support if necessary
+ ctx.ModuleErrorf("Migrating static/shared only proto srcs is not currently supported")
+ }
+
return attrs
}
@@ -230,6 +237,8 @@
type baseAttributes struct {
compilerAttributes
linkerAttributes
+
+ protoDependency *bazel.LabelAttribute
}
// Convenience struct to hold all attributes parsed from compiler properties.
@@ -257,6 +266,8 @@
localIncludes bazel.StringListAttribute
absoluteIncludes bazel.StringListAttribute
+
+ protoSrcs bazel.LabelListAttribute
}
func parseCommandLineFlags(soongFlags []string) []string {
@@ -337,6 +348,8 @@
ca.srcs.ResolveExcludes()
partitionedSrcs := groupSrcsByExtension(ctx, ca.srcs)
+ ca.protoSrcs = partitionedSrcs[protoSrcPartition]
+
for p, lla := range partitionedSrcs {
// if there are no sources, there is no need for headers
if lla.IsEmpty() {
@@ -400,7 +413,7 @@
}
// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
-func bp2BuildParseBaseProps(ctx android.BazelConversionPathContext, module *Module) baseAttributes {
+func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) baseAttributes {
archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
archVariantLinkerProps := module.GetArchVariantProperties(ctx, &BaseLinkerProperties{})
@@ -456,20 +469,30 @@
(&compilerAttrs).finalize(ctx, implementationHdrs)
(&linkerAttrs).finalize()
+ protoDep := bp2buildProto(ctx, module, compilerAttrs.protoSrcs)
+
+ // bp2buildProto will only set wholeStaticLib or implementationWholeStaticLib, but we don't know
+ // which. This will add the newly generated proto library to the appropriate attribute and nothing
+ // to the other
+ (&linkerAttrs).wholeArchiveDeps.Add(protoDep.wholeStaticLib)
+ (&linkerAttrs).implementationWholeArchiveDeps.Add(protoDep.implementationWholeStaticLib)
+
return baseAttributes{
compilerAttrs,
linkerAttrs,
+ protoDep.protoDep,
}
}
// Convenience struct to hold all attributes parsed from linker properties.
type linkerAttributes struct {
- deps bazel.LabelListAttribute
- implementationDeps bazel.LabelListAttribute
- dynamicDeps bazel.LabelListAttribute
- implementationDynamicDeps bazel.LabelListAttribute
- wholeArchiveDeps bazel.LabelListAttribute
- systemDynamicDeps bazel.LabelListAttribute
+ deps bazel.LabelListAttribute
+ implementationDeps bazel.LabelListAttribute
+ dynamicDeps bazel.LabelListAttribute
+ implementationDynamicDeps bazel.LabelListAttribute
+ wholeArchiveDeps bazel.LabelListAttribute
+ implementationWholeArchiveDeps bazel.LabelListAttribute
+ systemDynamicDeps bazel.LabelListAttribute
linkCrt bazel.BoolAttribute
useLibcrt bazel.BoolAttribute
diff --git a/cc/builder.go b/cc/builder.go
index fea65d5..7161ccf 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -413,7 +413,7 @@
// Objects is a collection of file paths corresponding to outputs for C++ related build statements.
type Objects struct {
objFiles android.Paths
- tidyFiles android.WritablePaths
+ tidyFiles android.Paths
coverageFiles android.Paths
sAbiDumpFiles android.Paths
kytheFiles android.Paths
@@ -422,7 +422,7 @@
func (a Objects) Copy() Objects {
return Objects{
objFiles: append(android.Paths{}, a.objFiles...),
- tidyFiles: append(android.WritablePaths{}, a.tidyFiles...),
+ tidyFiles: append(android.Paths{}, a.tidyFiles...),
coverageFiles: append(android.Paths{}, a.coverageFiles...),
sAbiDumpFiles: append(android.Paths{}, a.sAbiDumpFiles...),
kytheFiles: append(android.Paths{}, a.kytheFiles...),
@@ -451,11 +451,11 @@
// Source files are one-to-one with tidy, coverage, or kythe files, if enabled.
objFiles := make(android.Paths, len(srcFiles))
- var tidyFiles android.WritablePaths
+ var tidyFiles android.Paths
noTidySrcsMap := make(map[android.Path]bool)
var tidyVars string
if flags.tidy {
- tidyFiles = make(android.WritablePaths, 0, len(srcFiles))
+ tidyFiles = make(android.Paths, 0, len(srcFiles))
for _, path := range noTidySrcs {
noTidySrcsMap[path] = true
}
@@ -549,10 +549,6 @@
return "$" + kind + n
}
- // clang-tidy checks source files and does not need to link with libraries.
- // tidyPathDeps should contain pathDeps but not libraries.
- tidyPathDeps := skipNdkLibraryDeps(ctx, pathDeps)
-
for i, srcFile := range srcFiles {
objFile := android.ObjPathWithExt(ctx, subdir, srcFile, "o")
@@ -669,14 +665,13 @@
rule = clangTidyRE
}
- ctx.TidyFile(tidyFile)
ctx.Build(pctx, android.BuildParams{
Rule: rule,
Description: "clang-tidy " + srcFile.Rel(),
Output: tidyFile,
Input: srcFile,
Implicits: cFlagsDeps,
- OrderOnly: tidyPathDeps,
+ OrderOnly: pathDeps,
Args: map[string]string{
"ccCmd": ccCmd,
"cFlags": shareFlags("cFlags", escapeSingleQuotes(moduleToolingFlags)),
@@ -723,7 +718,7 @@
// Generate a rule for compiling multiple .o files to a static library (.a)
func transformObjToStaticLib(ctx android.ModuleContext,
objFiles android.Paths, wholeStaticLibs android.Paths,
- flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths, validations android.WritablePaths) {
+ flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths, validations android.Paths) {
arCmd := "${config.ClangBin}/llvm-ar"
arFlags := ""
@@ -738,7 +733,7 @@
Output: outputFile,
Inputs: objFiles,
Implicits: deps,
- Validations: validations.Paths(),
+ Validations: validations,
Args: map[string]string{
"arFlags": "crsPD" + arFlags,
"arCmd": arCmd,
@@ -768,7 +763,7 @@
func transformObjToDynamicBinary(ctx android.ModuleContext,
objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps, crtBegin, crtEnd android.Paths,
groupLate bool, flags builderFlags, outputFile android.WritablePath,
- implicitOutputs android.WritablePaths, validations android.WritablePaths) {
+ implicitOutputs android.WritablePaths, validations android.Paths) {
ldCmd := "${config.ClangBin}/clang++"
@@ -835,7 +830,7 @@
Inputs: objFiles,
Implicits: deps,
OrderOnly: sharedLibs,
- Validations: validations.Paths(),
+ Validations: validations,
Args: args,
})
}
diff --git a/cc/cc.go b/cc/cc.go
index 113620c..3bb0d6d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -815,6 +815,10 @@
makeLinkType string
// Kythe (source file indexer) paths for this compilation module
kytheFiles android.Paths
+ // Object .o file output paths for this compilation module
+ objFiles android.Paths
+ // Tidy .tidy file output paths for this compilation module
+ tidyFiles android.Paths
// For apex variants, this is set as apex.min_sdk_version
apexSdkVersion android.ApiLevel
@@ -1713,7 +1717,15 @@
// Returns true if Bazel was successfully used for the analysis of this module.
func (c *Module) maybeGenerateBazelActions(actx android.ModuleContext) bool {
- bazelModuleLabel := c.GetBazelLabel(actx, c)
+ var bazelModuleLabel string
+ if actx.ModuleType() == "cc_library" && c.static() {
+ // cc_library is a special case in bp2build; two targets are generated -- one for each
+ // of the shared and static variants. The shared variant keeps the module name, but the
+ // static variant uses a different suffixed name.
+ bazelModuleLabel = bazelLabelForStaticModule(actx, c)
+ } else {
+ bazelModuleLabel = c.GetBazelLabel(actx, c)
+ }
bazelActionsUsed := false
// Mixed builds mode is disabled for modules outside of device OS.
// TODO(b/200841190): Support non-device OS in mixed builds.
@@ -1827,6 +1839,8 @@
return
}
c.kytheFiles = objs.kytheFiles
+ c.objFiles = objs.objFiles
+ c.tidyFiles = objs.tidyFiles
}
if c.linker != nil {
diff --git a/cc/compiler.go b/cc/compiler.go
index 2e62b00..8adc3ab 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -637,9 +637,9 @@
func ndkPathDeps(ctx ModuleContext) android.Paths {
if ctx.Module().(*Module).IsSdkVariant() {
- // The NDK sysroot timestamp file depends on all the NDK sysroot files
- // (headers and libraries).
- return android.Paths{getNdkBaseTimestampFile(ctx)}
+ // The NDK sysroot timestamp file depends on all the NDK sysroot header files
+ // for compiling src to obj files.
+ return android.Paths{getNdkHeadersTimestampFile(ctx)}
}
return nil
}
diff --git a/cc/config/global.go b/cc/config/global.go
index 0b229be..a340e46 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -46,7 +46,6 @@
"-O2",
"-g",
- "-fdebug-info-for-profiling",
"-fno-strict-aliasing",
@@ -125,6 +124,9 @@
"-Werror=sequence-point",
"-Werror=format-security",
"-nostdlibinc",
+
+ // Emit additional debug info for AutoFDO
+ "-fdebug-info-for-profiling",
}
deviceGlobalCppflags = []string{
diff --git a/cc/libbuildversion/Android.bp b/cc/libbuildversion/Android.bp
index 2cff994..b105a30 100644
--- a/cc/libbuildversion/Android.bp
+++ b/cc/libbuildversion/Android.bp
@@ -19,4 +19,5 @@
"//apex_available:platform",
"//apex_available:anyapex",
],
+ vendor_available: true,
}
diff --git a/cc/libbuildversion/libbuildversion.cpp b/cc/libbuildversion/libbuildversion.cpp
index 5242025..1e01c11 100644
--- a/cc/libbuildversion/libbuildversion.cpp
+++ b/cc/libbuildversion/libbuildversion.cpp
@@ -36,7 +36,11 @@
return soong_build_number;
}
+#ifdef __ANDROID_VENDOR__
+ const prop_info* pi = __system_property_find("ro.vendor.build.version.incremental");
+#else
const prop_info* pi = __system_property_find("ro.build.version.incremental");
+#endif
if (pi == nullptr) return "";
std::string property_value;
diff --git a/cc/library.go b/cc/library.go
index 3dceda0..e53aac0 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -236,12 +236,13 @@
Hdrs bazel.LabelListAttribute
- Deps bazel.LabelListAttribute
- Implementation_deps bazel.LabelListAttribute
- Dynamic_deps bazel.LabelListAttribute
- Implementation_dynamic_deps bazel.LabelListAttribute
- Whole_archive_deps bazel.LabelListAttribute
- System_dynamic_deps bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Implementation_deps bazel.LabelListAttribute
+ Dynamic_deps bazel.LabelListAttribute
+ Implementation_dynamic_deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
+ Implementation_whole_archive_deps bazel.LabelListAttribute
+ System_dynamic_deps bazel.LabelListAttribute
Export_includes bazel.StringListAttribute
Export_system_includes bazel.StringListAttribute
@@ -303,40 +304,83 @@
srcs := compilerAttrs.srcs
+ sharedAttrs.Dynamic_deps.Add(baseAttributes.protoDependency)
+ staticAttrs.Deps.Add(baseAttributes.protoDependency)
+
asFlags := compilerAttrs.asFlags
if compilerAttrs.asSrcs.IsEmpty() && sharedAttrs.Srcs_as.IsEmpty() && staticAttrs.Srcs_as.IsEmpty() {
// Skip asflags for BUILD file simplicity if there are no assembly sources.
asFlags = bazel.MakeStringListAttribute(nil)
}
- attrs := &bazelCcLibraryAttributes{
- Srcs: srcs,
- Srcs_c: compilerAttrs.cSrcs,
- Srcs_as: compilerAttrs.asSrcs,
- Hdrs: compilerAttrs.hdrs,
+ staticCommonAttrs := staticOrSharedAttributes{
+ Srcs: *srcs.Clone().Append(staticAttrs.Srcs),
+ Srcs_c: *compilerAttrs.cSrcs.Clone().Append(staticAttrs.Srcs_c),
+ Srcs_as: *compilerAttrs.asSrcs.Clone().Append(staticAttrs.Srcs_as),
+ Copts: *compilerAttrs.copts.Clone().Append(staticAttrs.Copts),
+ Hdrs: *compilerAttrs.hdrs.Clone().Append(staticAttrs.Hdrs),
- Copts: compilerAttrs.copts,
+ Deps: *linkerAttrs.deps.Clone().Append(staticAttrs.Deps),
+ Implementation_deps: *linkerAttrs.implementationDeps.Clone().Append(staticAttrs.Implementation_deps),
+ Dynamic_deps: *linkerAttrs.dynamicDeps.Clone().Append(staticAttrs.Dynamic_deps),
+ Implementation_dynamic_deps: *linkerAttrs.implementationDynamicDeps.Clone().Append(staticAttrs.Implementation_dynamic_deps),
+ Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps,
+ Whole_archive_deps: *linkerAttrs.wholeArchiveDeps.Clone().Append(staticAttrs.Whole_archive_deps),
+ System_dynamic_deps: *linkerAttrs.systemDynamicDeps.Clone().Append(staticAttrs.System_dynamic_deps),
+ }
+
+ sharedCommonAttrs := staticOrSharedAttributes{
+ Srcs: *srcs.Clone().Append(sharedAttrs.Srcs),
+ Srcs_c: *compilerAttrs.cSrcs.Clone().Append(sharedAttrs.Srcs_c),
+ Srcs_as: *compilerAttrs.asSrcs.Clone().Append(sharedAttrs.Srcs_as),
+ Copts: *compilerAttrs.copts.Clone().Append(sharedAttrs.Copts),
+ Hdrs: *compilerAttrs.hdrs.Clone().Append(sharedAttrs.Hdrs),
+
+ Deps: *linkerAttrs.deps.Clone().Append(sharedAttrs.Deps),
+ Implementation_deps: *linkerAttrs.implementationDeps.Clone().Append(sharedAttrs.Implementation_deps),
+ Dynamic_deps: *linkerAttrs.dynamicDeps.Clone().Append(sharedAttrs.Dynamic_deps),
+ Implementation_dynamic_deps: *linkerAttrs.implementationDynamicDeps.Clone().Append(sharedAttrs.Implementation_dynamic_deps),
+ Whole_archive_deps: *linkerAttrs.wholeArchiveDeps.Clone().Append(sharedAttrs.Whole_archive_deps),
+ System_dynamic_deps: *linkerAttrs.systemDynamicDeps.Clone().Append(sharedAttrs.System_dynamic_deps),
+ }
+
+ staticTargetAttrs := &bazelCcLibraryStaticAttributes{
+ staticOrSharedAttributes: staticCommonAttrs,
+
Cppflags: compilerAttrs.cppFlags,
Conlyflags: compilerAttrs.conlyFlags,
Asflags: asFlags,
- Implementation_deps: linkerAttrs.implementationDeps,
- Deps: linkerAttrs.deps,
- Implementation_dynamic_deps: linkerAttrs.implementationDynamicDeps,
- Dynamic_deps: linkerAttrs.dynamicDeps,
- Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
- System_dynamic_deps: linkerAttrs.systemDynamicDeps,
- Export_includes: exportedIncludes.Includes,
- Export_system_includes: exportedIncludes.SystemIncludes,
- Local_includes: compilerAttrs.localIncludes,
- Absolute_includes: compilerAttrs.absoluteIncludes,
- Linkopts: linkerAttrs.linkopts,
- Link_crt: linkerAttrs.linkCrt,
- Use_libcrt: linkerAttrs.useLibcrt,
- Rtti: compilerAttrs.rtti,
- Stl: compilerAttrs.stl,
- Cpp_std: compilerAttrs.cppStd,
- C_std: compilerAttrs.cStd,
+ Export_includes: exportedIncludes.Includes,
+ Export_system_includes: exportedIncludes.SystemIncludes,
+ Local_includes: compilerAttrs.localIncludes,
+ Absolute_includes: compilerAttrs.absoluteIncludes,
+ Use_libcrt: linkerAttrs.useLibcrt,
+ Rtti: compilerAttrs.rtti,
+ Stl: compilerAttrs.stl,
+ Cpp_std: compilerAttrs.cppStd,
+ C_std: compilerAttrs.cStd,
+
+ Features: linkerAttrs.features,
+ }
+
+ sharedTargetAttrs := &bazelCcLibrarySharedAttributes{
+ staticOrSharedAttributes: sharedCommonAttrs,
+ Cppflags: compilerAttrs.cppFlags,
+ Conlyflags: compilerAttrs.conlyFlags,
+ Asflags: asFlags,
+
+ Export_includes: exportedIncludes.Includes,
+ Export_system_includes: exportedIncludes.SystemIncludes,
+ Local_includes: compilerAttrs.localIncludes,
+ Absolute_includes: compilerAttrs.absoluteIncludes,
+ Linkopts: linkerAttrs.linkopts,
+ Link_crt: linkerAttrs.linkCrt,
+ Use_libcrt: linkerAttrs.useLibcrt,
+ Rtti: compilerAttrs.rtti,
+ Stl: compilerAttrs.stl,
+ Cpp_std: compilerAttrs.cppStd,
+ C_std: compilerAttrs.cStd,
Additional_linker_inputs: linkerAttrs.additionalLinkerInputs,
@@ -347,20 +391,20 @@
All: linkerAttrs.stripAll,
None: linkerAttrs.stripNone,
},
-
- Shared: sharedAttrs,
-
- Static: staticAttrs,
-
Features: linkerAttrs.features,
}
- props := bazel.BazelTargetModuleProperties{
- Rule_class: "cc_library",
- Bzl_load_location: "//build/bazel/rules:full_cc_library.bzl",
+ staticProps := bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_library_static",
+ Bzl_load_location: "//build/bazel/rules:cc_library_static.bzl",
+ }
+ sharedProps := bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_library_shared",
+ Bzl_load_location: "//build/bazel/rules:cc_library_shared.bzl",
}
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+ ctx.CreateBazelTargetModule(staticProps, android.CommonAttributes{Name: m.Name() + "_bp2build_cc_library_static"}, staticTargetAttrs)
+ ctx.CreateBazelTargetModule(sharedProps, android.CommonAttributes{Name: m.Name()}, sharedTargetAttrs)
}
// cc_library creates both static and/or shared libraries for a device and/or
@@ -1322,11 +1366,21 @@
return outputFile
}
+func ndkSharedLibDeps(ctx ModuleContext) android.Paths {
+ if ctx.Module().(*Module).IsSdkVariant() {
+ // The NDK sysroot timestamp file depends on all the NDK
+ // sysroot header and shared library files.
+ return android.Paths{getNdkBaseTimestampFile(ctx)}
+ }
+ return nil
+}
+
func (library *libraryDecorator) linkShared(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
var linkerDeps android.Paths
linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
+ linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...)
unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list")
forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list")
@@ -2405,16 +2459,18 @@
Copts: compilerAttrs.copts,
Hdrs: compilerAttrs.hdrs,
- Deps: linkerAttrs.deps,
- Implementation_deps: linkerAttrs.implementationDeps,
- Dynamic_deps: linkerAttrs.dynamicDeps,
- Implementation_dynamic_deps: linkerAttrs.implementationDynamicDeps,
- Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
- System_dynamic_deps: linkerAttrs.systemDynamicDeps,
+ Deps: linkerAttrs.deps,
+ Implementation_deps: linkerAttrs.implementationDeps,
+ Dynamic_deps: linkerAttrs.dynamicDeps,
+ Implementation_dynamic_deps: linkerAttrs.implementationDynamicDeps,
+ Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
+ Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps,
+ System_dynamic_deps: linkerAttrs.systemDynamicDeps,
}
var attrs interface{}
if isStatic {
+ commonAttrs.Deps.Add(baseAttributes.protoDependency)
attrs = &bazelCcLibraryStaticAttributes{
staticOrSharedAttributes: commonAttrs,
@@ -2435,6 +2491,8 @@
Features: linkerAttrs.features,
}
} else {
+ commonAttrs.Dynamic_deps.Add(baseAttributes.protoDependency)
+
attrs = &bazelCcLibrarySharedAttributes{
staticOrSharedAttributes: commonAttrs,
diff --git a/cc/library_test.go b/cc/library_test.go
index 7ddfaa7..d220e19 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -257,9 +257,16 @@
CcObjectFiles: []string{"foo.o"},
Includes: []string{"include"},
SystemIncludes: []string{"system_include"},
- RootStaticArchives: []string{"foo.a"},
+ Headers: []string{"foo.h"},
RootDynamicLibraries: []string{"foo.so"},
},
+ "//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{
+ CcObjectFiles: []string{"foo.o"},
+ Includes: []string{"include"},
+ SystemIncludes: []string{"system_include"},
+ Headers: []string{"foo.h"},
+ RootStaticArchives: []string{"foo.a"},
+ },
},
}
ctx := testCcWithConfig(t, config)
@@ -273,18 +280,25 @@
expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.a"}
android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
+ flagExporter := ctx.ModuleProvider(staticFoo, FlagExporterInfoProvider).(FlagExporterInfo)
+ android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs)
+ android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs)
+ android.AssertPathsRelativeToTopEquals(t, "exported headers", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.GeneratedHeaders)
+ android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps)
+
sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
outputFiles, err = sharedFoo.(android.OutputFileProducer).OutputFiles("")
if err != nil {
- t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
+ t.Errorf("Unexpected error getting cc_library outputfiles %s", err)
}
expectedOutputFiles = []string{"outputbase/execroot/__main__/foo.so"}
android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
- entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0]
- expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"}
- gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
- android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
+ flagExporter = ctx.ModuleProvider(sharedFoo, FlagExporterInfoProvider).(FlagExporterInfo)
+ android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs)
+ android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs)
+ android.AssertPathsRelativeToTopEquals(t, "exported headers", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.GeneratedHeaders)
+ android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps)
}
func TestLibraryVersionScript(t *testing.T) {
diff --git a/cc/linkable.go b/cc/linkable.go
index 560c9de..02d7047 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -384,9 +384,13 @@
includes := android.PathsForBazelOut(ctx, ccInfo.Includes)
systemIncludes := android.PathsForBazelOut(ctx, ccInfo.SystemIncludes)
+ headers := android.PathsForBazelOut(ctx, ccInfo.Headers)
return FlagExporterInfo{
IncludeDirs: android.FirstUniquePaths(includes),
SystemIncludeDirs: android.FirstUniquePaths(systemIncludes),
+ GeneratedHeaders: headers,
+ // necessary to ensure generated headers are considered implicit deps of dependent actions
+ Deps: headers,
}
}
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index ee11db1..6c200f5 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -94,21 +94,6 @@
return android.PathForOutput(ctx, "ndk.timestamp")
}
-// Replace ndk_base.timestamp and ndk.timestamp with ndk_headers.timestamp.
-func skipNdkLibraryDeps(ctx android.ModuleContext, paths android.Paths) android.Paths {
- var newPaths android.Paths
- baseTimestamp := getNdkBaseTimestampFile(ctx)
- fullTimestamp := getNdkFullTimestampFile(ctx)
- headersTimestamp := getNdkHeadersTimestampFile(ctx)
- for _, path := range paths {
- if path == baseTimestamp || path == fullTimestamp {
- path = headersTimestamp
- }
- newPaths = append(newPaths, path)
- }
- return newPaths
-}
-
func NdkSingleton() android.Singleton {
return &ndkSingleton{}
}
diff --git a/cc/pgo.go b/cc/pgo.go
index e78549e..cd017c4 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -96,10 +96,6 @@
flags.Local.LdFlags = append(flags.Local.LdFlags, profileInstrumentFlag)
return flags
}
-func (props *PgoProperties) addSamplingProfileGatherFlags(ctx ModuleContext, flags Flags) Flags {
- flags.Local.CFlags = append(flags.Local.CFlags, props.Pgo.Cflags...)
- return flags
-}
func (props *PgoProperties) getPgoProfileFile(ctx BaseModuleContext) android.OptionalPath {
profileFile := *props.Pgo.Profile_file
@@ -313,10 +309,6 @@
if (props.ShouldProfileModule && props.isInstrumentation()) || props.PgoInstrLink {
// Instrumentation PGO use and gather flags cannot coexist.
return props.addInstrumentationProfileGatherFlags(ctx, flags)
- } else if props.ShouldProfileModule && props.isSampling() {
- flags = props.addSamplingProfileGatherFlags(ctx, flags)
- } else if ctx.DeviceConfig().SamplingPGO() {
- flags = props.addSamplingProfileGatherFlags(ctx, flags)
}
if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") {
diff --git a/cc/proto.go b/cc/proto.go
index 4466144..f3410bc 100644
--- a/cc/proto.go
+++ b/cc/proto.go
@@ -16,8 +16,14 @@
import (
"github.com/google/blueprint/pathtools"
+ "github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/bazel"
+)
+
+const (
+ protoTypeDefault = "lite"
)
// genProto creates a rule to convert a .proto file to generated .pb.cc and .pb.h files and returns
@@ -63,7 +69,7 @@
var lib string
if String(p.Proto.Plugin) == "" {
- switch String(p.Proto.Type) {
+ switch proptools.StringDefault(p.Proto.Type, protoTypeDefault) {
case "full":
if ctx.useSdk() {
lib = "libprotobuf-cpp-full-ndk"
@@ -71,7 +77,7 @@
} else {
lib = "libprotobuf-cpp-full"
}
- case "lite", "":
+ case "lite":
if ctx.useSdk() {
lib = "libprotobuf-cpp-lite-ndk"
static = true
@@ -157,3 +163,69 @@
return flags
}
+
+type protoAttributes struct {
+ Deps bazel.LabelListAttribute
+}
+
+type bp2buildProtoDeps struct {
+ wholeStaticLib *bazel.LabelAttribute
+ implementationWholeStaticLib *bazel.LabelAttribute
+ protoDep *bazel.LabelAttribute
+}
+
+func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) bp2buildProtoDeps {
+ var ret bp2buildProtoDeps
+
+ protoInfo, ok := android.Bp2buildProtoProperties(ctx, m, protoSrcs)
+ if !ok {
+ return ret
+ }
+
+ var depName string
+ typ := proptools.StringDefault(protoInfo.Type, protoTypeDefault)
+ var rule_class string
+ suffix := "_cc_proto"
+ switch typ {
+ case "lite":
+ suffix += "_lite"
+ rule_class = "cc_lite_proto_library"
+ depName = "libprotobuf-cpp-lite"
+ case "full":
+ rule_class = "cc_proto_library"
+ depName = "libprotobuf-cpp-full"
+ default:
+ ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ)
+ }
+
+ dep := android.BazelLabelForModuleDepSingle(ctx, depName)
+ ret.protoDep = &bazel.LabelAttribute{Value: &dep}
+
+ protoLabel := bazel.Label{Label: ":" + protoInfo.Name}
+ var protoAttrs protoAttributes
+ protoAttrs.Deps.SetValue(bazel.LabelList{Includes: []bazel.Label{protoLabel}})
+
+ name := m.Name() + suffix
+
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: rule_class,
+ Bzl_load_location: "//build/bazel/rules:cc_proto.bzl",
+ },
+ android.CommonAttributes{Name: name},
+ &protoAttrs)
+
+ var privateHdrs bool
+ if lib, ok := m.linker.(*libraryDecorator); ok {
+ privateHdrs = !proptools.Bool(lib.Properties.Proto.Export_proto_headers)
+ }
+
+ labelAttr := &bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + name}}
+ if privateHdrs {
+ ret.implementationWholeStaticLib = labelAttr
+ } else {
+ ret.wholeStaticLib = labelAttr
+ }
+
+ return ret
+}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 93d4b4c..d7b1ade 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -35,7 +35,6 @@
asanCflags = []string{
"-fno-omit-frame-pointer",
- "-fno-experimental-new-pass-manager",
}
asanLdflags = []string{"-Wl,-u,__asan_preinit"}
@@ -666,9 +665,6 @@
flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-coverage=stack-depth")
flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-coverage=stack-depth")
- // TODO(b/133876586): Experimental PM breaks sanitizer coverage.
- flags.Local.CFlags = append(flags.Local.CFlags, "-fno-experimental-new-pass-manager")
-
// Disable fortify for fuzzing builds. Generally, we'll be building with
// UBSan or ASan here and the fortify checks pollute the stack traces.
flags.Local.CFlags = append(flags.Local.CFlags, "-U_FORTIFY_SOURCE")
diff --git a/cc/tidy.go b/cc/tidy.go
index 53ff156..78a791f 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -15,6 +15,7 @@
package cc
import (
+ "path/filepath"
"regexp"
"strings"
@@ -183,3 +184,154 @@
}
return flags
}
+
+func init() {
+ android.RegisterSingletonType("tidy_phony_targets", TidyPhonySingleton)
+}
+
+// This TidyPhonySingleton generates both tidy-* and obj-* phony targets for C/C++ files.
+func TidyPhonySingleton() android.Singleton {
+ return &tidyPhonySingleton{}
+}
+
+type tidyPhonySingleton struct{}
+
+// Given a final module, add its tidy/obj phony targets to tidy/objModulesInDirGroup.
+func collectTidyObjModuleTargets(ctx android.SingletonContext, module android.Module,
+ tidyModulesInDirGroup, objModulesInDirGroup map[string]map[string]android.Paths) {
+ allObjFileGroups := make(map[string]android.Paths) // variant group name => obj file Paths
+ allTidyFileGroups := make(map[string]android.Paths) // variant group name => tidy file Paths
+ subsetObjFileGroups := make(map[string]android.Paths) // subset group name => obj file Paths
+ subsetTidyFileGroups := make(map[string]android.Paths) // subset group name => tidy file Paths
+
+ // (1) Collect all obj/tidy files into OS-specific groups.
+ ctx.VisitAllModuleVariants(module, func(variant android.Module) {
+ if ctx.Config().KatiEnabled() && android.ShouldSkipAndroidMkProcessing(variant) {
+ return
+ }
+ if m, ok := variant.(*Module); ok {
+ osName := variant.Target().Os.Name
+ addToOSGroup(osName, m.objFiles, allObjFileGroups, subsetObjFileGroups)
+ addToOSGroup(osName, m.tidyFiles, allTidyFileGroups, subsetTidyFileGroups)
+ }
+ })
+
+ // (2) Add an all-OS group, with "" or "subset" name, to include all os-specific phony targets.
+ addAllOSGroup(ctx, module, allObjFileGroups, "", "obj")
+ addAllOSGroup(ctx, module, allTidyFileGroups, "", "tidy")
+ addAllOSGroup(ctx, module, subsetObjFileGroups, "subset", "obj")
+ addAllOSGroup(ctx, module, subsetTidyFileGroups, "subset", "tidy")
+
+ tidyTargetGroups := make(map[string]android.Path)
+ objTargetGroups := make(map[string]android.Path)
+ genObjTidyPhonyTargets(ctx, module, "obj", allObjFileGroups, objTargetGroups)
+ genObjTidyPhonyTargets(ctx, module, "obj", subsetObjFileGroups, objTargetGroups)
+ genObjTidyPhonyTargets(ctx, module, "tidy", allTidyFileGroups, tidyTargetGroups)
+ genObjTidyPhonyTargets(ctx, module, "tidy", subsetTidyFileGroups, tidyTargetGroups)
+
+ moduleDir := ctx.ModuleDir(module)
+ appendToModulesInDirGroup(tidyTargetGroups, moduleDir, tidyModulesInDirGroup)
+ appendToModulesInDirGroup(objTargetGroups, moduleDir, objModulesInDirGroup)
+}
+
+func (m *tidyPhonySingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ // For tidy-* directory phony targets, there are different variant groups.
+ // tidyModulesInDirGroup[G][D] is for group G, directory D, with Paths
+ // of all phony targets to be included into direct dependents of tidy-D_G.
+ tidyModulesInDirGroup := make(map[string]map[string]android.Paths)
+ // Also for obj-* directory phony targets.
+ objModulesInDirGroup := make(map[string]map[string]android.Paths)
+
+ // Collect tidy/obj targets from the 'final' modules.
+ ctx.VisitAllModules(func(module android.Module) {
+ if module == ctx.FinalModule(module) {
+ collectTidyObjModuleTargets(ctx, module, tidyModulesInDirGroup, objModulesInDirGroup)
+ }
+ })
+
+ suffix := ""
+ if ctx.Config().KatiEnabled() {
+ suffix = "-soong"
+ }
+ generateObjTidyPhonyTargets(ctx, suffix, "obj", objModulesInDirGroup)
+ generateObjTidyPhonyTargets(ctx, suffix, "tidy", tidyModulesInDirGroup)
+}
+
+// The name for an obj/tidy module variant group phony target is Name_group-obj/tidy,
+func objTidyModuleGroupName(module android.Module, group string, suffix string) string {
+ if group == "" {
+ return module.Name() + "-" + suffix
+ }
+ return module.Name() + "_" + group + "-" + suffix
+}
+
+// Generate obj-* or tidy-* phony targets.
+func generateObjTidyPhonyTargets(ctx android.SingletonContext, suffix string, prefix string, objTidyModulesInDirGroup map[string]map[string]android.Paths) {
+ // For each variant group, create a <prefix>-<directory>_group target that
+ // depends on all subdirectories and modules in the directory.
+ for group, modulesInDir := range objTidyModulesInDirGroup {
+ groupSuffix := ""
+ if group != "" {
+ groupSuffix = "_" + group
+ }
+ mmTarget := func(dir string) string {
+ return prefix + "-" + strings.Replace(filepath.Clean(dir), "/", "-", -1) + groupSuffix
+ }
+ dirs, topDirs := android.AddAncestors(ctx, modulesInDir, mmTarget)
+ // Create a <prefix>-soong_group target that depends on all <prefix>-dir_group of top level dirs.
+ var topDirPaths android.Paths
+ for _, dir := range topDirs {
+ topDirPaths = append(topDirPaths, android.PathForPhony(ctx, mmTarget(dir)))
+ }
+ ctx.Phony(prefix+suffix+groupSuffix, topDirPaths...)
+ // Create a <prefix>-dir_group target that depends on all targets in modulesInDir[dir]
+ for _, dir := range dirs {
+ if dir != "." && dir != "" {
+ ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
+ }
+ }
+ }
+}
+
+// Append (obj|tidy)TargetGroups[group] into (obj|tidy)ModulesInDirGroups[group][moduleDir].
+func appendToModulesInDirGroup(targetGroups map[string]android.Path, moduleDir string, modulesInDirGroup map[string]map[string]android.Paths) {
+ for group, phonyPath := range targetGroups {
+ if _, found := modulesInDirGroup[group]; !found {
+ modulesInDirGroup[group] = make(map[string]android.Paths)
+ }
+ modulesInDirGroup[group][moduleDir] = append(modulesInDirGroup[group][moduleDir], phonyPath)
+ }
+}
+
+// Add given files to the OS group and subset group.
+func addToOSGroup(osName string, files android.Paths, allGroups, subsetGroups map[string]android.Paths) {
+ if len(files) > 0 {
+ subsetName := osName + "_subset"
+ allGroups[osName] = append(allGroups[osName], files...)
+ // Now include only the first variant in the subsetGroups.
+ // If clang and clang-tidy get faster, we might include more variants.
+ if _, found := subsetGroups[subsetName]; !found {
+ subsetGroups[subsetName] = files
+ }
+ }
+}
+
+// Add an all-OS group, with groupName, to include all os-specific phony targets.
+func addAllOSGroup(ctx android.SingletonContext, module android.Module, phonyTargetGroups map[string]android.Paths, groupName string, objTidyName string) {
+ if len(phonyTargetGroups) > 0 {
+ var targets android.Paths
+ for group, _ := range phonyTargetGroups {
+ targets = append(targets, android.PathForPhony(ctx, objTidyModuleGroupName(module, group, objTidyName)))
+ }
+ phonyTargetGroups[groupName] = targets
+ }
+}
+
+// Create one phony targets for each group and add them to the targetGroups.
+func genObjTidyPhonyTargets(ctx android.SingletonContext, module android.Module, objTidyName string, fileGroups map[string]android.Paths, targetGroups map[string]android.Path) {
+ for group, files := range fileGroups {
+ groupName := objTidyModuleGroupName(module, group, objTidyName)
+ ctx.Phony(groupName, files...)
+ targetGroups[group] = android.PathForPhony(ctx, groupName)
+ }
+}
diff --git a/dexpreopt/testing.go b/dexpreopt/testing.go
index 2fba01a..5131cd3 100644
--- a/dexpreopt/testing.go
+++ b/dexpreopt/testing.go
@@ -85,12 +85,12 @@
// Prepares a test fixture by enabling dexpreopt, registering the fake_tool_binary module type and
// using that to define the `dex2oatd` module.
var PrepareForTestByEnablingDexpreopt = android.GroupFixturePreparers(
- FixtureModifyGlobalConfig(func(*GlobalConfig) {}),
+ FixtureModifyGlobalConfig(func(android.PathContext, *GlobalConfig) {}),
)
// FixtureModifyGlobalConfig enables dexpreopt (unless modified by the mutator) and modifies the
// configuration.
-func FixtureModifyGlobalConfig(configModifier func(dexpreoptConfig *GlobalConfig)) android.FixturePreparer {
+func FixtureModifyGlobalConfig(configModifier func(ctx android.PathContext, dexpreoptConfig *GlobalConfig)) android.FixturePreparer {
return android.FixtureModifyConfig(func(config android.Config) {
// Initialize the dexpreopt GlobalConfig to an empty structure. This has no effect if it has
// already been set.
@@ -100,48 +100,48 @@
// Retrieve the existing configuration and modify it.
dexpreoptConfig = GetGlobalConfig(pathCtx)
- configModifier(dexpreoptConfig)
+ configModifier(pathCtx, dexpreoptConfig)
})
}
// FixtureSetArtBootJars enables dexpreopt and sets the ArtApexJars property.
func FixtureSetArtBootJars(bootJars ...string) android.FixturePreparer {
- return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+ return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
dexpreoptConfig.ArtApexJars = android.CreateTestConfiguredJarList(bootJars)
})
}
// FixtureSetBootJars enables dexpreopt and sets the BootJars property.
func FixtureSetBootJars(bootJars ...string) android.FixturePreparer {
- return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+ return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
dexpreoptConfig.BootJars = android.CreateTestConfiguredJarList(bootJars)
})
}
// FixtureSetApexBootJars sets the ApexBootJars property in the global config.
func FixtureSetApexBootJars(bootJars ...string) android.FixturePreparer {
- return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+ return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
dexpreoptConfig.ApexBootJars = android.CreateTestConfiguredJarList(bootJars)
})
}
// FixtureSetStandaloneSystemServerJars sets the StandaloneSystemServerJars property.
func FixtureSetStandaloneSystemServerJars(jars ...string) android.FixturePreparer {
- return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+ return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
dexpreoptConfig.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(jars)
})
}
// FixtureSetSystemServerJars sets the SystemServerJars property.
func FixtureSetSystemServerJars(jars ...string) android.FixturePreparer {
- return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+ return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
dexpreoptConfig.SystemServerJars = android.CreateTestConfiguredJarList(jars)
})
}
// FixtureSetApexSystemServerJars sets the ApexSystemServerJars property in the global config.
func FixtureSetApexSystemServerJars(jars ...string) android.FixturePreparer {
- return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+ return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
dexpreoptConfig.ApexSystemServerJars = android.CreateTestConfiguredJarList(jars)
})
}
@@ -149,14 +149,21 @@
// FixtureSetApexStandaloneSystemServerJars sets the ApexStandaloneSystemServerJars property in the
// global config.
func FixtureSetApexStandaloneSystemServerJars(jars ...string) android.FixturePreparer {
- return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+ return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
dexpreoptConfig.ApexStandaloneSystemServerJars = android.CreateTestConfiguredJarList(jars)
})
}
// FixtureSetPreoptWithUpdatableBcp sets the PreoptWithUpdatableBcp property in the global config.
func FixtureSetPreoptWithUpdatableBcp(value bool) android.FixturePreparer {
- return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+ return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
dexpreoptConfig.PreoptWithUpdatableBcp = value
})
}
+
+// FixtureSetBootImageProfiles sets the BootImageProfiles property in the global config.
+func FixtureSetBootImageProfiles(profiles ...string) android.FixturePreparer {
+ return FixtureModifyGlobalConfig(func(ctx android.PathContext, dexpreoptConfig *GlobalConfig) {
+ dexpreoptConfig.BootImageProfiles = android.PathsForSource(ctx, profiles)
+ })
+}
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 3a1f5fc..38065f1 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -16,7 +16,6 @@
import (
"fmt"
- "strconv"
"strings"
"github.com/google/blueprint"
@@ -43,20 +42,6 @@
},
"args", "libs")
-// targetSdkVersion for manifest_fixer
-// When TARGET_BUILD_APPS is not empty, this method returns the unreleased(future) API level
-// This enables release builds (that run with TARGET_BUILD_APPS=[val...]) to target APIs that have not yet been finalized as part of an SDK
-func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext android.SdkContext) string {
- if ctx.Config().UnbundledBuildApps() {
- return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
- }
- targetSdkVersion, err := sdkContext.TargetSdkVersion(ctx).EffectiveVersionString(ctx)
- if err != nil {
- ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
- }
- return targetSdkVersion
-}
-
// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext android.SdkContext,
classLoaderContexts dexpreopt.ClassLoaderContextMap, isLibrary, useEmbeddedNativeLibs, usesNonSdkApis,
@@ -104,7 +89,10 @@
args = append(args, "--logging-parent", loggingParent)
}
var deps android.Paths
- targetSdkVersion := targetSdkVersionForManifestFixer(ctx, sdkContext)
+ targetSdkVersion, err := sdkContext.TargetSdkVersion(ctx).EffectiveVersionString(ctx)
+ if err != nil {
+ ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
+ }
if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
deps = append(deps, ApiFingerprintPath(ctx))
diff --git a/java/android_resources.go b/java/android_resources.go
index 6864ebb..8c5908f 100644
--- a/java/android_resources.go
+++ b/java/android_resources.go
@@ -43,7 +43,7 @@
// androidResourceGlob returns the list of files in the given directory, using the standard
// exclusion patterns for Android resources.
-func androidResourceGlob(ctx android.ModuleContext, dir android.Path) android.Paths {
+func androidResourceGlob(ctx android.EarlyModuleContext, dir android.Path) android.Paths {
return ctx.GlobFiles(filepath.Join(dir.String(), "**/*"), androidResourceIgnoreFilenames)
}
diff --git a/java/app.go b/java/app.go
index c08ec06..b43e532 100755
--- a/java/app.go
+++ b/java/app.go
@@ -45,6 +45,7 @@
ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
android.RegisterBp2BuildMutator("android_app_certificate", AndroidAppCertificateBp2Build)
+ android.RegisterBp2BuildMutator("android_app", AppBp2Build)
}
// AndroidManifest.xml merging
@@ -139,6 +140,7 @@
}
type AndroidApp struct {
+ android.BazelModuleBase
Library
aapt
android.OverridableModuleBase
@@ -291,7 +293,7 @@
if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
a.checkJniLibsSdkVersion(ctx, minSdkVersion)
- android.CheckMinSdkVersion(a, ctx, minSdkVersion)
+ android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
} else {
ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
}
@@ -1438,3 +1440,47 @@
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
}
+
+type bazelAndroidAppAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Manifest bazel.Label
+ Custom_package *string
+ Resource_files bazel.LabelListAttribute
+}
+
+// AppBp2Build is used for android_app.
+func AppBp2Build(ctx android.TopDownMutatorContext) {
+ a, ok := ctx.Module().(*AndroidApp)
+ if !ok || !a.ConvertWithBp2build(ctx) {
+ return
+ }
+ if ctx.ModuleType() != "android_app" {
+ return
+ }
+
+ //TODO(b/209577426): Support multiple arch variants
+ srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Srcs, a.properties.Exclude_srcs))
+
+ manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
+
+ resourceFiles := bazel.LabelList{
+ Includes: []bazel.Label{},
+ }
+ for _, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") {
+ files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))
+ resourceFiles.Includes = append(resourceFiles.Includes, files...)
+ }
+
+ attrs := &bazelAndroidAppAttributes{
+ Srcs: srcs,
+ Manifest: android.BazelLabelForModuleSrcSingle(ctx, manifest),
+ // TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
+ Custom_package: a.overridableAppProperties.Package_name,
+ Resource_files: bazel.MakeLabelListAttribute(resourceFiles),
+ }
+ props := bazel.BazelTargetModuleProperties{Rule_class: "android_binary",
+ Bzl_load_location: "@rules_android//rules:rules.bzl"}
+
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, attrs)
+
+}
diff --git a/java/base.go b/java/base.go
index 2f90db2..c0da215 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1643,8 +1643,7 @@
}
// Implements android.ApexModule
-func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
+func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
sdkSpec := j.MinSdkVersion(ctx)
if !sdkSpec.Specified() {
return fmt.Errorf("min_sdk_version is not specified")
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index bfa6838..bfe895c 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -390,6 +390,13 @@
// Map from the base module name (without prebuilt_ prefix) of a fragment's contents module to the
// hidden API encoded dex jar path.
contentModuleDexJarPaths bootDexJarByModule
+
+ // Path to the image profile file on host (or empty, if profile is not generated).
+ profilePathOnHost android.Path
+
+ // Install path of the boot image profile if it needs to be installed in the APEX, or empty if not
+ // needed.
+ profileInstallPathInApex string
}
func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList {
@@ -418,6 +425,14 @@
}
}
+func (i BootclasspathFragmentApexContentInfo) ProfilePathOnHost() android.Path {
+ return i.profilePathOnHost
+}
+
+func (i BootclasspathFragmentApexContentInfo) ProfileInstallPathInApex() string {
+ return i.profileInstallPathInApex
+}
+
func (b *BootclasspathFragmentModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
tag := ctx.OtherModuleDependencyTag(dep)
if IsBootclasspathFragmentContentDepTag(tag) {
@@ -579,6 +594,11 @@
if imageConfig != nil {
info.modules = imageConfig.modules
+ global := dexpreopt.GetGlobalConfig(ctx)
+ if !global.DisableGenerateProfile {
+ info.profilePathOnHost = imageConfig.profilePathOnHost
+ info.profileInstallPathInApex = imageConfig.profileInstallPathInApex
+ }
}
info.bootImageFilesByArch = bootImageFilesByArch
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index a722946..75083e8 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -256,6 +256,10 @@
// Subdirectory where the image files on device are installed.
installDirOnDevice string
+ // Install path of the boot image profile if it needs to be installed in the APEX, or empty if not
+ // needed.
+ profileInstallPathInApex string
+
// A list of (location, jar) pairs for the Java modules in this image.
modules android.ConfiguredJarList
@@ -272,6 +276,9 @@
// Rules which should be used in make to install the outputs.
profileInstalls android.RuleBuilderInstalls
+ // Path to the image profile file on host (or empty, if profile is not generated).
+ profilePathOnHost android.Path
+
// Target-dependent fields.
variants []*bootImageVariant
}
@@ -769,11 +776,14 @@
FlagForEachArg("--dex-location=", image.getAnyAndroidVariant().dexLocationsDeps).
FlagWithOutput("--reference-profile-file=", profile)
- rule.Install(profile, "/system/etc/boot-image.prof")
+ if image == defaultBootImageConfig(ctx) {
+ rule.Install(profile, "/system/etc/boot-image.prof")
+ image.profileInstalls = append(image.profileInstalls, rule.Installs()...)
+ }
rule.Build("bootJarsProfile", "profile boot jars")
- image.profileInstalls = append(image.profileInstalls, rule.Installs()...)
+ image.profilePathOnHost = profile
return profile
}
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 415a1d4..26c1105 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -56,22 +56,20 @@
artModules := global.ArtApexJars
frameworkModules := global.BootJars.RemoveList(artModules)
- artDirOnHost := "apex/art_boot_images/javalib"
- artDirOnDevice := "apex/com.android.art/javalib"
- frameworkSubdir := "system/framework"
-
// ART config for the primary boot image in the ART apex.
// It includes the Core Libraries.
artCfg := bootImageConfig{
- name: artBootImageName,
- stem: "boot",
- installDirOnHost: artDirOnHost,
- installDirOnDevice: artDirOnDevice,
- modules: artModules,
+ name: artBootImageName,
+ stem: "boot",
+ installDirOnHost: "apex/art_boot_images/javalib",
+ installDirOnDevice: "apex/com.android.art/javalib",
+ profileInstallPathInApex: "etc/boot-image.prof",
+ modules: artModules,
}
// Framework config for the boot image extension.
// It includes framework libraries and depends on the ART config.
+ frameworkSubdir := "system/framework"
frameworkCfg := bootImageConfig{
extends: &artCfg,
name: frameworkBootImageName,
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 3065d57..52ab06e 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1129,6 +1129,22 @@
return generatedScopes
}
+var _ android.ModuleWithMinSdkVersionCheck = (*SdkLibrary)(nil)
+
+func (module *SdkLibrary) CheckMinSdkVersion(ctx android.ModuleContext) {
+ android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx).ApiLevel, func(c android.ModuleContext, do android.PayloadDepsCallback) {
+ ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
+ isExternal := !module.depIsInSameApex(ctx, child)
+ if am, ok := child.(android.ApexModule); ok {
+ if !do(ctx, parent, am, isExternal) {
+ return false
+ }
+ }
+ return !isExternal
+ })
+ })
+}
+
type sdkLibraryComponentTag struct {
blueprint.BaseDependencyTag
name string
@@ -1214,6 +1230,10 @@
}
func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if proptools.String(module.deviceProperties.Min_sdk_version) != "" {
+ module.CheckMinSdkVersion(ctx)
+ }
+
module.generateCommonBuildActions(ctx)
// Only build an implementation library if required.
@@ -2605,12 +2625,12 @@
func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
if module.hideApexVariantFromMake {
- return []android.AndroidMkEntries{android.AndroidMkEntries{
+ return []android.AndroidMkEntries{{
Disabled: true,
}}
}
- return []android.AndroidMkEntries{android.AndroidMkEntries{
+ return []android.AndroidMkEntries{{
Class: "ETC",
OutputFile: android.OptionalPathForPath(module.outputFilePath),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 2271573..f3a19e9 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -1140,3 +1140,87 @@
})
}
}
+
+func TestSdkLibrary_CheckMinSdkVersion(t *testing.T) {
+ preparer := android.GroupFixturePreparers(
+ PrepareForTestWithJavaBuildComponents,
+ PrepareForTestWithJavaDefaultModules,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ )
+
+ preparer.RunTestWithBp(t, `
+ java_sdk_library {
+ name: "sdklib",
+ srcs: ["a.java"],
+ static_libs: ["util"],
+ min_sdk_version: "30",
+ unsafe_ignore_missing_latest_api: true,
+ }
+
+ java_library {
+ name: "util",
+ srcs: ["a.java"],
+ min_sdk_version: "30",
+ }
+ `)
+
+ preparer.
+ RunTestWithBp(t, `
+ java_sdk_library {
+ name: "sdklib",
+ srcs: ["a.java"],
+ libs: ["util"],
+ impl_only_libs: ["util"],
+ stub_only_libs: ["util"],
+ stub_only_static_libs: ["util"],
+ min_sdk_version: "30",
+ unsafe_ignore_missing_latest_api: true,
+ }
+
+ java_library {
+ name: "util",
+ srcs: ["a.java"],
+ }
+ `)
+
+ preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "util".*should support min_sdk_version\(30\)`)).
+ RunTestWithBp(t, `
+ java_sdk_library {
+ name: "sdklib",
+ srcs: ["a.java"],
+ static_libs: ["util"],
+ min_sdk_version: "30",
+ unsafe_ignore_missing_latest_api: true,
+ }
+
+ java_library {
+ name: "util",
+ srcs: ["a.java"],
+ min_sdk_version: "31",
+ }
+ `)
+
+ preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "another_util".*should support min_sdk_version\(30\)`)).
+ RunTestWithBp(t, `
+ java_sdk_library {
+ name: "sdklib",
+ srcs: ["a.java"],
+ static_libs: ["util"],
+ min_sdk_version: "30",
+ unsafe_ignore_missing_latest_api: true,
+ }
+
+ java_library {
+ name: "util",
+ srcs: ["a.java"],
+ static_libs: ["another_util"],
+ min_sdk_version: "30",
+ }
+
+ java_library {
+ name: "another_util",
+ srcs: ["a.java"],
+ min_sdk_version: "31",
+ }
+ `)
+}
diff --git a/mk2rbc/Android.bp b/mk2rbc/Android.bp
index b18bfc7..4fa3eb6 100644
--- a/mk2rbc/Android.bp
+++ b/mk2rbc/Android.bp
@@ -38,7 +38,6 @@
"soong_variables.go",
"types.go",
"variable.go",
- "version_defaults.go",
],
deps: ["androidmk-parser"],
}
diff --git a/mk2rbc/cmd/mk2rbc.go b/mk2rbc/cmd/mk2rbc.go
index bb5a680..d9b4e86 100644
--- a/mk2rbc/cmd/mk2rbc.go
+++ b/mk2rbc/cmd/mk2rbc.go
@@ -80,7 +80,6 @@
var tracedVariables []string
var errorLogger = errorSink{data: make(map[string]datum)}
var makefileFinder = &LinuxMakefileFinder{}
-var versionDefaultsMk = filepath.Join("build", "make", "core", "version_defaults.mk")
func main() {
flag.Usage = func() {
@@ -168,18 +167,14 @@
if len(files) != 1 {
quit(fmt.Errorf("a launcher can be generated only for a single product"))
}
- versionDefaults, err := generateVersionDefaults()
- if err != nil {
- quit(err)
+ if *inputVariables == "" {
+ quit(fmt.Errorf("the product launcher requires an input variables file"))
}
- versionDefaultsPath := outputFilePath(versionDefaultsMk)
- err = writeGenerated(versionDefaultsPath, versionDefaults)
- if err != nil {
- fmt.Fprintf(os.Stderr, "%s: %s", files[0], err)
- ok = false
+ if !convertOne(*inputVariables) {
+ quit(fmt.Errorf("the product launcher input variables file failed to convert"))
}
- err = writeGenerated(*launcher, mk2rbc.Launcher(outputFilePath(files[0]), versionDefaultsPath,
+ err := writeGenerated(*launcher, mk2rbc.Launcher(outputFilePath(files[0]), outputFilePath(*inputVariables),
mk2rbc.MakePath2ModuleName(files[0])))
if err != nil {
fmt.Fprintf(os.Stderr, "%s: %s", files[0], err)
@@ -213,15 +208,6 @@
}
}
-func generateVersionDefaults() (string, error) {
- versionSettings, err := mk2rbc.ParseVersionDefaults(filepath.Join(*rootDir, versionDefaultsMk))
- if err != nil {
- return "", err
- }
- return mk2rbc.VersionDefaults(versionSettings), nil
-
-}
-
func quit(s interface{}) {
fmt.Fprintln(os.Stderr, s)
os.Exit(2)
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 4b9779c..cade4d2 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -1111,10 +1111,8 @@
}
switch call.name {
- case "filter":
+ case "filter", "filter-out":
return ctx.parseCompareFilterFuncResult(directive, call, value, isEq), true
- case "filter-out":
- return ctx.parseCompareFilterFuncResult(directive, call, value, !isEq), true
case "wildcard":
return ctx.parseCompareWildcardFuncResult(directive, call, value, !isEq), true
case "findstring":
@@ -1695,12 +1693,12 @@
return starScript, nil
}
-func Launcher(mainModuleUri, versionDefaultsUri, mainModuleName string) string {
+func Launcher(mainModuleUri, inputVariablesUri, mainModuleName string) string {
var buf bytes.Buffer
fmt.Fprintf(&buf, "load(%q, %q)\n", baseUri, baseName)
- fmt.Fprintf(&buf, "load(%q, \"version_defaults\")\n", versionDefaultsUri)
+ fmt.Fprintf(&buf, "load(%q, input_variables_init = \"init\")\n", inputVariablesUri)
fmt.Fprintf(&buf, "load(%q, \"init\")\n", mainModuleUri)
- fmt.Fprintf(&buf, "%s(%s(%q, init, version_defaults))\n", cfnPrintVars, cfnMain, mainModuleName)
+ fmt.Fprintf(&buf, "%s(%s(%q, init, input_variables_init))\n", cfnPrintVars, cfnMain, mainModuleName)
return buf.String()
}
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index dfdf274..fa33e75 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -390,6 +390,8 @@
ifeq (,$(filter barbet coral%,$(TARGET_PRODUCT)))
else ifneq (,$(filter barbet%,$(TARGET_PRODUCT)))
endif
+ifeq (,$(filter-out sunfish_kasan, $(TARGET_PRODUCT)))
+endif
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
@@ -409,6 +411,8 @@
pass
elif rblf.filter("barbet%", g["TARGET_PRODUCT"]):
pass
+ if not rblf.filter_out("sunfish_kasan", g["TARGET_PRODUCT"]):
+ pass
`,
},
{
diff --git a/mk2rbc/version_defaults.go b/mk2rbc/version_defaults.go
deleted file mode 100644
index 64645d7..0000000
--- a/mk2rbc/version_defaults.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 mk2rbc
-
-import (
- "bytes"
- "fmt"
- "io/ioutil"
- "os"
- "sort"
- "strconv"
- "strings"
-
- mkparser "android/soong/androidmk/parser"
-)
-
-const codenamePrefix = "PLATFORM_VERSION_CODENAME."
-
-// ParseVersionDefaults extracts version settings from the given file
-// and returns the map.
-func ParseVersionDefaults(path string) (map[string]string, error) {
- contents, err := ioutil.ReadFile(path)
- if err != nil {
- return nil, err
- }
- parser := mkparser.NewParser(path, bytes.NewBuffer(contents))
- nodes, errs := parser.Parse()
- if len(errs) > 0 {
- for _, e := range errs {
- fmt.Fprintln(os.Stderr, "ERROR:", e)
- }
- return nil, fmt.Errorf("cannot parse %s", path)
- }
-
- result := map[string]string{
- "DEFAULT_PLATFORM_VERSION": "",
- "MAX_PLATFORM_VERSION": "",
- "MIN_PLATFORM_VERSION": "A",
- "PLATFORM_BASE_SDK_EXTENSION_VERSION": "",
- "PLATFORM_SDK_EXTENSION_VERSION": "",
- "PLATFORM_SDK_VERSION": "",
- "PLATFORM_SECURITY_PATCH": "",
- "PLATFORM_VERSION_LAST_STABLE": "",
- }
- for _, node := range nodes {
- asgn, ok := node.(*mkparser.Assignment)
- if !(ok && asgn.Name.Const()) {
- continue
- }
- s := asgn.Name.Strings[0]
- _, ok = result[s]
- if !ok {
- ok = strings.HasPrefix(s, codenamePrefix)
- }
- if !ok {
- continue
- }
- v := asgn.Value
- if !v.Const() {
- return nil, fmt.Errorf("the value of %s should be constant", s)
- }
- result[s] = strings.TrimSpace(v.Strings[0])
- }
- return result, nil
-}
-
-func genericValue(s string) interface{} {
- if ival, err := strconv.ParseInt(s, 0, 0); err == nil {
- return ival
- }
- return s
-}
-
-// VersionDefaults generates the contents of the version_defaults.rbc file
-func VersionDefaults(values map[string]string) string {
- var sink bytes.Buffer
- var lines []string
- var codenames []string
- for name, value := range values {
- if strings.HasPrefix(name, codenamePrefix) {
- codenames = append(codenames,
- fmt.Sprintf("%q: %q", strings.TrimPrefix(name, codenamePrefix), value))
- } else {
- // Print numbers as such
- lines = append(lines, fmt.Sprintf(" %s = %#v,\n",
- strings.ToLower(name), genericValue(value)))
- }
- }
-
- sort.Strings(lines)
- sort.Strings(codenames)
-
- sink.WriteString("version_defaults = struct(\n")
- for _, l := range lines {
- sink.WriteString(l)
- }
- sink.WriteString(" codenames = { ")
- sink.WriteString(strings.Join(codenames, ", "))
- sink.WriteString(" }\n)\n")
- return sink.String()
-}
diff --git a/mk2rbc/version_defaults_test.go b/mk2rbc/version_defaults_test.go
deleted file mode 100644
index c78fa32..0000000
--- a/mk2rbc/version_defaults_test.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package mk2rbc
-
-import (
- "path/filepath"
- "reflect"
- "strings"
- "testing"
-)
-
-func TestParseVersionDefaults(t *testing.T) {
- testDir := getTestDirectory()
- abspath := func(relPath string) string { return filepath.Join(testDir, relPath) }
- actualProducts, err := ParseVersionDefaults(abspath("version_defaults.mk.test"))
- if err != nil {
- t.Fatal(err)
- }
- expectedProducts := map[string]string{
- "DEFAULT_PLATFORM_VERSION": "TP1A",
- "MAX_PLATFORM_VERSION": "TP1A",
- "MIN_PLATFORM_VERSION": "TP1A",
- "PLATFORM_BASE_SDK_EXTENSION_VERSION": "0",
- "PLATFORM_SDK_EXTENSION_VERSION": "1",
- "PLATFORM_SDK_VERSION": "31",
- "PLATFORM_SECURITY_PATCH": "2021-10-05",
- "PLATFORM_VERSION_LAST_STABLE": "12",
- "PLATFORM_VERSION_CODENAME.SP2A": "Sv2",
- "PLATFORM_VERSION_CODENAME.TP1A": "Tiramisu",
- }
- if !reflect.DeepEqual(actualProducts, expectedProducts) {
- t.Errorf("\nExpected: %v\n Actual: %v", expectedProducts, actualProducts)
- }
-}
-
-func TestVersionDefaults(t *testing.T) {
- testDir := getTestDirectory()
- abspath := func(relPath string) string { return filepath.Join(testDir, relPath) }
- actualProducts, err := ParseVersionDefaults(abspath("version_defaults.mk.test"))
- if err != nil {
- t.Fatal(err)
- }
- expectedString := `version_defaults = struct(
- default_platform_version = "TP1A",
- max_platform_version = "TP1A",
- min_platform_version = "TP1A",
- platform_base_sdk_extension_version = 0,
- platform_sdk_extension_version = 1,
- platform_sdk_version = 31,
- platform_security_patch = "2021-10-05",
- platform_version_last_stable = 12,
- codenames = { "SP2A": "Sv2", "TP1A": "Tiramisu" }
-)
-`
- actualString := VersionDefaults(actualProducts)
- if !reflect.DeepEqual(actualString, expectedString) {
- t.Errorf("\nExpected: %v\nActual:\n%v",
- strings.ReplaceAll(expectedString, "\n", "\n"),
- strings.ReplaceAll(actualString, "\n", "\n"))
- }
-
-}
diff --git a/python/library.go b/python/library.go
index b920117..9c92ebd 100644
--- a/python/library.go
+++ b/python/library.go
@@ -96,8 +96,8 @@
}
props := bazel.BazelTargetModuleProperties{
- // Use the native py_library rule.
- Rule_class: "py_library",
+ Rule_class: "py_library",
+ Bzl_load_location: "//build/bazel/rules/python:library.bzl",
}
ctx.CreateBazelTargetModule(props, android.CommonAttributes{
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 32d02e4..5e1b4b7 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -30,7 +30,7 @@
defaultBindgenFlags = []string{""}
// bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures.
- bindgenClangVersion = "clang-r433403"
+ bindgenClangVersion = "clang-r437112"
_ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string {
if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" {
diff --git a/rust/builder.go b/rust/builder.go
index 60b5926..a7efc28 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -216,6 +216,13 @@
// Suppress an implicit sysroot
rustcFlags = append(rustcFlags, "--sysroot=/dev/null")
+ // Enable incremental compilation if requested by user
+ if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
+ incrementalPath := android.PathForOutput(ctx, "rustc").String()
+
+ rustcFlags = append(rustcFlags, "-C incremental="+incrementalPath)
+ }
+
// Collect linker flags
linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
linkFlags = append(linkFlags, flags.LinkFlags...)
diff --git a/rust/config/global.go b/rust/config/global.go
index 78c8dae..23384e5 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -55,6 +55,8 @@
deviceGlobalRustFlags = []string{
"-C panic=abort",
"-Z link-native-libraries=no",
+ // Generate additional debug info for AutoFDO
+ "-Z debug-info-for-profiling",
}
deviceGlobalLinkFlags = []string{
diff --git a/rust/project_json.go b/rust/project_json.go
index ae48312..fe259d6 100644
--- a/rust/project_json.go
+++ b/rust/project_json.go
@@ -211,6 +211,8 @@
comp = c.binaryDecorator.baseCompiler
case *procMacroDecorator:
comp = c.baseCompiler
+ case *toolchainLibraryDecorator:
+ comp = c.baseCompiler
default:
return nil, nil, false
}
diff --git a/scripts/check_boot_jars/package_allowed_list.txt b/scripts/check_boot_jars/package_allowed_list.txt
index ed63651..a02c195 100644
--- a/scripts/check_boot_jars/package_allowed_list.txt
+++ b/scripts/check_boot_jars/package_allowed_list.txt
@@ -72,6 +72,7 @@
jdk\.internal
jdk\.internal\.math
jdk\.internal\.misc
+jdk\.internal\.ref
jdk\.internal\.reflect
jdk\.internal\.util
jdk\.internal\.vm\.annotation
diff --git a/scripts/rbc-run b/scripts/rbc-run
index 235da75..7243421 100755
--- a/scripts/rbc-run
+++ b/scripts/rbc-run
@@ -2,7 +2,7 @@
# Convert and run one configuration
# Args: a product/board makefile optionally followed by additional arguments
# that will be passed to rbcrun.
-[[ $# -gt 0 && -f "$1" ]] || { echo "Usage: ${0##*/} product.mk [Additional rbcrun arguments]" >&2; exit 1; }
+[[ $# -gt 1 && -f "$1" && -f "$2" ]] || { echo "Usage: ${0##*/} product.mk input_variables.mk [Additional rbcrun arguments]" >&2; exit 1; }
set -eu
declare -r output_root="${OUT_DIR:-out}"
@@ -10,7 +10,8 @@
declare -r converter="${output_root}/soong/mk2rbc"
declare -r launcher="${output_root}/rbc/launcher.rbc"
declare -r makefile="$1"
-shift
-"${converter}" -mode=write -r --outdir "${output_root}/rbc" --launcher="${launcher}" "${makefile}"
+declare -r input_variables="$2"
+shift 2
+"${converter}" -mode=write -r --outdir "${output_root}/rbc" --input_variables "${input_variables}" --launcher="${launcher}" "${makefile}"
"${runner}" RBC_OUT="make,global" RBC_DEBUG="${RBC_DEBUG:-}" $@ "${launcher}"
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index ff2af43..2dacdb5 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -40,6 +40,7 @@
}
`, apex, fragment)),
android.FixtureAddFile("frameworks/base/config/boot-profile.txt", nil),
+ android.FixtureAddFile("frameworks/base/config/boot-image-profile.txt", nil),
android.FixtureAddFile("build/soong/scripts/check_boot_jars/package_allowed_list.txt", nil),
)
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 4ced722..ae9a2ce 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -153,7 +153,12 @@
return true, nil
}
-func primaryBuilderInvocation(config Config, name string, output string, specificArgs []string) bootstrap.PrimaryBuilderInvocation {
+func primaryBuilderInvocation(
+ config Config,
+ name string,
+ output string,
+ specificArgs []string,
+ description string) bootstrap.PrimaryBuilderInvocation {
commonArgs := make([]string, 0, 0)
if !config.skipSoongTests {
@@ -178,9 +183,10 @@
allArgs = append(allArgs, "Android.bp")
return bootstrap.PrimaryBuilderInvocation{
- Inputs: []string{"Android.bp"},
- Outputs: []string{output},
- Args: allArgs,
+ Inputs: []string{"Android.bp"},
+ Outputs: []string{output},
+ Args: allArgs,
+ Description: description,
}
}
@@ -232,7 +238,9 @@
config,
soongBuildTag,
config.SoongNinjaFile(),
- mainSoongBuildExtraArgs)
+ mainSoongBuildExtraArgs,
+ fmt.Sprintf("analyzing Android.bp files and generating ninja file at %s", config.SoongNinjaFile()),
+ )
if config.bazelBuildMode() == mixedBuild {
// Mixed builds call Bazel from soong_build and they therefore need the
@@ -248,7 +256,9 @@
config.Bp2BuildMarkerFile(),
[]string{
"--bp2build_marker", config.Bp2BuildMarkerFile(),
- })
+ },
+ fmt.Sprintf("converting Android.bp files to BUILD files at %s/bp2build", config.SoongOutDir()),
+ )
jsonModuleGraphInvocation := primaryBuilderInvocation(
config,
@@ -256,15 +266,20 @@
config.ModuleGraphFile(),
[]string{
"--module_graph_file", config.ModuleGraphFile(),
- })
+ },
+ fmt.Sprintf("generating the Soong module graph at %s", config.ModuleGraphFile()),
+ )
+ queryviewDir := filepath.Join(config.SoongOutDir(), "queryview")
queryviewInvocation := primaryBuilderInvocation(
config,
queryviewTag,
config.QueryviewMarkerFile(),
[]string{
- "--bazel_queryview_dir", filepath.Join(config.SoongOutDir(), "queryview"),
- })
+ "--bazel_queryview_dir", queryviewDir,
+ },
+ fmt.Sprintf("generating the Soong module graph as a Bazel workspace at %s", queryviewDir),
+ )
soongDocsInvocation := primaryBuilderInvocation(
config,
@@ -272,7 +287,9 @@
config.SoongDocsHtml(),
[]string{
"--soong_docs", config.SoongDocsHtml(),
- })
+ },
+ fmt.Sprintf("generating Soong docs at %s", config.SoongDocsHtml()),
+ )
globFiles := []string{
config.NamedGlobFile(soongBuildTag),