Merge "Fix duplicate variations when using the VSDK."
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..9f386ca
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "imports": [
+ {
+ "path": "packages/modules/SdkExtensions"
+ }
+ ]
+}
diff --git a/android/apex.go b/android/apex.go
index 4b74436..4618fe9 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -117,19 +117,6 @@
return false
}
-// InApexByBaseName tells whether this apex variant of the module is part of the given apexVariant
-// or not, where the APEX is specified by its canonical base name, i.e. typically beginning with
-// "com.android.". In particular this function doesn't differentiate between source and prebuilt
-// APEXes, where the latter may have "prebuilt_" prefixes.
-func (i ApexInfo) InApexVariantByBaseName(apexVariant string) bool {
- for _, a := range i.InApexVariants {
- if RemoveOptionalPrebuiltPrefix(a) == apexVariant {
- return true
- }
- }
- return false
-}
-
func (i ApexInfo) InApexModule(apexModuleName string) bool {
for _, a := range i.InApexModules {
if a == apexModuleName {
@@ -669,8 +656,8 @@
mctx.VisitDirectDeps(func(dep Module) {
if _, ok := mctx.OtherModuleDependencyTag(dep).(CopyDirectlyInAnyApexTag); ok {
depBase := dep.(ApexModule).apexModuleBase()
- base.ApexProperties.DirectlyInAnyApex = depBase.ApexProperties.DirectlyInAnyApex
- base.ApexProperties.InAnyApex = depBase.ApexProperties.InAnyApex
+ depBase.ApexProperties.DirectlyInAnyApex = base.ApexProperties.DirectlyInAnyApex
+ depBase.ApexProperties.InAnyApex = base.ApexProperties.InAnyApex
}
})
diff --git a/android/bazel.go b/android/bazel.go
index ef770bf..4967b12 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -220,15 +220,8 @@
// Per-module denylist to opt modules out of mixed builds. Such modules will
// still be generated via bp2build.
mixedBuildsDisabledList = []string{
- "libc_common", // cparsons@ cc_library_static, depends on //bionic/libc:libc_nopthread
- "libc_common_static", // cparsons@ cc_library_static, depends on //bionic/libc:libc_common
- "libc_common_shared", // cparsons@ cc_library_static, depends on //bionic/libc:libc_common
- "libc_netbsd", // lberki@, cc_library_static, version script assignment of 'LIBC_PRIVATE' to symbol 'SHA1Final' failed: symbol not defined
- "libc_nopthread", // cparsons@ cc_library_static, version script assignment of 'LIBC' to symbol 'memcmp' failed: symbol not defined
- "libc_openbsd", // ruperts@, cc_library_static, OK for bp2build but error: duplicate symbol: strcpy for mixed builds
- "libarm-optimized-routines-string", // jingwen@, cc_library_static, OK for bp2build but b/186615213 (asflags not handled in bp2build), version script assignment of 'LIBC' to symbol 'memcmp' failed: symbol not defined (also for memrchr, strnlen)
- "fmtlib_ndk", // http://b/187040371, cc_library_static, OK for bp2build but format-inl.h:11:10: fatal error: 'cassert' file not found for mixed builds
- "libc_nomalloc", // cc_library_static, OK for bp2build but ld.lld: error: undefined symbol: pthread_mutex_lock (and others)
+ "libc_common_shared", // cparsons@ cc_library_static, breaks module `libc`.
+ "libc_nomalloc", // cparsons@ cc_library_static, breaks module `linker`
}
// Used for quicker lookups
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index a1206dc..f906c8a 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -351,6 +351,9 @@
"HOME="+paths.homeDir,
pwdPrefix(),
"BUILD_DIR="+absolutePath(paths.buildDir),
+ // Make OUT_DIR absolute here so tools/bazel.sh uses the correct
+ // OUT_DIR at <root>/out, instead of <root>/out/soong/workspace/out.
+ "OUT_DIR="+absolutePath(paths.outDir()),
// Disables local host detection of gcc; toolchain information is defined
// explicitly in BUILD files.
"BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1")
@@ -576,6 +579,11 @@
return filepath.Join(p.buildDir, "workspace")
}
+// Returns the path to the top level out dir ($OUT_DIR).
+func (p *bazelPaths) outDir() string {
+ return filepath.Dir(p.buildDir)
+}
+
// Issues commands to Bazel to receive results for all cquery requests
// queued in the BazelContext.
func (context *bazelContext) InvokeBazel() error {
diff --git a/apex/apex.go b/apex/apex.go
index 3448327..926085b 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2020,7 +2020,7 @@
a.filesInfo = filesInfo
// Set suffix and primaryApexType depending on the ApexType
- buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuildApps()
+ buildFlattenedAsDefault := ctx.Config().FlattenApex()
switch a.properties.ApexType {
case imageApex:
if buildFlattenedAsDefault {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 364013f..6a7c35c 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -709,6 +709,79 @@
}
}
+func TestApexManifestMinSdkVersion(t *testing.T) {
+ ctx := testApex(t, `
+ apex_defaults {
+ name: "my_defaults",
+ key: "myapex.key",
+ product_specific: true,
+ file_contexts: ":my-file-contexts",
+ updatable: false,
+ }
+ apex {
+ name: "myapex_30",
+ min_sdk_version: "30",
+ defaults: ["my_defaults"],
+ }
+
+ apex {
+ name: "myapex_current",
+ min_sdk_version: "current",
+ defaults: ["my_defaults"],
+ }
+
+ apex {
+ name: "myapex_none",
+ defaults: ["my_defaults"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ filegroup {
+ name: "my-file-contexts",
+ srcs: ["product_specific_file_contexts"],
+ }
+ `, withFiles(map[string][]byte{
+ "product_specific_file_contexts": nil,
+ }), android.FixtureModifyProductVariables(
+ func(variables android.FixtureProductVariables) {
+ variables.Unbundled_build = proptools.BoolPtr(true)
+ variables.Always_use_prebuilt_sdks = proptools.BoolPtr(false)
+ }), android.FixtureMergeEnv(map[string]string{
+ "UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT": "true",
+ }))
+
+ testCases := []struct {
+ module string
+ minSdkVersion string
+ }{
+ {
+ module: "myapex_30",
+ minSdkVersion: "30",
+ },
+ {
+ module: "myapex_current",
+ minSdkVersion: "Q.$$(cat out/soong/api_fingerprint.txt)",
+ },
+ {
+ module: "myapex_none",
+ minSdkVersion: "Q.$$(cat out/soong/api_fingerprint.txt)",
+ },
+ }
+ for _, tc := range testCases {
+ module := ctx.ModuleForTests(tc.module, "android_common_"+tc.module+"_image")
+ args := module.Rule("apexRule").Args
+ optFlags := args["opt_flags"]
+ if !strings.Contains(optFlags, "--min_sdk_version "+tc.minSdkVersion) {
+ t.Errorf("%s: Expected min_sdk_version=%s, got: %s", tc.module, tc.minSdkVersion, optFlags)
+ }
+ }
+}
+
func TestBasicZipApex(t *testing.T) {
ctx := testApex(t, `
apex {
@@ -7611,6 +7684,80 @@
}))
}
+func TestApexJavaCoverage(t *testing.T) {
+ bp := `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["mylib"],
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "mylib",
+ srcs: ["mylib.java"],
+ apex_available: ["myapex"],
+ compile_dex: true,
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: ["mybootclasspathlib"],
+ apex_available: ["myapex"],
+ }
+
+ java_library {
+ name: "mybootclasspathlib",
+ srcs: ["mybootclasspathlib.java"],
+ apex_available: ["myapex"],
+ compile_dex: true,
+ }
+
+ systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ contents: ["mysystemserverclasspathlib"],
+ apex_available: ["myapex"],
+ }
+
+ java_library {
+ name: "mysystemserverclasspathlib",
+ srcs: ["mysystemserverclasspathlib.java"],
+ apex_available: ["myapex"],
+ compile_dex: true,
+ }
+ `
+
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithMyapex,
+ java.PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAndroidBuildComponents,
+ android.FixtureWithRootAndroidBp(bp),
+ android.FixtureMergeEnv(map[string]string{
+ "EMMA_INSTRUMENT": "true",
+ }),
+ ).RunTest(t)
+
+ // Make sure jacoco ran on both mylib and mybootclasspathlib
+ if result.ModuleForTests("mylib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
+ t.Errorf("Failed to find jacoco rule for mylib")
+ }
+ if result.ModuleForTests("mybootclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
+ t.Errorf("Failed to find jacoco rule for mybootclasspathlib")
+ }
+ if result.ModuleForTests("mysystemserverclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
+ t.Errorf("Failed to find jacoco rule for mysystemserverclasspathlib")
+ }
+}
+
func TestMain(m *testing.M) {
os.Exit(m.Run())
}
diff --git a/apex/builder.go b/apex/builder.go
index da8841c..021e499 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -602,6 +602,11 @@
// codename
if moduleMinSdkVersion.IsCurrent() || moduleMinSdkVersion.IsNone() {
minSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String()
+
+ if java.UseApiFingerprint(ctx) {
+ minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
+ implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
+ }
}
// apex module doesn't have a concept of target_sdk_version, hence for the time
// being targetSdkVersion == default targetSdkVersion of the branch.
@@ -611,10 +616,6 @@
targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
}
- if java.UseApiFingerprint(ctx) {
- minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
- implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
- }
optFlags = append(optFlags, "--target_sdk_version "+targetSdkVersion)
optFlags = append(optFlags, "--min_sdk_version "+minSdkVersion)
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 6125ef5..81bfc86 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -228,10 +228,11 @@
})
// Create an ApexInfo for the prebuilt_apex.
+ apexVariationName := android.RemoveOptionalPrebuiltPrefix(mctx.ModuleName())
apexInfo := android.ApexInfo{
- ApexVariationName: android.RemoveOptionalPrebuiltPrefix(mctx.ModuleName()),
- InApexVariants: []string{mctx.ModuleName()},
- InApexModules: []string{mctx.ModuleName()},
+ ApexVariationName: apexVariationName,
+ InApexVariants: []string{apexVariationName},
+ InApexModules: []string{apexVariationName},
ApexContents: []*android.ApexContents{apexContents},
ForPrebuiltApex: true,
}
diff --git a/bazel/properties.go b/bazel/properties.go
index 8adc9d0..b2d68da 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -140,7 +140,6 @@
// Return all needles in a given haystack, where needleFn is true for needles.
func FilterLabelList(haystack LabelList, needleFn func(string) bool) LabelList {
var includes []Label
-
for _, inc := range haystack.Includes {
if needleFn(inc.Label) {
includes = append(includes, inc)
@@ -308,19 +307,19 @@
}
PlatformTargetMap = map[string]string{
- TARGET_ANDROID_ARM: "//build/bazel/platforms:android_arm",
- TARGET_ANDROID_ARM64: "//build/bazel/platforms:android_arm64",
- TARGET_ANDROID_X86: "//build/bazel/platforms:android_x86",
- TARGET_ANDROID_X86_64: "//build/bazel/platforms:android_x86_64",
- TARGET_DARWIN_X86_64: "//build/bazel/platforms:darwin_x86_64",
- TARGET_FUCHSIA_ARM64: "//build/bazel/platforms:fuchsia_arm64",
- TARGET_FUCHSIA_X86_64: "//build/bazel/platforms:fuchsia_x86_64",
- TARGET_LINUX_X86: "//build/bazel/platforms:linux_glibc_x86",
- TARGET_LINUX_x86_64: "//build/bazel/platforms:linux_glibc_x86_64",
- TARGET_LINUX_BIONIC_ARM64: "//build/bazel/platforms:linux_bionic_arm64",
- TARGET_LINUX_BIONIC_X86_64: "//build/bazel/platforms:linux_bionic_x86_64",
- TARGET_WINDOWS_X86: "//build/bazel/platforms:windows_x86",
- TARGET_WINDOWS_X86_64: "//build/bazel/platforms:windows_x86_64",
+ TARGET_ANDROID_ARM: "//build/bazel/platforms/os_arch:android_arm",
+ TARGET_ANDROID_ARM64: "//build/bazel/platforms/os_arch:android_arm64",
+ TARGET_ANDROID_X86: "//build/bazel/platforms/os_arch:android_x86",
+ TARGET_ANDROID_X86_64: "//build/bazel/platforms/os_arch:android_x86_64",
+ TARGET_DARWIN_X86_64: "//build/bazel/platforms/os_arch:darwin_x86_64",
+ TARGET_FUCHSIA_ARM64: "//build/bazel/platforms/os_arch:fuchsia_arm64",
+ TARGET_FUCHSIA_X86_64: "//build/bazel/platforms/os_arch:fuchsia_x86_64",
+ TARGET_LINUX_X86: "//build/bazel/platforms/os_arch:linux_glibc_x86",
+ TARGET_LINUX_x86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
+ TARGET_LINUX_BIONIC_ARM64: "//build/bazel/platforms/os_arch:linux_bionic_arm64",
+ TARGET_LINUX_BIONIC_X86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64",
+ TARGET_WINDOWS_X86: "//build/bazel/platforms/os_arch:windows_x86",
+ TARGET_WINDOWS_X86_64: "//build/bazel/platforms/os_arch:windows_x86_64",
CONDITIONS_DEFAULT: ConditionsDefaultSelectKey, // The default condition of an os select map.
}
@@ -332,49 +331,174 @@
HasConfigurableValues() bool
}
-// Represents an attribute whose value is a single label
-type LabelAttribute struct {
- Value Label
+type labelArchValues struct {
X86 Label
X86_64 Label
Arm Label
Arm64 Label
+
+ ConditionsDefault Label
+}
+
+type labelTargetValue struct {
+ // E.g. for android
+ OsValue Label
+
+ // E.g. for android_arm, android_arm64, ...
+ ArchValues labelArchValues
+}
+
+type labelTargetValues struct {
+ Android labelTargetValue
+ Darwin labelTargetValue
+ Fuchsia labelTargetValue
+ Linux labelTargetValue
+ LinuxBionic labelTargetValue
+ Windows labelTargetValue
+
+ ConditionsDefault labelTargetValue
+}
+
+// Represents an attribute whose value is a single label
+type LabelAttribute struct {
+ Value Label
+
+ ArchValues labelArchValues
+
+ TargetValues labelTargetValues
}
func (attr *LabelAttribute) GetValueForArch(arch string) Label {
- switch arch {
- case ARCH_ARM:
- return attr.Arm
- case ARCH_ARM64:
- return attr.Arm64
- case ARCH_X86:
- return attr.X86
- case ARCH_X86_64:
- return attr.X86_64
- case CONDITIONS_DEFAULT:
- return attr.Value
- default:
- panic("Invalid arch type")
+ var v *Label
+ if v = attr.archValuePtrs()[arch]; v == nil {
+ panic(fmt.Errorf("Unknown arch: %s", arch))
}
+ return *v
}
func (attr *LabelAttribute) SetValueForArch(arch string, value Label) {
- switch arch {
- case ARCH_ARM:
- attr.Arm = value
- case ARCH_ARM64:
- attr.Arm64 = value
- case ARCH_X86:
- attr.X86 = value
- case ARCH_X86_64:
- attr.X86_64 = value
- default:
- panic("Invalid arch type")
+ var v *Label
+ if v = attr.archValuePtrs()[arch]; v == nil {
+ panic(fmt.Errorf("Unknown arch: %s", arch))
+ }
+ *v = value
+}
+
+func (attr *LabelAttribute) archValuePtrs() map[string]*Label {
+ return map[string]*Label{
+ ARCH_X86: &attr.ArchValues.X86,
+ ARCH_X86_64: &attr.ArchValues.X86_64,
+ ARCH_ARM: &attr.ArchValues.Arm,
+ ARCH_ARM64: &attr.ArchValues.Arm64,
+ CONDITIONS_DEFAULT: &attr.ArchValues.ConditionsDefault,
}
}
func (attr LabelAttribute) HasConfigurableValues() bool {
- return attr.Arm.Label != "" || attr.Arm64.Label != "" || attr.X86.Label != "" || attr.X86_64.Label != ""
+ for arch := range PlatformArchMap {
+ if attr.GetValueForArch(arch).Label != "" {
+ return true
+ }
+ }
+
+ for os := range PlatformOsMap {
+ if attr.GetOsValueForTarget(os).Label != "" {
+ return true
+ }
+ // TODO(b/187530594): Should we also check arch=CONDITIONS_DEFAULT (not in AllArches)
+ for _, arch := range AllArches {
+ if attr.GetOsArchValueForTarget(os, arch).Label != "" {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func (attr *LabelAttribute) getValueForTarget(os string) labelTargetValue {
+ var v *labelTargetValue
+ if v = attr.targetValuePtrs()[os]; v == nil {
+ panic(fmt.Errorf("Unknown os: %s", os))
+ }
+ return *v
+}
+
+func (attr *LabelAttribute) GetOsValueForTarget(os string) Label {
+ var v *labelTargetValue
+ if v = attr.targetValuePtrs()[os]; v == nil {
+ panic(fmt.Errorf("Unknown os: %s", os))
+ }
+ return v.OsValue
+}
+
+func (attr *LabelAttribute) GetOsArchValueForTarget(os string, arch string) Label {
+ var v *labelTargetValue
+ if v = attr.targetValuePtrs()[os]; v == nil {
+ panic(fmt.Errorf("Unknown os: %s", os))
+ }
+ switch arch {
+ case ARCH_X86:
+ return v.ArchValues.X86
+ case ARCH_X86_64:
+ return v.ArchValues.X86_64
+ case ARCH_ARM:
+ return v.ArchValues.Arm
+ case ARCH_ARM64:
+ return v.ArchValues.Arm64
+ case CONDITIONS_DEFAULT:
+ return v.ArchValues.ConditionsDefault
+ default:
+ panic(fmt.Errorf("Unknown arch: %s\n", arch))
+ }
+}
+
+func (attr *LabelAttribute) setValueForTarget(os string, value labelTargetValue) {
+ var v *labelTargetValue
+ if v = attr.targetValuePtrs()[os]; v == nil {
+ panic(fmt.Errorf("Unknown os: %s", os))
+ }
+ *v = value
+}
+
+func (attr *LabelAttribute) SetOsValueForTarget(os string, value Label) {
+ var v *labelTargetValue
+ if v = attr.targetValuePtrs()[os]; v == nil {
+ panic(fmt.Errorf("Unknown os: %s", os))
+ }
+ v.OsValue = value
+}
+
+func (attr *LabelAttribute) SetOsArchValueForTarget(os string, arch string, value Label) {
+ var v *labelTargetValue
+ if v = attr.targetValuePtrs()[os]; v == nil {
+ panic(fmt.Errorf("Unknown os: %s", os))
+ }
+ switch arch {
+ case ARCH_X86:
+ v.ArchValues.X86 = value
+ case ARCH_X86_64:
+ v.ArchValues.X86_64 = value
+ case ARCH_ARM:
+ v.ArchValues.Arm = value
+ case ARCH_ARM64:
+ v.ArchValues.Arm64 = value
+ case CONDITIONS_DEFAULT:
+ v.ArchValues.ConditionsDefault = value
+ default:
+ panic(fmt.Errorf("Unknown arch: %s\n", arch))
+ }
+}
+
+func (attr *LabelAttribute) targetValuePtrs() map[string]*labelTargetValue {
+ return map[string]*labelTargetValue{
+ OS_ANDROID: &attr.TargetValues.Android,
+ OS_DARWIN: &attr.TargetValues.Darwin,
+ OS_FUCHSIA: &attr.TargetValues.Fuchsia,
+ OS_LINUX: &attr.TargetValues.Linux,
+ OS_LINUX_BIONIC: &attr.TargetValues.LinuxBionic,
+ OS_WINDOWS: &attr.TargetValues.Windows,
+ CONDITIONS_DEFAULT: &attr.TargetValues.ConditionsDefault,
+ }
}
// Arch-specific label_list typed Bazel attribute values. This should correspond
@@ -384,7 +508,6 @@
X86_64 LabelList
Arm LabelList
Arm64 LabelList
- Common LabelList
ConditionsDefault LabelList
}
@@ -630,7 +753,6 @@
X86_64 []string
Arm []string
Arm64 []string
- Common []string
ConditionsDefault []string
}
@@ -871,6 +993,6 @@
// TryVariableSubstitution, replace string substitution formatting within s with Starlark
// string.format compatible tag for productVariable.
func TryVariableSubstitution(s string, productVariable string) (string, bool) {
- sub := productVariableSubstitutionPattern.ReplaceAllString(s, "{"+productVariable+"}")
+ sub := productVariableSubstitutionPattern.ReplaceAllString(s, "$("+productVariable+")")
return sub, s != sub
}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 388c8cf..6bdfc0e 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -445,7 +445,7 @@
return prettyPrint(propertyValue.Elem(), indent)
case reflect.Slice:
if propertyValue.Len() == 0 {
- return "", nil
+ return "[]", nil
}
if propertyValue.Len() == 1 {
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 350bac1..b87d713 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -400,6 +400,141 @@
})
}
+func TestCcLibrarySharedStaticPropsInArch(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library shared/static props in arch",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/arm.cpp": "",
+ "foo/bar/x86.cpp": "",
+ "foo/bar/sharedonly.cpp": "",
+ "foo/bar/staticonly.cpp": "",
+ "foo/bar/Android.bp": `
+cc_library {
+ name: "a",
+ arch: {
+ arm: {
+ shared: {
+ srcs: ["arm_shared.cpp"],
+ cflags: ["-DARM_SHARED"],
+ static_libs: ["arm_static_dep_for_shared"],
+ whole_static_libs: ["arm_whole_static_dep_for_shared"],
+ shared_libs: ["arm_shared_dep_for_shared"],
+ },
+ },
+ x86: {
+ static: {
+ srcs: ["x86_static.cpp"],
+ cflags: ["-DX86_STATIC"],
+ static_libs: ["x86_dep_for_static"],
+ },
+ },
+ },
+ target: {
+ android: {
+ shared: {
+ srcs: ["android_shared.cpp"],
+ cflags: ["-DANDROID_SHARED"],
+ static_libs: ["android_dep_for_shared"],
+ },
+ },
+ android_arm: {
+ shared: {
+ cflags: ["-DANDROID_ARM_SHARED"],
+ },
+ },
+ },
+ srcs: ["both.cpp"],
+ cflags: ["bothflag"],
+ static_libs: ["static_dep_for_both"],
+ static: {
+ srcs: ["staticonly.cpp"],
+ cflags: ["staticflag"],
+ static_libs: ["static_dep_for_static"],
+ },
+ shared: {
+ srcs: ["sharedonly.cpp"],
+ cflags: ["sharedflag"],
+ static_libs: ["static_dep_for_shared"],
+ },
+ bazel_module: { bp2build_available: true },
+}
+
+cc_library_static { name: "static_dep_for_shared" }
+cc_library_static { name: "static_dep_for_static" }
+cc_library_static { name: "static_dep_for_both" }
+
+cc_library_static { name: "arm_static_dep_for_shared" }
+cc_library_static { name: "arm_whole_static_dep_for_shared" }
+cc_library_static { name: "arm_shared_dep_for_shared" }
+
+cc_library_static { name: "x86_dep_for_static" }
+
+cc_library_static { name: "android_dep_for_shared" }
+`,
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
+ name = "a",
+ copts = [
+ "bothflag",
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ dynamic_deps_for_shared = select({
+ "//build/bazel/platforms/arch:arm": [":arm_shared_dep_for_shared"],
+ "//conditions:default": [],
+ }),
+ implementation_deps = [":static_dep_for_both"],
+ 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": [],
+ }),
+ shared_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": [],
+ }),
+ srcs = ["both.cpp"],
+ static_copts = ["staticflag"] + select({
+ "//build/bazel/platforms/arch:x86": ["-DX86_STATIC"],
+ "//conditions:default": [],
+ }),
+ static_deps_for_shared = [":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": [],
+ }),
+ static_deps_for_static = [":static_dep_for_static"] + select({
+ "//build/bazel/platforms/arch:x86": [":x86_dep_for_static"],
+ "//conditions:default": [],
+ }),
+ static_srcs = ["staticonly.cpp"] + select({
+ "//build/bazel/platforms/arch:x86": ["x86_static.cpp"],
+ "//conditions:default": [],
+ }),
+ whole_archive_deps_for_shared = select({
+ "//build/bazel/platforms/arch:arm": [":arm_whole_static_dep_for_shared"],
+ "//conditions:default": [],
+ }),
+)`},
+ })
+}
+
func TestCcLibraryNonConfiguredVersionScript(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
description: "cc_library non-configured version script",
@@ -673,3 +808,46 @@
)`},
})
}
+
+func TestCcLibraryLabelAttributeGetTargetProperties(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library GetTargetProperties on a LabelAttribute",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `
+ cc_library {
+ name: "a",
+ srcs: ["a.cpp"],
+ target: {
+ android_arm: {
+ version_script: "android_arm.map",
+ },
+ linux_bionic_arm64: {
+ version_script: "linux_bionic_arm64.map",
+ },
+ },
+
+ bazel_module: { bp2build_available: true },
+ }
+ `,
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
+ name = "a",
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ srcs = ["a.cpp"],
+ version_script = select({
+ "//build/bazel/platforms/os_arch:android_arm": "android_arm.map",
+ "//build/bazel/platforms/os_arch:linux_bionic_arm64": "linux_bionic_arm64.map",
+ "//conditions:default": None,
+ }),
+)`},
+ })
+}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 833ceba..da38adb 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -850,6 +850,84 @@
})
}
+func TestCcLibraryStaticOneArchEmpty(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static one arch empty",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+ filesystem: map[string]string{
+ "common.cc": "",
+ "foo-no-arm.cc": "",
+ "foo-excluded.cc": "",
+ },
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ srcs: ["common.cc", "foo-*.cc"],
+ exclude_srcs: ["foo-excluded.cc"],
+ arch: {
+ arm: { exclude_srcs: ["foo-no-arm.cc"] },
+ },
+}`,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ linkstatic = True,
+ srcs = ["common.cc"] + select({
+ "//build/bazel/platforms/arch:arm": [],
+ "//conditions:default": ["foo-no-arm.cc"],
+ }),
+)`},
+ })
+}
+
+func TestCcLibraryStaticOneArchEmptyOtherSet(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static one arch empty other set",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+ filesystem: map[string]string{
+ "common.cc": "",
+ "foo-no-arm.cc": "",
+ "x86-only.cc": "",
+ "foo-excluded.cc": "",
+ },
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ srcs: ["common.cc", "foo-*.cc"],
+ exclude_srcs: ["foo-excluded.cc"],
+ arch: {
+ arm: { exclude_srcs: ["foo-no-arm.cc"] },
+ x86: { srcs: ["x86-only.cc"] },
+ },
+}`,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ linkstatic = True,
+ srcs = ["common.cc"] + select({
+ "//build/bazel/platforms/arch:arm": [],
+ "//build/bazel/platforms/arch:x86": [
+ "foo-no-arm.cc",
+ "x86-only.cc",
+ ],
+ "//conditions:default": ["foo-no-arm.cc"],
+ }),
+)`},
+ })
+}
+
func TestCcLibraryStaticMultipleDepSameName(t *testing.T) {
runCcLibraryStaticTestCase(t, bp2buildTestCase{
description: "cc_library_static multiple dep same name panic",
@@ -1204,14 +1282,14 @@
"//build/bazel/platforms/os:android": ["android_src.c"],
"//conditions:default": [],
}) + select({
- "//build/bazel/platforms:android_arm": ["android_arm_src.c"],
- "//build/bazel/platforms:android_arm64": ["android_arm64_src.c"],
- "//build/bazel/platforms:android_x86": ["android_x86_src.c"],
- "//build/bazel/platforms:android_x86_64": ["android_x86_64_src.c"],
+ "//build/bazel/platforms/os_arch:android_arm": ["android_arm_src.c"],
+ "//build/bazel/platforms/os_arch:android_arm64": ["android_arm64_src.c"],
+ "//build/bazel/platforms/os_arch:android_x86": ["android_x86_src.c"],
+ "//build/bazel/platforms/os_arch:android_x86_64": ["android_x86_64_src.c"],
"//conditions:default": [],
}) + select({
- "//build/bazel/platforms:linux_bionic_arm64": ["linux_bionic_arm64_src.c"],
- "//build/bazel/platforms:linux_bionic_x86_64": ["linux_bionic_x86_64_src.c"],
+ "//build/bazel/platforms/os_arch:linux_bionic_arm64": ["linux_bionic_arm64_src.c"],
+ "//build/bazel/platforms/os_arch:linux_bionic_x86_64": ["linux_bionic_x86_64_src.c"],
"//conditions:default": [],
}),
)`},
@@ -1334,3 +1412,37 @@
)`},
})
}
+
+func TestCcLibraryStaticProductVariableStringReplacement(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static product variable selects",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ srcs: ["common.c"],
+ product_variables: {
+ platform_sdk_version: {
+ asflags: ["-DPLATFORM_SDK_VERSION=%d"],
+ },
+ },
+} `,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ asflags = select({
+ "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
+ "//conditions:default": [],
+ }),
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ linkstatic = True,
+ srcs_c = ["common.c"],
+)`},
+ })
+}
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index f7e94c2..57f75ea 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -210,7 +210,7 @@
expectedBazelTargets: []string{`cc_object(
name = "foo",
asflags = select({
- "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION={Platform_sdk_version}"],
+ "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
"//conditions:default": [],
}),
copts = ["-fno-addrsig"],
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index b5070b9..7e1a298 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -60,19 +60,67 @@
}
func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) {
- var value reflect.Value
- var archSelects selects
-
- if label.HasConfigurableValues() {
- archSelects = map[string]reflect.Value{}
- for arch, selectKey := range bazel.PlatformArchMap {
- archSelects[selectKey] = reflect.ValueOf(label.GetValueForArch(arch))
- }
- } else {
- value = reflect.ValueOf(label.Value)
+ value := reflect.ValueOf(label.Value)
+ if !label.HasConfigurableValues() {
+ return value, []selects{}
}
- return value, []selects{archSelects}
+ // Keep track of which arches and oses have been used in case we need to raise a warning
+ usedArches := make(map[string]bool)
+ usedOses := make(map[string]bool)
+
+ archSelects := map[string]reflect.Value{}
+ for arch, selectKey := range bazel.PlatformArchMap {
+ archSelects[selectKey] = reflect.ValueOf(label.GetValueForArch(arch))
+ if archSelects[selectKey].IsValid() && !isZero(archSelects[selectKey]) {
+ usedArches[arch] = true
+ }
+ }
+
+ osSelects := map[string]reflect.Value{}
+ for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) {
+ selectKey := bazel.PlatformOsMap[os]
+ osSelects[selectKey] = reflect.ValueOf(label.GetOsValueForTarget(os))
+ if osSelects[selectKey].IsValid() && !isZero(osSelects[selectKey]) {
+ usedOses[os] = true
+ }
+ }
+
+ osArchSelects := make([]selects, 0)
+ for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) {
+ archSelects := make(map[string]reflect.Value)
+ // TODO(b/187530594): Should we also check arch=CONDITIONS_DEFAULT? (not in AllArches)
+ for _, arch := range bazel.AllArches {
+ target := os + "_" + arch
+ selectKey := bazel.PlatformTargetMap[target]
+ archSelects[selectKey] = reflect.ValueOf(label.GetOsArchValueForTarget(os, arch))
+ if archSelects[selectKey].IsValid() && !isZero(archSelects[selectKey]) {
+ if _, ok := usedArches[arch]; ok {
+ fmt.Printf("WARNING: Same arch used twice in LabelAttribute select: arch '%s'\n", arch)
+ }
+ if _, ok := usedOses[os]; ok {
+ fmt.Printf("WARNING: Same os used twice in LabelAttribute select: os '%s'\n", os)
+ }
+ }
+ }
+ osArchSelects = append(osArchSelects, archSelects)
+ }
+
+ // Because we have to return a single Label, we can only use one select statement
+ combinedSelects := map[string]reflect.Value{}
+ for k, v := range archSelects {
+ combinedSelects[k] = v
+ }
+ for k, v := range osSelects {
+ combinedSelects[k] = v
+ }
+ for _, osArchSelect := range osArchSelects {
+ for k, v := range osArchSelect {
+ combinedSelects[k] = v
+ }
+ }
+
+ return value, []selects{combinedSelects}
}
func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) {
@@ -80,32 +128,55 @@
if !list.HasConfigurableValues() {
return value, []selects{}
}
+ var ret []selects
archSelects := map[string]reflect.Value{}
for arch, selectKey := range bazel.PlatformArchMap {
- archSelects[selectKey] = reflect.ValueOf(list.GetValueForArch(arch).Includes)
+ if use, value := labelListSelectValue(selectKey, list.GetValueForArch(arch)); use {
+ archSelects[selectKey] = value
+ }
+ }
+ if len(archSelects) > 0 {
+ ret = append(ret, archSelects)
}
osSelects := map[string]reflect.Value{}
- osArchSelects := make([]selects, 0)
+ osArchSelects := []selects{}
for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) {
selectKey := bazel.PlatformOsMap[os]
- osSelects[selectKey] = reflect.ValueOf(list.GetOsValueForTarget(os).Includes)
- archSelects := make(map[string]reflect.Value)
+ if use, value := labelListSelectValue(selectKey, list.GetOsValueForTarget(os)); use {
+ osSelects[selectKey] = value
+ }
+ selects := make(map[string]reflect.Value)
// TODO(b/187530594): Should we also check arch=CONDITIOSN_DEFAULT? (not in AllArches)
for _, arch := range bazel.AllArches {
target := os + "_" + arch
selectKey := bazel.PlatformTargetMap[target]
- archSelects[selectKey] = reflect.ValueOf(list.GetOsArchValueForTarget(os, arch).Includes)
+ if use, value := labelListSelectValue(selectKey, list.GetOsArchValueForTarget(os, arch)); use {
+ selects[selectKey] = value
+ }
}
- osArchSelects = append(osArchSelects, archSelects)
+ if len(selects) > 0 {
+ osArchSelects = append(osArchSelects, selects)
+ }
}
+ if len(osSelects) > 0 {
+ ret = append(ret, osSelects)
+ }
+ ret = append(ret, osArchSelects...)
- var selects []selects
- selects = append(selects, archSelects)
- selects = append(selects, osSelects)
- selects = append(selects, osArchSelects...)
- return value, selects
+ return value, ret
+}
+
+func labelListSelectValue(selectKey string, list bazel.LabelList) (bool, reflect.Value) {
+ if selectKey == bazel.ConditionsDefaultSelectKey || len(list.Includes) > 0 {
+ return true, reflect.ValueOf(list.Includes)
+ } else if len(list.Excludes) > 0 {
+ // if there is still an excludes -- we need to have an empty list for this select & use the
+ // value in conditions default Includes
+ return true, reflect.ValueOf([]string{})
+ }
+ return false, reflect.Zero(reflect.TypeOf([]string{}))
}
// prettyPrintAttribute converts an Attribute to its Bazel syntax. May contain
diff --git a/build_test.bash b/build_test.bash
index 296a79c..b039285 100755
--- a/build_test.bash
+++ b/build_test.bash
@@ -54,7 +54,7 @@
echo
echo "Running Bazel smoke test..."
-"${TOP}/tools/bazel" --batch --max_idle_secs=1 info
+STANDALONE_BAZEL=true "${TOP}/tools/bazel" --batch --max_idle_secs=1 info
echo
echo "Running Soong test..."
diff --git a/cc/bp2build.go b/cc/bp2build.go
index e64573c..fed9936 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -19,6 +19,8 @@
"android/soong/android"
"android/soong/bazel"
+
+ "github.com/google/blueprint/proptools"
)
// bp2build functions and helpers for converting cc_* modules to Bazel.
@@ -104,25 +106,63 @@
// Deps in the static: { .. } and shared: { .. } props of a cc_library.
if lib, ok := module.compiler.(*libraryDecorator); ok {
- allDeps = append(allDeps, lib.SharedProperties.Shared.Static_libs...)
- allDeps = append(allDeps, lib.SharedProperties.Shared.Whole_static_libs...)
- allDeps = append(allDeps, lib.SharedProperties.Shared.Shared_libs...)
+ appendDeps := func(deps []string, p StaticOrSharedProperties) []string {
+ deps = append(deps, p.Static_libs...)
+ deps = append(deps, p.Whole_static_libs...)
+ deps = append(deps, p.Shared_libs...)
+ return deps
+ }
- allDeps = append(allDeps, lib.StaticProperties.Static.Static_libs...)
- allDeps = append(allDeps, lib.StaticProperties.Static.Whole_static_libs...)
- allDeps = append(allDeps, lib.StaticProperties.Static.Shared_libs...)
+ allDeps = appendDeps(allDeps, lib.SharedProperties.Shared)
+ allDeps = appendDeps(allDeps, lib.StaticProperties.Static)
// TODO(b/186024507, b/186489250): Temporarily exclude adding
// system_shared_libs deps until libc and libm builds.
// allDeps = append(allDeps, lib.SharedProperties.Shared.System_shared_libs...)
// allDeps = append(allDeps, lib.StaticProperties.Static.System_shared_libs...)
+
+ // Deps in the target/arch nested static: { .. } and shared: { .. } props of a cc_library.
+ // target: { <target>: shared: { ... } }
+ for _, targetProps := range module.GetTargetProperties(ctx, &SharedProperties{}) {
+ if p, ok := targetProps.Properties.(*SharedProperties); ok {
+ allDeps = appendDeps(allDeps, p.Shared)
+ }
+ for _, archProperties := range targetProps.ArchProperties {
+ if p, ok := archProperties.(*SharedProperties); ok {
+ allDeps = appendDeps(allDeps, p.Shared)
+ }
+ }
+ }
+ // target: { <target>: static: { ... } }
+ for _, targetProps := range module.GetTargetProperties(ctx, &StaticProperties{}) {
+ if p, ok := targetProps.Properties.(*StaticProperties); ok {
+ allDeps = appendDeps(allDeps, p.Static)
+ }
+ for _, archProperties := range targetProps.ArchProperties {
+ if p, ok := archProperties.(*StaticProperties); ok {
+ allDeps = appendDeps(allDeps, p.Static)
+ }
+ }
+ }
+ // arch: { <arch>: shared: { ... } }
+ for _, properties := range module.GetArchProperties(ctx, &SharedProperties{}) {
+ if p, ok := properties.(*SharedProperties); ok {
+ allDeps = appendDeps(allDeps, p.Shared)
+ }
+ }
+ // arch: { <arch>: static: { ... } }
+ for _, properties := range module.GetArchProperties(ctx, &StaticProperties{}) {
+ if p, ok := properties.(*StaticProperties); ok {
+ allDeps = appendDeps(allDeps, p.Static)
+ }
+ }
}
ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...)
}
// staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
-// properities which apply to either the shared or static version of a cc_library module.
+// properties which apply to either the shared or static version of a cc_library module.
type staticOrSharedAttributes struct {
copts bazel.StringListAttribute
srcs bazel.LabelListAttribute
@@ -138,7 +178,7 @@
return staticOrSharedAttributes{}
}
- return bp2buildParseStaticOrSharedProps(ctx, lib.SharedProperties.Shared)
+ return bp2buildParseStaticOrSharedProps(ctx, module, lib, false)
}
// bp2buildParseStaticProps returns the attributes for the static variant of a cc_library.
@@ -148,30 +188,143 @@
return staticOrSharedAttributes{}
}
- return bp2buildParseStaticOrSharedProps(ctx, lib.StaticProperties.Static)
+ return bp2buildParseStaticOrSharedProps(ctx, module, lib, true)
}
-func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, props StaticOrSharedProperties) staticOrSharedAttributes {
- copts := bazel.StringListAttribute{Value: props.Cflags}
+func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
+ var props StaticOrSharedProperties
+ if isStatic {
+ props = lib.StaticProperties.Static
+ } else {
+ props = lib.SharedProperties.Shared
+ }
- srcs := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleSrc(ctx, props.Srcs)}
+ attrs := staticOrSharedAttributes{
+ copts: bazel.StringListAttribute{Value: props.Cflags},
+ srcs: bazel.LabelListAttribute{Value: android.BazelLabelForModuleSrc(ctx, props.Srcs)},
+ staticDeps: bazel.LabelListAttribute{Value: android.BazelLabelForModuleDeps(ctx, props.Static_libs)},
+ dynamicDeps: bazel.LabelListAttribute{Value: android.BazelLabelForModuleDeps(ctx, props.Shared_libs)},
+ wholeArchiveDeps: bazel.LabelListAttribute{Value: android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)},
+ }
- staticDeps := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleDeps(ctx, props.Static_libs)}
+ setArchAttrs := func(arch string, props StaticOrSharedProperties) {
+ attrs.copts.SetValueForArch(arch, props.Cflags)
+ attrs.srcs.SetValueForArch(arch, android.BazelLabelForModuleSrc(ctx, props.Srcs))
+ attrs.staticDeps.SetValueForArch(arch, android.BazelLabelForModuleDeps(ctx, props.Static_libs))
+ attrs.dynamicDeps.SetValueForArch(arch, android.BazelLabelForModuleDeps(ctx, props.Shared_libs))
+ attrs.wholeArchiveDeps.SetValueForArch(arch, android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs))
+ }
- dynamicDeps := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleDeps(ctx, props.Shared_libs)}
+ setTargetAttrs := func(target string, props StaticOrSharedProperties) {
+ attrs.copts.SetOsValueForTarget(target, props.Cflags)
+ attrs.srcs.SetOsValueForTarget(target, android.BazelLabelForModuleSrc(ctx, props.Srcs))
+ attrs.staticDeps.SetOsValueForTarget(target, android.BazelLabelForModuleDeps(ctx, props.Static_libs))
+ attrs.dynamicDeps.SetOsValueForTarget(target, android.BazelLabelForModuleDeps(ctx, props.Shared_libs))
+ attrs.wholeArchiveDeps.SetOsValueForTarget(target, android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs))
+ }
- wholeArchiveDeps := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)}
+ setTargetArchAttrs := func(target, arch string, props StaticOrSharedProperties) {
+ attrs.copts.SetOsArchValueForTarget(target, arch, props.Cflags)
+ attrs.srcs.SetOsArchValueForTarget(target, arch, android.BazelLabelForModuleSrc(ctx, props.Srcs))
+ attrs.staticDeps.SetOsArchValueForTarget(target, arch, android.BazelLabelForModuleDeps(ctx, props.Static_libs))
+ attrs.dynamicDeps.SetOsArchValueForTarget(target, arch, android.BazelLabelForModuleDeps(ctx, props.Shared_libs))
+ attrs.wholeArchiveDeps.SetOsArchValueForTarget(target, arch, android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs))
+ }
- return staticOrSharedAttributes{
- copts: copts,
- srcs: srcs,
- staticDeps: staticDeps,
- dynamicDeps: dynamicDeps,
- wholeArchiveDeps: wholeArchiveDeps,
+ if isStatic {
+ for arch, properties := range module.GetArchProperties(ctx, &StaticProperties{}) {
+ if staticOrSharedProps, ok := properties.(*StaticProperties); ok {
+ setArchAttrs(arch.Name, staticOrSharedProps.Static)
+ }
+ }
+ for target, p := range module.GetTargetProperties(ctx, &StaticProperties{}) {
+ if staticOrSharedProps, ok := p.Properties.(*StaticProperties); ok {
+ setTargetAttrs(target.Name, staticOrSharedProps.Static)
+ }
+ for arch, archProperties := range p.ArchProperties {
+ if staticOrSharedProps, ok := archProperties.(*StaticProperties); ok {
+ setTargetArchAttrs(target.Name, arch.Name, staticOrSharedProps.Static)
+ }
+ }
+ }
+ } else {
+ for arch, p := range module.GetArchProperties(ctx, &SharedProperties{}) {
+ if staticOrSharedProps, ok := p.(*SharedProperties); ok {
+ setArchAttrs(arch.Name, staticOrSharedProps.Shared)
+ }
+ }
+ for target, p := range module.GetTargetProperties(ctx, &SharedProperties{}) {
+ if staticOrSharedProps, ok := p.Properties.(*SharedProperties); ok {
+ setTargetAttrs(target.Name, staticOrSharedProps.Shared)
+ }
+ for arch, archProperties := range p.ArchProperties {
+ if staticOrSharedProps, ok := archProperties.(*SharedProperties); ok {
+ setTargetArchAttrs(target.Name, arch.Name, staticOrSharedProps.Shared)
+ }
+ }
+ }
+ }
+
+ return attrs
+}
+
+// Convenience struct to hold all attributes parsed from prebuilt properties.
+type prebuiltAttributes struct {
+ Src bazel.LabelAttribute
+}
+
+func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
+ prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
+ prebuiltLinker := prebuiltLibraryLinker.prebuiltLinker
+
+ var srcLabelAttribute bazel.LabelAttribute
+
+ if len(prebuiltLinker.properties.Srcs) > 1 {
+ ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file\n")
+ }
+
+ if len(prebuiltLinker.properties.Srcs) == 1 {
+ srcLabelAttribute.Value = android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0])
+ for arch, props := range module.GetArchProperties(ctx, &prebuiltLinkerProperties{}) {
+ if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
+ if len(prebuiltLinkerProperties.Srcs) > 1 {
+ ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for arch %s\n", arch.Name)
+ }
+ if len(prebuiltLinkerProperties.Srcs) == 1 {
+ srcLabelAttribute.SetValueForArch(arch.Name, android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0]))
+ }
+ }
+ }
+ }
+
+ for os, targetProperties := range module.GetTargetProperties(ctx, &prebuiltLinkerProperties{}) {
+ if prebuiltLinkerProperties, ok := targetProperties.Properties.(*prebuiltLinkerProperties); ok {
+ if len(prebuiltLinkerProperties.Srcs) > 1 {
+ ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for os %s\n", os.Name)
+
+ }
+
+ if len(prebuiltLinkerProperties.Srcs) == 1 {
+ srcLabelAttribute.SetOsValueForTarget(os.Name, android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0]))
+ }
+ }
+ for arch, archProperties := range targetProperties.ArchProperties {
+ if prebuiltLinkerProperties, ok := archProperties.(*prebuiltLinkerProperties); ok {
+ if len(prebuiltLinkerProperties.Srcs) > 1 {
+ ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for os_arch %s_%s\n", os.Name, arch.Name)
+
+ }
+
+ if len(prebuiltLinkerProperties.Srcs) == 1 {
+ srcLabelAttribute.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0]))
+ }
+ }
+
+ }
+ }
+
+ return prebuiltAttributes{
+ Src: srcLabelAttribute,
}
}
@@ -330,7 +483,9 @@
if baseCompilerProps, ok := osProps.Properties.(*BaseCompilerProperties); ok {
srcsList := parseSrcs(baseCompilerProps)
// TODO(b/186153868): add support for os-specific srcs and exclude_srcs
- srcs.SetOsValueForTarget(os.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList))
+ if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
+ srcs.SetOsValueForTarget(os.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList))
+ }
copts.SetOsValueForTarget(os.Name, parseCopts(baseCompilerProps))
asFlags.SetOsValueForTarget(os.Name, parseCommandLineFlags(baseCompilerProps.Asflags))
conlyFlags.SetOsValueForTarget(os.Name, parseCommandLineFlags(baseCompilerProps.Conlyflags))
@@ -340,7 +495,9 @@
if baseCompilerProps, ok := archProps.(*BaseCompilerProperties); ok {
srcsList := parseSrcs(baseCompilerProps)
// TODO(b/186153868): add support for os-specific srcs and exclude_srcs
- srcs.SetOsArchValueForTarget(os.Name, arch.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList))
+ if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
+ srcs.SetOsArchValueForTarget(os.Name, arch.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList))
+ }
copts.SetOsArchValueForTarget(os.Name, arch.Name, parseCopts(baseCompilerProps))
asFlags.SetOsArchValueForTarget(os.Name, arch.Name, parseCommandLineFlags(baseCompilerProps.Asflags))
conlyFlags.SetOsArchValueForTarget(os.Name, arch.Name, parseCommandLineFlags(baseCompilerProps.Conlyflags))
@@ -349,18 +506,25 @@
}
}
+ productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
+ "Cflags": &copts,
+ "Asflags": &asFlags,
+ "CppFlags": &cppFlags,
+ }
productVariableProps := android.ProductVariableProperties(ctx)
- if props, exists := productVariableProps["Cflags"]; exists {
- for _, prop := range props {
- flags, ok := prop.Property.([]string)
- if !ok {
- ctx.ModuleErrorf("Could not convert product variable cflag property")
+ for propName, attr := range productVarPropNameToAttribute {
+ if props, exists := productVariableProps[propName]; exists {
+ for _, prop := range props {
+ flags, ok := prop.Property.([]string)
+ if !ok {
+ ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
+ }
+ newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
+ attr.ProductValues = append(attr.ProductValues, bazel.ProductVariableValues{
+ ProductVariable: prop.ProductConfigVariable,
+ Values: newFlags,
+ })
}
- newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
- copts.ProductValues = append(copts.ProductValues, bazel.ProductVariableValues{
- ProductVariable: prop.ProductConfigVariable,
- Values: newFlags,
- })
}
}
@@ -477,6 +641,10 @@
linkopts.SetOsValueForTarget(os.Name, getBp2BuildLinkerFlags(baseLinkerProps))
+ if baseLinkerProps.Version_script != nil {
+ versionScript.SetOsValueForTarget(os.Name, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
+ }
+
sharedLibs := baseLinkerProps.Shared_libs
dynamicDeps.SetOsValueForTarget(os.Name, android.BazelLabelForModuleDeps(ctx, sharedLibs))
}
@@ -491,6 +659,10 @@
linkopts.SetOsArchValueForTarget(os.Name, arch.Name, getBp2BuildLinkerFlags(baseLinkerProps))
+ if baseLinkerProps.Version_script != nil {
+ versionScript.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
+ }
+
sharedLibs := baseLinkerProps.Shared_libs
dynamicDeps.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleDeps(ctx, sharedLibs))
}
@@ -530,11 +702,20 @@
return relativePaths
}
-// bp2BuildParseExportedIncludes creates a string list attribute contains the
-// exported included directories of a module.
func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
libraryDecorator := module.linker.(*libraryDecorator)
+ return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
+}
+func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
+ prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
+ libraryDecorator := prebuiltLibraryLinker.libraryDecorator
+ return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
+}
+
+// bp2BuildParseExportedIncludes creates a string list attribute contains the
+// exported included directories of a module.
+func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) bazel.StringListAttribute {
// Export_system_include_dirs and export_include_dirs are already module dir
// relative, so they don't need to be relativized like include_dirs, which
// are root-relative.
diff --git a/cc/builder.go b/cc/builder.go
index 51c8a0b..fae9522 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -534,7 +534,7 @@
Implicits: cFlagsDeps,
OrderOnly: pathDeps,
Args: map[string]string{
- "windresCmd": gccCmd(flags.toolchain, "windres"),
+ "windresCmd": mingwCmd(flags.toolchain, "windres"),
"flags": flags.toolchain.WindresFlags(),
},
})
@@ -1069,6 +1069,6 @@
})
}
-func gccCmd(toolchain config.Toolchain, cmd string) string {
+func mingwCmd(toolchain config.Toolchain, cmd string) string {
return filepath.Join(toolchain.GccRoot(), "bin", toolchain.GccTriple()+"-"+cmd)
}
diff --git a/cc/cc.go b/cc/cc.go
index 8a34dad..91c4417 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -726,15 +726,8 @@
runtimeDepTag = installDependencyTag{name: "runtime lib"}
testPerSrcDepTag = dependencyTag{name: "test_per_src"}
stubImplDepTag = dependencyTag{name: "stub_impl"}
- llndkStubDepTag = dependencyTag{name: "llndk stub"}
)
-type copyDirectlyInAnyApexDependencyTag dependencyTag
-
-func (copyDirectlyInAnyApexDependencyTag) CopyDirectlyInAnyApex() {}
-
-var _ android.CopyDirectlyInAnyApexTag = copyDirectlyInAnyApexDependencyTag{}
-
func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
ccLibDepTag, ok := depTag.(libraryDependencyTag)
return ok && ccLibDepTag.shared()
@@ -3244,8 +3237,8 @@
return false
}
}
- if depTag == stubImplDepTag || depTag == llndkStubDepTag {
- // We don't track beyond LLNDK or from an implementation library to its stubs.
+ if depTag == stubImplDepTag {
+ // We don't track from an implementation library to its stubs.
return false
}
if depTag == staticVariantTag {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 5acafbe..7fc044d 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -2799,12 +2799,8 @@
}
}
expected := []string{
- "android_vendor.29_arm64_armv8-a_shared_1",
- "android_vendor.29_arm64_armv8-a_shared_2",
"android_vendor.29_arm64_armv8-a_shared_current",
"android_vendor.29_arm64_armv8-a_shared",
- "android_vendor.29_arm_armv7-a-neon_shared_1",
- "android_vendor.29_arm_armv7-a-neon_shared_2",
"android_vendor.29_arm_armv7-a-neon_shared_current",
"android_vendor.29_arm_armv7-a-neon_shared",
}
@@ -2813,9 +2809,6 @@
params := result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared").Description("generate stub")
android.AssertSame(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
- params = result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared_1").Description("generate stub")
- android.AssertSame(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
-
checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
t.Helper()
m := result.ModuleForTests(module, variant).Module()
diff --git a/cc/gen.go b/cc/gen.go
index b152e02..3a1a0e2 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -204,7 +204,7 @@
headerFile := android.GenPathWithExt(ctx, "windmc", srcFile, "h")
rcFile := android.GenPathWithExt(ctx, "windmc", srcFile, "rc")
- windmcCmd := gccCmd(flags.toolchain, "windmc")
+ windmcCmd := mingwCmd(flags.toolchain, "windmc")
ctx.Build(pctx, android.BuildParams{
Rule: windmc,
diff --git a/cc/image.go b/cc/image.go
index 47a424b..c6b209f 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -579,7 +579,7 @@
// If using a snapshot, the recovery variant under AOSP directories is not needed,
// except for kernel headers, which needs all variants.
- if m.KernelHeadersDecorator() &&
+ if !m.KernelHeadersDecorator() &&
!m.IsSnapshotPrebuilt() &&
usingRecoverySnapshot &&
!isRecoveryProprietaryModule(mctx) {
diff --git a/cc/library.go b/cc/library.go
index 9fb7a24..5e70c51 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1813,6 +1813,11 @@
return nil
}
+ if library.hasLLNDKStubs() && ctx.Module().(*Module).UseVndk() {
+ // LLNDK libraries only need a single stubs variant.
+ return []string{android.FutureApiLevel.String()}
+ }
+
// Future API level is implicitly added if there isn't
vers := library.Properties.Stubs.Versions
if inList(android.FutureApiLevel.String(), vers) {
@@ -2154,8 +2159,7 @@
return nil
}
-// versionSelector normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions,
-// and propagates the value from implementation libraries to llndk libraries with the same name.
+// versionSelector normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions.
func versionSelectorMutator(mctx android.BottomUpMutatorContext) {
if library := moduleLibraryInterface(mctx.Module()); library != nil && CanBeVersionVariant(mctx.Module().(*Module)) {
if library.buildShared() {
@@ -2169,15 +2173,6 @@
// depend on the implementation library and haven't been mutated yet.
library.setAllStubsVersions(versions)
}
-
- if mctx.Module().(*Module).UseVndk() && library.hasLLNDKStubs() {
- // Propagate the version to the llndk stubs module.
- mctx.VisitDirectDepsWithTag(llndkStubDepTag, func(stubs android.Module) {
- if stubsLib := moduleLibraryInterface(stubs); stubsLib != nil {
- stubsLib.setAllStubsVersions(library.allStubsVersions())
- }
- })
- }
}
}
}
diff --git a/cc/object.go b/cc/object.go
index cd71161..39fc43d 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -157,8 +157,6 @@
// Set arch-specific configurable attributes
compilerAttrs := bp2BuildParseCompilerProps(ctx, m)
- var asFlags bazel.StringListAttribute
-
var deps bazel.LabelListAttribute
for _, props := range m.linker.linkerProps() {
if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok {
@@ -167,24 +165,6 @@
}
}
- productVariableProps := android.ProductVariableProperties(ctx)
- if props, exists := productVariableProps["Asflags"]; exists {
- // TODO(b/183595873): consider deduplicating handling of product variable properties
- for _, prop := range props {
- flags, ok := prop.Property.([]string)
- if !ok {
- ctx.ModuleErrorf("Could not convert product variable asflag property")
- return
- }
- newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
- asFlags.ProductValues = append(asFlags.ProductValues, bazel.ProductVariableValues{
- ProductVariable: prop.ProductConfigVariable,
- Values: newFlags,
- })
- }
- }
- // TODO(b/183595872) warn/error if we're not handling product variables
-
// Don't split cc_object srcs across languages. Doing so would add complexity,
// and this isn't typically done for cc_object.
srcs := compilerAttrs.srcs
@@ -195,7 +175,7 @@
Srcs: srcs,
Deps: deps,
Copts: compilerAttrs.copts,
- Asflags: asFlags,
+ Asflags: compilerAttrs.asFlags,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cmd/go2bp/Android.bp b/cmd/go2bp/Android.bp
new file mode 100644
index 0000000..53d70b6
--- /dev/null
+++ b/cmd/go2bp/Android.bp
@@ -0,0 +1,26 @@
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+blueprint_go_binary {
+ name: "go2bp",
+ deps: [
+ "blueprint-proptools",
+ "bpfix-lib",
+ ],
+ srcs: ["go2bp.go"],
+}
diff --git a/cmd/go2bp/go2bp.go b/cmd/go2bp/go2bp.go
new file mode 100644
index 0000000..67138f1
--- /dev/null
+++ b/cmd/go2bp/go2bp.go
@@ -0,0 +1,361 @@
+// 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 main
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/json"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "sort"
+ "strings"
+ "text/template"
+
+ "github.com/google/blueprint/proptools"
+
+ "android/soong/bpfix/bpfix"
+)
+
+type RewriteNames []RewriteName
+type RewriteName struct {
+ prefix string
+ repl string
+}
+
+func (r *RewriteNames) String() string {
+ return ""
+}
+
+func (r *RewriteNames) Set(v string) error {
+ split := strings.SplitN(v, "=", 2)
+ if len(split) != 2 {
+ return fmt.Errorf("Must be in the form of <prefix>=<replace>")
+ }
+ *r = append(*r, RewriteName{
+ prefix: split[0],
+ repl: split[1],
+ })
+ return nil
+}
+
+func (r *RewriteNames) GoToBp(name string) string {
+ ret := name
+ for _, r := range *r {
+ prefix := r.prefix
+ if name == prefix {
+ ret = r.repl
+ break
+ }
+ prefix += "/"
+ if strings.HasPrefix(name, prefix) {
+ ret = r.repl + "-" + strings.TrimPrefix(name, prefix)
+ }
+ }
+ return strings.ReplaceAll(ret, "/", "-")
+}
+
+var rewriteNames = RewriteNames{}
+
+type Exclude map[string]bool
+
+func (e Exclude) String() string {
+ return ""
+}
+
+func (e Exclude) Set(v string) error {
+ e[v] = true
+ return nil
+}
+
+var excludes = make(Exclude)
+var excludeDeps = make(Exclude)
+var excludeSrcs = make(Exclude)
+
+type GoModule struct {
+ Dir string
+}
+
+type GoPackage struct {
+ Dir string
+ ImportPath string
+ Name string
+ Imports []string
+ GoFiles []string
+ TestGoFiles []string
+ TestImports []string
+
+ Module *GoModule
+}
+
+func (g GoPackage) IsCommand() bool {
+ return g.Name == "main"
+}
+
+func (g GoPackage) BpModuleType() string {
+ if g.IsCommand() {
+ return "blueprint_go_binary"
+ }
+ return "bootstrap_go_package"
+}
+
+func (g GoPackage) BpName() string {
+ if g.IsCommand() {
+ return filepath.Base(g.ImportPath)
+ }
+ return rewriteNames.GoToBp(g.ImportPath)
+}
+
+func (g GoPackage) BpDeps(deps []string) []string {
+ var ret []string
+ for _, d := range deps {
+ // Ignore stdlib dependencies
+ if !strings.Contains(d, ".") {
+ continue
+ }
+ if _, ok := excludeDeps[d]; ok {
+ continue
+ }
+ name := rewriteNames.GoToBp(d)
+ ret = append(ret, name)
+ }
+ return ret
+}
+
+func (g GoPackage) BpSrcs(srcs []string) []string {
+ var ret []string
+ prefix, err := filepath.Rel(g.Module.Dir, g.Dir)
+ if err != nil {
+ panic(err)
+ }
+ for _, f := range srcs {
+ f = filepath.Join(prefix, f)
+ if _, ok := excludeSrcs[f]; ok {
+ continue
+ }
+ ret = append(ret, f)
+ }
+ return ret
+}
+
+// AllImports combines Imports and TestImports, as blueprint does not differentiate these.
+func (g GoPackage) AllImports() []string {
+ imports := append([]string(nil), g.Imports...)
+ imports = append(imports, g.TestImports...)
+
+ if len(imports) == 0 {
+ return nil
+ }
+
+ // Sort and de-duplicate
+ sort.Strings(imports)
+ j := 0
+ for i := 1; i < len(imports); i++ {
+ if imports[i] == imports[j] {
+ continue
+ }
+ j++
+ imports[j] = imports[i]
+ }
+ return imports[:j+1]
+}
+
+var bpTemplate = template.Must(template.New("bp").Parse(`
+{{.BpModuleType}} {
+ name: "{{.BpName}}",
+ {{- if not .IsCommand}}
+ pkgPath: "{{.ImportPath}}",
+ {{- end}}
+ {{- if .BpDeps .AllImports}}
+ deps: [
+ {{- range .BpDeps .AllImports}}
+ "{{.}}",
+ {{- end}}
+ ],
+ {{- end}}
+ {{- if .BpSrcs .GoFiles}}
+ srcs: [
+ {{- range .BpSrcs .GoFiles}}
+ "{{.}}",
+ {{- end}}
+ ],
+ {{- end}}
+ {{- if .BpSrcs .TestGoFiles}}
+ testSrcs: [
+ {{- range .BpSrcs .TestGoFiles}}
+ "{{.}}",
+ {{- end}}
+ ],
+ {{- end}}
+}
+`))
+
+func rerunForRegen(filename string) error {
+ buf, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return err
+ }
+
+ scanner := bufio.NewScanner(bytes.NewBuffer(buf))
+
+ // Skip the first line in the file
+ for i := 0; i < 2; i++ {
+ if !scanner.Scan() {
+ if scanner.Err() != nil {
+ return scanner.Err()
+ } else {
+ return fmt.Errorf("unexpected EOF")
+ }
+ }
+ }
+
+ // Extract the old args from the file
+ line := scanner.Text()
+ if strings.HasPrefix(line, "// go2bp ") {
+ line = strings.TrimPrefix(line, "// go2bp ")
+ } else {
+ return fmt.Errorf("unexpected second line: %q", line)
+ }
+ args := strings.Split(line, " ")
+ lastArg := args[len(args)-1]
+ args = args[:len(args)-1]
+
+ // Append all current command line args except -regen <file> to the ones from the file
+ for i := 1; i < len(os.Args); i++ {
+ if os.Args[i] == "-regen" || os.Args[i] == "--regen" {
+ i++
+ } else {
+ args = append(args, os.Args[i])
+ }
+ }
+ args = append(args, lastArg)
+
+ cmd := os.Args[0] + " " + strings.Join(args, " ")
+ // Re-exec pom2bp with the new arguments
+ output, err := exec.Command("/bin/sh", "-c", cmd).Output()
+ if exitErr, _ := err.(*exec.ExitError); exitErr != nil {
+ return fmt.Errorf("failed to run %s\n%s", cmd, string(exitErr.Stderr))
+ } else if err != nil {
+ return err
+ }
+
+ return ioutil.WriteFile(filename, output, 0666)
+}
+
+func main() {
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, `go2bp, a tool to create Android.bp files from go modules
+
+The tool will extract the necessary information from Go files to create an Android.bp that can
+compile them. This needs to be run from the same directory as the go.mod file.
+
+Usage: %s [--rewrite <pkg-prefix>=<replace>] [-exclude <package>] [-regen <file>]
+
+ -rewrite <pkg-prefix>=<replace>
+ rewrite can be used to specify mappings between go package paths and Android.bp modules. The -rewrite
+ option can be specified multiple times. When determining the Android.bp module for a given Go
+ package, mappings are searched in the order they were specified. The first <pkg-prefix> matching
+ either the package directly, or as the prefix '<pkg-prefix>/' will be replaced with <replace>.
+ After all replacements are finished, all '/' characters are replaced with '-'.
+ -exclude <package>
+ Don't put the specified go package in the Android.bp file.
+ -exclude-deps <package>
+ Don't put the specified go package in the dependency lists.
+ -exclude-srcs <module>
+ Don't put the specified source files in srcs or testSrcs lists.
+ -regen <file>
+ Read arguments from <file> and overwrite it.
+
+`, os.Args[0])
+ }
+
+ var regen string
+
+ flag.Var(&excludes, "exclude", "Exclude go package")
+ flag.Var(&excludeDeps, "exclude-dep", "Exclude go package from deps")
+ flag.Var(&excludeSrcs, "exclude-src", "Exclude go file from source lists")
+ flag.Var(&rewriteNames, "rewrite", "Regex(es) to rewrite artifact names")
+ flag.StringVar(®en, "regen", "", "Rewrite specified file")
+ flag.Parse()
+
+ if regen != "" {
+ err := rerunForRegen(regen)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ os.Exit(0)
+ }
+
+ if flag.NArg() != 0 {
+ fmt.Fprintf(os.Stderr, "Unused argument detected: %v\n", flag.Args())
+ os.Exit(1)
+ }
+
+ if _, err := os.Stat("go.mod"); err != nil {
+ fmt.Fprintln(os.Stderr, "go.mod file not found")
+ os.Exit(1)
+ }
+
+ cmd := exec.Command("go", "list", "-json", "./...")
+ output, err := cmd.Output()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Failed to dump the go packages: %v\n", err)
+ os.Exit(1)
+ }
+ decoder := json.NewDecoder(bytes.NewReader(output))
+
+ pkgs := []GoPackage{}
+ for decoder.More() {
+ pkg := GoPackage{}
+ err := decoder.Decode(&pkg)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Failed to parse json: %v\n", err)
+ os.Exit(1)
+ }
+ pkgs = append(pkgs, pkg)
+ }
+
+ buf := &bytes.Buffer{}
+
+ fmt.Fprintln(buf, "// Automatically generated with:")
+ fmt.Fprintln(buf, "// go2bp", strings.Join(proptools.ShellEscapeList(os.Args[1:]), " "))
+
+ for _, pkg := range pkgs {
+ if excludes[pkg.ImportPath] {
+ continue
+ }
+ if len(pkg.BpSrcs(pkg.GoFiles)) == 0 && len(pkg.BpSrcs(pkg.TestGoFiles)) == 0 {
+ continue
+ }
+ err := bpTemplate.Execute(buf, pkg)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "Error writing", pkg.Name, err)
+ os.Exit(1)
+ }
+ }
+
+ out, err := bpfix.Reformat(buf.String())
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "Error formatting output", err)
+ os.Exit(1)
+ }
+
+ os.Stdout.WriteString(out)
+}
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index e0f8caa..20f146a 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -433,7 +433,7 @@
config := build.NewConfig(ctx, args...)
config.Environment().Set("OUT_DIR", outDir)
if !*keepArtifacts {
- config.Environment().Set("EMPTY_NINJA_FILE", "true")
+ config.SetEmptyNinjaFile(true)
}
build.FindSources(ctx, config, mpctx.Finder)
config.Lunch(ctx, product, *buildVariant)
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 7abb67f..0336fb6 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -17,7 +17,6 @@
import (
"flag"
"fmt"
- "io/fs"
"io/ioutil"
"os"
"path/filepath"
@@ -364,54 +363,41 @@
// - won't be overwritten by corresponding bp2build generated files
//
// And return their paths so they can be left out of the Bazel workspace dir (i.e. ignored)
-func getPathsToIgnoredBuildFiles(topDir string, outDir string, generatedRoot string) ([]string, error) {
+func getPathsToIgnoredBuildFiles(topDir string, generatedRoot string, srcDirBazelFiles []string) []string {
paths := make([]string, 0)
- err := filepath.WalkDir(topDir, func(fFullPath string, fDirEntry fs.DirEntry, err error) error {
+ for _, srcDirBazelFileRelativePath := range srcDirBazelFiles {
+ srcDirBazelFileFullPath := shared.JoinPath(topDir, srcDirBazelFileRelativePath)
+ fileInfo, err := os.Stat(srcDirBazelFileFullPath)
if err != nil {
- // Warn about error, but continue trying to walk the directory tree
- fmt.Fprintf(os.Stderr, "WARNING: Error accessing path '%s', err: %s\n", fFullPath, err)
- return nil
+ // Warn about error, but continue trying to check files
+ fmt.Fprintf(os.Stderr, "WARNING: Error accessing path '%s', err: %s\n", srcDirBazelFileFullPath, err)
+ continue
}
- if fDirEntry.IsDir() {
+ if fileInfo.IsDir() {
// Don't ignore entire directories
- return nil
+ continue
}
- if !(fDirEntry.Name() == "BUILD" || fDirEntry.Name() == "BUILD.bazel") {
+ if !(fileInfo.Name() == "BUILD" || fileInfo.Name() == "BUILD.bazel") {
// Don't ignore this file - it is not a build file
- return nil
+ continue
}
- f := strings.TrimPrefix(fFullPath, topDir+"/")
- if strings.HasPrefix(f, ".repo/") {
- // Don't check for files to ignore in the .repo dir (recursively)
- return fs.SkipDir
- }
- if strings.HasPrefix(f, outDir+"/") {
- // Don't check for files to ignore in the out dir (recursively)
- return fs.SkipDir
- }
- if strings.HasPrefix(f, generatedRoot) {
- // Don't check for files to ignore in the bp2build dir (recursively)
- // NOTE: This is usually under outDir
- return fs.SkipDir
- }
- fDir := filepath.Dir(f)
- if android.ShouldKeepExistingBuildFileForDir(fDir) {
+ srcDirBazelFileDir := filepath.Dir(srcDirBazelFileRelativePath)
+ if android.ShouldKeepExistingBuildFileForDir(srcDirBazelFileDir) {
// Don't ignore this existing build file
- return nil
+ continue
}
- f_bp2build := shared.JoinPath(topDir, generatedRoot, f)
- if _, err := os.Stat(f_bp2build); err == nil {
+ correspondingBp2BuildFile := shared.JoinPath(topDir, generatedRoot, srcDirBazelFileRelativePath)
+ if _, err := os.Stat(correspondingBp2BuildFile); err == nil {
// If bp2build generated an alternate BUILD file, don't exclude this workspace path
// BUILD file clash resolution happens later in the symlink forest creation
- return nil
+ continue
}
- fmt.Fprintf(os.Stderr, "Ignoring existing BUILD file: %s\n", f)
- paths = append(paths, f)
- return nil
- })
+ fmt.Fprintf(os.Stderr, "Ignoring existing BUILD file: %s\n", srcDirBazelFileRelativePath)
+ paths = append(paths, srcDirBazelFileRelativePath)
+ }
- return paths, err
+ return paths
}
// Returns temporary symlink forest excludes necessary for bazel build //external/... (and bazel build //frameworks/...) to work
@@ -431,6 +417,22 @@
return excludes
}
+// Read the bazel.list file that the Soong Finder already dumped earlier (hopefully)
+// It contains the locations of BUILD files, BUILD.bazel files, etc. in the source dir
+func getExistingBazelRelatedFiles(topDir string) ([]string, error) {
+ bazelFinderFile := filepath.Join(filepath.Dir(bootstrap.CmdlineArgs.ModuleListFile), "bazel.list")
+ if !filepath.IsAbs(bazelFinderFile) {
+ // Assume this was a relative path under topDir
+ bazelFinderFile = filepath.Join(topDir, bazelFinderFile)
+ }
+ data, err := ioutil.ReadFile(bazelFinderFile)
+ if err != nil {
+ return nil, err
+ }
+ files := strings.Split(strings.TrimSpace(string(data)), "\n")
+ return files, nil
+}
+
// Run Soong in the bp2build mode. This creates a standalone context that registers
// an alternate pipeline of mutators and singletons specifically for generating
// Bazel BUILD files instead of Ninja files.
@@ -489,14 +491,13 @@
excludes = append(excludes, bootstrap.CmdlineArgs.NinjaBuildDir)
}
- // FIXME: Don't hardcode this here
- topLevelOutDir := "out"
-
- pathsToIgnoredBuildFiles, err := getPathsToIgnoredBuildFiles(topDir, topLevelOutDir, generatedRoot)
+ existingBazelRelatedFiles, err := getExistingBazelRelatedFiles(topDir)
if err != nil {
- fmt.Fprintf(os.Stderr, "Error walking SrcDir: '%s': %s\n", configuration.SrcDir(), err)
+ fmt.Fprintf(os.Stderr, "Error determining existing Bazel-related files: %s\n", err)
os.Exit(1)
}
+
+ pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(topDir, generatedRoot, existingBazelRelatedFiles)
excludes = append(excludes, pathsToIgnoredBuildFiles...)
excludes = append(excludes, getTemporaryExcludes()...)
diff --git a/java/androidmk.go b/java/androidmk.go
index 0154544..04357e0 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -460,6 +460,8 @@
entries := &entriesList[0]
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
testSuiteComponent(entries, a.appTestHelperAppProperties.Test_suites)
+ // introduce a flag variable to control the generation of the .config file
+ entries.SetString("LOCAL_DISABLE_TEST_CONFIG", "true")
})
return entriesList
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 5eaa77b..246c0eb 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -188,3 +188,21 @@
android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_SOONG_DEX_JAR", result.Config, []string{expectedSoongDexJar}, actualSoongDexJar)
}
+
+func TestAndroidTestHelperApp_LocalDisableTestConfig(t *testing.T) {
+ ctx, _ := testJava(t, `
+ android_test_helper_app {
+ name: "foo",
+ srcs: ["a.java"],
+ }
+ `)
+
+ mod := ctx.ModuleForTests("foo", "android_common").Module()
+ entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
+
+ expected := []string{"true"}
+ actual := entries.EntryMap["LOCAL_DISABLE_TEST_CONFIG"]
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("Unexpected flag value - expected: %q, actual: %q", expected, actual)
+ }
+}
diff --git a/java/base.go b/java/base.go
index f7989b8..440b004 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1778,3 +1778,9 @@
func (j *Module) ProvidesUsesLib() *string {
return j.usesLibraryProperties.Provides_uses_lib
}
+
+type ModuleWithStem interface {
+ Stem() string
+}
+
+var _ ModuleWithStem = (*Module)(nil)
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 188d362..792193f 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -22,6 +22,7 @@
"android/soong/android"
"android/soong/dexpreopt"
+
"github.com/google/blueprint/proptools"
"github.com/google/blueprint"
@@ -76,12 +77,17 @@
return true
}
+// Contents of bootclasspath fragments in an apex are considered to be directly in the apex, as if
+// they were listed in java_libs.
+func (b bootclasspathFragmentContentDependencyTag) CopyDirectlyInAnyApex() {}
+
// The tag used for the dependency between the bootclasspath_fragment module and its contents.
var bootclasspathFragmentContentDepTag = bootclasspathFragmentContentDependencyTag{}
var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathFragmentContentDepTag
var _ android.ReplaceSourceWithPrebuilt = bootclasspathFragmentContentDepTag
var _ android.SdkMemberTypeDependencyTag = bootclasspathFragmentContentDepTag
+var _ android.CopyDirectlyInAnyApexTag = bootclasspathFragmentContentDepTag
func IsBootclasspathFragmentContentDepTag(tag blueprint.DependencyTag) bool {
return tag == bootclasspathFragmentContentDepTag
@@ -496,10 +502,21 @@
global := dexpreopt.GetGlobalConfig(ctx)
+ // Convert content names to their appropriate stems, in case a test library is overriding an actual boot jar
+ var stems []string
+ for _, name := range b.properties.Contents {
+ dep := ctx.GetDirectDepWithTag(name, bootclasspathFragmentContentDepTag)
+ if m, ok := dep.(ModuleWithStem); ok {
+ stems = append(stems, m.Stem())
+ } else {
+ ctx.PropertyErrorf("contents", "%v is not a ModuleWithStem", name)
+ }
+ }
+
// Only create configs for updatable boot jars. Non-updatable boot jars must be part of the
// platform_bootclasspath's classpath proto config to guarantee that they come before any
// updatable jars at runtime.
- return global.UpdatableBootJars.Filter(b.properties.Contents)
+ return global.UpdatableBootJars.Filter(stems)
}
func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 9531056..17c7a7b 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -51,7 +51,6 @@
lastReleasedApiXmlFile android.WritablePath
privateApiFile android.WritablePath
removedApiFile android.WritablePath
- removedDexApiFile android.WritablePath
nullabilityWarningsFile android.WritablePath
checkCurrentApiTimestamp android.WritablePath
@@ -79,9 +78,6 @@
// the generated removed API filename by Metalava, defaults to <module>_removed.txt
Removed_api_filename *string
- // the generated removed Dex API filename by Metalava.
- Removed_dex_api_filename *string
-
Check_api struct {
Last_released ApiToCheck
@@ -274,11 +270,6 @@
d.removedApiFilePath = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
}
- if String(d.properties.Removed_dex_api_filename) != "" {
- d.removedDexApiFile = android.PathForModuleOut(ctx, "metalava", String(d.properties.Removed_dex_api_filename))
- cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
- }
-
if Bool(d.properties.Write_sdk_values) {
d.metadataDir = android.PathForModuleOut(ctx, "metalava", "metadata")
cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index bdf055a..52934a3 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -171,7 +171,7 @@
// A platform variant is required but this is for an apex so ignore it.
return false
}
- } else if !apexInfo.InApexVariantByBaseName(requiredApex) {
+ } else if !apexInfo.InApexVariant(requiredApex) {
// An apex variant for a specific apex is required but this is the wrong apex.
return false
}
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index 9111c30..7ffb056 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -17,6 +17,7 @@
import (
"android/soong/android"
"android/soong/dexpreopt"
+
"github.com/google/blueprint"
)
@@ -97,16 +98,33 @@
func (s *SystemServerClasspathModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {
global := dexpreopt.GetGlobalConfig(ctx)
+ // Convert content names to their appropriate stems, in case a test library is overriding an actual boot jar
+ var stems []string
+ for _, name := range s.properties.Contents {
+ dep := ctx.GetDirectDepWithTag(name, systemServerClasspathFragmentContentDepTag)
+ if m, ok := dep.(ModuleWithStem); ok {
+ stems = append(stems, m.Stem())
+ } else {
+ ctx.PropertyErrorf("contents", "%v is not a ModuleWithStem", name)
+ }
+ }
+
// Only create configs for updatable boot jars. Non-updatable system server jars must be part of the
// platform_systemserverclasspath's classpath proto config to guarantee that they come before any
// updatable jars at runtime.
- return global.UpdatableSystemServerJars.Filter(s.properties.Contents)
+ return global.UpdatableSystemServerJars.Filter(stems)
}
type systemServerClasspathFragmentContentDependencyTag struct {
blueprint.BaseDependencyTag
}
+// Contents of system server fragments in an apex are considered to be directly in the apex, as if
+// they were listed in java_libs.
+func (systemServerClasspathFragmentContentDependencyTag) CopyDirectlyInAnyApex() {}
+
+var _ android.CopyDirectlyInAnyApexTag = systemServerClasspathFragmentContentDepTag
+
// The tag used for the dependency between the systemserverclasspath_fragment module and its contents.
var systemServerClasspathFragmentContentDepTag = systemServerClasspathFragmentContentDependencyTag{}
diff --git a/python/test.go b/python/test.go
index 6713189..7413782 100644
--- a/python/test.go
+++ b/python/test.go
@@ -15,6 +15,8 @@
package python
import (
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
"android/soong/tradefed"
)
@@ -102,6 +104,9 @@
binary.pythonInstaller = NewPythonInstaller("nativetest", "nativetest64")
test := &testDecorator{binaryDecorator: binary}
+ if hod == android.HostSupportedNoCross && test.testProperties.Test_options.Unit_test == nil {
+ test.testProperties.Test_options.Unit_test = proptools.BoolPtr(true)
+ }
module.bootstrapper = test
module.installer = test
diff --git a/rust/snapshot_utils.go b/rust/snapshot_utils.go
index e0ed1f7..943c790 100644
--- a/rust/snapshot_utils.go
+++ b/rust/snapshot_utils.go
@@ -20,12 +20,12 @@
func (mod *Module) ExcludeFromVendorSnapshot() bool {
// TODO Rust does not yet support snapshotting
- return true
+ return false
}
func (mod *Module) ExcludeFromRecoverySnapshot() bool {
// TODO Rust does not yet support snapshotting
- return true
+ return false
}
func (mod *Module) IsSnapshotLibrary() bool {
diff --git a/tests/mixed_mode_test.sh b/tests/mixed_mode_test.sh
index 80774bf..b408fd3 100755
--- a/tests/mixed_mode_test.sh
+++ b/tests/mixed_mode_test.sh
@@ -14,7 +14,7 @@
setup
create_mock_bazel
- run_bazel info
+ STANDALONE_BAZEL=true run_bazel info
}
test_bazel_smoke
diff --git a/ui/build/config.go b/ui/build/config.go
index 1d1f71f..3ebde0d 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -72,6 +72,9 @@
// During Bazel execution, Bazel cannot write outside OUT_DIR.
// So if DIST_DIR is set to an external dir (outside of OUT_DIR), we need to rig it temporarily and then migrate files at the end of the build.
riggedDistDirForBazel string
+
+ // Set by multiproduct_kati
+ emptyNinjaFile bool
}
const srcDirFileCheck = "build/soong/root.bp"
@@ -203,9 +206,6 @@
"ANDROID_DEV_SCRIPTS",
"ANDROID_EMULATOR_PREBUILTS",
"ANDROID_PRE_BUILD_PATHS",
-
- // Only set in multiproduct_kati after config generation
- "EMPTY_NINJA_FILE",
)
if ret.UseGoma() || ret.ForceUseGoma() {
@@ -1189,3 +1189,11 @@
func (c *configImpl) BazelMetricsDir() string {
return filepath.Join(c.LogsDir(), "bazel_metrics")
}
+
+func (c *configImpl) SetEmptyNinjaFile(v bool) {
+ c.emptyNinjaFile = v
+}
+
+func (c *configImpl) EmptyNinjaFile() bool {
+ return c.emptyNinjaFile
+}
diff --git a/ui/build/kati.go b/ui/build/kati.go
index 06ec646..dad68fa 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -136,7 +136,7 @@
// information out with --empty_ninja_file.
//
// From https://github.com/google/kati/commit/87b8da7af2c8bea28b1d8ab17679453d859f96e5
- if config.Environment().IsEnvTrue("EMPTY_NINJA_FILE") {
+ if config.EmptyNinjaFile() {
args = append(args, "--empty_ninja_file")
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index cd645eb..7128414 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -119,6 +119,7 @@
args.OutFile = shared.JoinPath(config.SoongOutDir(), ".bootstrap/build.ninja")
args.GlobFile = globFile
args.GeneratingPrimaryBuilder = true
+ args.EmptyNinjaFile = config.EmptyNinjaFile()
args.DelveListen = os.Getenv("SOONG_DELVE")
if args.DelveListen != "" {