diff options
36 files changed, 665 insertions, 577 deletions
@@ -1,17 +1,22 @@ # This file is included by several other projects as the list of people # approving build related projects. +# AMER ahumesky@google.com asmundak@google.com ccross@android.com cparsons@google.com dwillemsen@google.com eakammer@google.com -jingwen@google.com joeo@google.com -lberki@google.com +spandandas@google.com +yuntaoxu@google.com + +# APAC +jingwen@google.com ruperts@google.com -# To expedite LON reviews +# EMEA hansson@google.com +lberki@google.com paulduffin@google.com diff --git a/android/arch.go b/android/arch.go index 340f136c7..cc70eee9c 100644 --- a/android/arch.go +++ b/android/arch.go @@ -1987,6 +1987,10 @@ func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySe axisToProps[bazel.OsConfigurationAxis] = osToProp axisToProps[bazel.OsArchConfigurationAxis] = archOsToProp + axisToProps[bazel.BionicConfigurationAxis] = map[string]interface{}{ + "bionic": getTargetStruct(ctx, propertySet, archProperties, "Bionic"), + } + return axisToProps } diff --git a/android/bazel.go b/android/bazel.go index 8d137621d..d40e6508e 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -129,7 +129,7 @@ var ( // Keep any existing BUILD files (and do not generate new BUILD files) for these directories bp2buildKeepExistingBuildFile = map[string]bool{ // This is actually build/bazel/build.BAZEL symlinked to ./BUILD - ".":/*recrusive = */ false, + ".":/*recursive = */ false, "build/bazel":/* recursive = */ true, "build/pesto":/* recursive = */ true, @@ -140,13 +140,15 @@ var ( "prebuilts/sdk":/* recursive = */ false, "prebuilts/sdk/tools":/* recursive = */ false, + "packages/apps/Music":/* recursive = */ false, } // Configure modules in these directories to enable bp2build_available: true or false by default. bp2buildDefaultConfig = Bp2BuildConfig{ - "bionic": Bp2BuildDefaultTrueRecursively, - "external/gwp_asan": Bp2BuildDefaultTrueRecursively, - "system/core/libcutils": Bp2BuildDefaultTrueRecursively, + "bionic": Bp2BuildDefaultTrueRecursively, + "build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively, + "external/gwp_asan": Bp2BuildDefaultTrueRecursively, + "system/core/libcutils": Bp2BuildDefaultTrueRecursively, "system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively, "system/libbase": Bp2BuildDefaultTrueRecursively, "system/logging/liblog": Bp2BuildDefaultTrueRecursively, diff --git a/android/sdk.go b/android/sdk.go index e70003144..da740f3cd 100644 --- a/android/sdk.go +++ b/android/sdk.go @@ -239,6 +239,12 @@ type SnapshotBuilder interface { // to the zip CopyToSnapshot(src Path, dest string) + // Return the path to an empty file. + // + // This can be used by sdk member types that need to create an empty file in the snapshot, simply + // pass the value returned from this to the CopyToSnapshot() method. + EmptyFile() Path + // Unzip the supplied zip into the snapshot relative directory destDir. UnzipToSnapshot(zipPath Path, destDir string) diff --git a/apex/apex.go b/apex/apex.go index 11df288a3..d385ac1c3 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2240,6 +2240,7 @@ func newApexBundle() *apexBundle { android.InitDefaultableModule(module) android.InitSdkAwareModule(module) android.InitOverridableModule(module, &module.overridableProperties.Overrides) + android.InitBazelModule(module) return module } diff --git a/apex/apex_test.go b/apex/apex_test.go index 422e46c4d..d6c714200 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -4667,6 +4667,13 @@ func TestPrebuiltApexNameWithPlatformBootclasspath(t *testing.T) { prebuilt_bootclasspath_fragment { name: "art-bootclasspath-fragment", contents: ["core-oj"], + hidden_api: { + annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", + metadata: "my-bootclasspath-fragment/metadata.csv", + index: "my-bootclasspath-fragment/index.csv", + stub_flags: "my-bootclasspath-fragment/stub-flags.csv", + all_flags: "my-bootclasspath-fragment/all-flags.csv", + }, } java_import { @@ -4890,7 +4897,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { } } - checkHiddenAPIIndexInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) { + checkHiddenAPIIndexFromClassesInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) { t.Helper() platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common") var rule android.TestingBuildParams @@ -4899,6 +4906,15 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { java.CheckHiddenAPIRuleInputs(t, "intermediate index", expectedIntermediateInputs, rule) } + checkHiddenAPIIndexFromFlagsInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) { + t.Helper() + platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common") + var rule android.TestingBuildParams + + rule = platformBootclasspath.Output("hiddenapi-index.csv") + java.CheckHiddenAPIRuleInputs(t, "monolithic index", expectedIntermediateInputs, rule) + } + fragment := java.ApexVariantReference{ Apex: proptools.StringPtr("myapex"), Module: proptools.StringPtr("my-bootclasspath-fragment"), @@ -4923,6 +4939,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { name: "my-bootclasspath-fragment", contents: ["libfoo", "libbar"], apex_available: ["myapex"], + hidden_api: { + annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", + metadata: "my-bootclasspath-fragment/metadata.csv", + index: "my-bootclasspath-fragment/index.csv", + stub_flags: "my-bootclasspath-fragment/stub-flags.csv", + all_flags: "my-bootclasspath-fragment/all-flags.csv", + }, } java_import { @@ -4946,9 +4969,10 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar") // Verify the correct module jars contribute to the hiddenapi index file. - checkHiddenAPIIndexInputs(t, ctx, ` - out/soong/.intermediates/libbar.stubs/android_common/combined/libbar.stubs.jar - out/soong/.intermediates/libfoo/android_common_myapex/combined/libfoo.jar + checkHiddenAPIIndexFromClassesInputs(t, ctx, ``) + checkHiddenAPIIndexFromFlagsInputs(t, ctx, ` + my-bootclasspath-fragment/index.csv + out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv `) }) @@ -4964,6 +4988,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { name: "my-bootclasspath-fragment", contents: ["libfoo", "libbar"], apex_available: ["myapex"], + hidden_api: { + annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", + metadata: "my-bootclasspath-fragment/metadata.csv", + index: "my-bootclasspath-fragment/index.csv", + stub_flags: "my-bootclasspath-fragment/stub-flags.csv", + all_flags: "my-bootclasspath-fragment/all-flags.csv", + }, } java_import { @@ -4987,9 +5018,10 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar") // Verify the correct module jars contribute to the hiddenapi index file. - checkHiddenAPIIndexInputs(t, ctx, ` - out/soong/.intermediates/libbar.stubs/android_common/combined/libbar.stubs.jar - out/soong/.intermediates/libfoo/android_common_myapex/combined/libfoo.jar + checkHiddenAPIIndexFromClassesInputs(t, ctx, ``) + checkHiddenAPIIndexFromFlagsInputs(t, ctx, ` + my-bootclasspath-fragment/index.csv + out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv `) }) @@ -5012,6 +5044,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { name: "my-bootclasspath-fragment", contents: ["libfoo", "libbar"], apex_available: ["myapex"], + hidden_api: { + annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", + metadata: "my-bootclasspath-fragment/metadata.csv", + index: "my-bootclasspath-fragment/index.csv", + stub_flags: "my-bootclasspath-fragment/stub-flags.csv", + all_flags: "my-bootclasspath-fragment/all-flags.csv", + }, } java_import { @@ -5070,6 +5109,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { name: "my-bootclasspath-fragment", contents: ["libfoo", "libbar"], apex_available: ["myapex"], + hidden_api: { + annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", + metadata: "my-bootclasspath-fragment/metadata.csv", + index: "my-bootclasspath-fragment/index.csv", + stub_flags: "my-bootclasspath-fragment/stub-flags.csv", + all_flags: "my-bootclasspath-fragment/all-flags.csv", + }, } java_import { @@ -5108,9 +5154,10 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar") // Verify the correct module jars contribute to the hiddenapi index file. - checkHiddenAPIIndexInputs(t, ctx, ` - out/soong/.intermediates/prebuilt_libbar.stubs/android_common/combined/libbar.stubs.jar - out/soong/.intermediates/prebuilt_libfoo/android_common_myapex/combined/libfoo.jar + checkHiddenAPIIndexFromClassesInputs(t, ctx, ``) + checkHiddenAPIIndexFromFlagsInputs(t, ctx, ` + my-bootclasspath-fragment/index.csv + out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv `) }) @@ -5146,6 +5193,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { name: "my-bootclasspath-fragment", contents: ["libfoo", "libbar"], apex_available: ["myapex"], + hidden_api: { + annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", + metadata: "my-bootclasspath-fragment/metadata.csv", + index: "my-bootclasspath-fragment/index.csv", + stub_flags: "my-bootclasspath-fragment/stub-flags.csv", + all_flags: "my-bootclasspath-fragment/all-flags.csv", + }, } java_import { @@ -5182,9 +5236,10 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar") // Verify the correct module jars contribute to the hiddenapi index file. - checkHiddenAPIIndexInputs(t, ctx, ` - out/soong/.intermediates/libbar/android_common_myapex/javac/libbar.jar - out/soong/.intermediates/libfoo/android_common_apex10000/javac/libfoo.jar + checkHiddenAPIIndexFromClassesInputs(t, ctx, ``) + checkHiddenAPIIndexFromFlagsInputs(t, ctx, ` + my-bootclasspath-fragment/index.csv + out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv `) }) @@ -5220,6 +5275,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { name: "my-bootclasspath-fragment", contents: ["libfoo", "libbar"], apex_available: ["myapex"], + hidden_api: { + annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", + metadata: "my-bootclasspath-fragment/metadata.csv", + index: "my-bootclasspath-fragment/index.csv", + stub_flags: "my-bootclasspath-fragment/stub-flags.csv", + all_flags: "my-bootclasspath-fragment/all-flags.csv", + }, } java_import { @@ -5258,9 +5320,10 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar") // Verify the correct module jars contribute to the hiddenapi index file. - checkHiddenAPIIndexInputs(t, ctx, ` - out/soong/.intermediates/prebuilt_libbar.stubs/android_common/combined/libbar.stubs.jar - out/soong/.intermediates/prebuilt_libfoo/android_common_myapex/combined/libfoo.jar + checkHiddenAPIIndexFromClassesInputs(t, ctx, ``) + checkHiddenAPIIndexFromFlagsInputs(t, ctx, ` + my-bootclasspath-fragment/index.csv + out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv `) }) } @@ -7183,6 +7246,13 @@ func TestDexpreoptAccessDexFilesFromPrebuiltApex(t *testing.T) { name: "my-bootclasspath-fragment", contents: ["libfoo"], apex_available: ["myapex"], + hidden_api: { + annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", + metadata: "my-bootclasspath-fragment/metadata.csv", + index: "my-bootclasspath-fragment/index.csv", + stub_flags: "my-bootclasspath-fragment/stub-flags.csv", + all_flags: "my-bootclasspath-fragment/all-flags.csv", + }, } java_import { diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go index 4b1600e1c..5cd3eab6a 100644 --- a/apex/bootclasspath_fragment_test.go +++ b/apex/bootclasspath_fragment_test.go @@ -383,6 +383,13 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) { apex_available: [ "com.android.art", ], + hidden_api: { + annotation_flags: "mybootclasspathfragment/annotation-flags.csv", + metadata: "mybootclasspathfragment/metadata.csv", + index: "mybootclasspathfragment/index.csv", + stub_flags: "mybootclasspathfragment/stub-flags.csv", + all_flags: "mybootclasspathfragment/all-flags.csv", + }, } `, contentsInsert(contents), prefer) return android.FixtureAddTextFile("prebuilts/module_sdk/art/Android.bp", text) @@ -582,6 +589,13 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { apex_available: [ "com.android.art", ], + hidden_api: { + annotation_flags: "mybootclasspathfragment/annotation-flags.csv", + metadata: "mybootclasspathfragment/metadata.csv", + index: "mybootclasspathfragment/index.csv", + stub_flags: "mybootclasspathfragment/stub-flags.csv", + all_flags: "mybootclasspathfragment/all-flags.csv", + }, } `) diff --git a/apex/builder.go b/apex/builder.go index 24c049bcd..148f42f09 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -761,7 +761,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { rule := java.Signapk args := map[string]string{ "certificates": pem.String() + " " + key.String(), - "flags": "-a 4096", //alignment + "flags": "-a 4096 --align-file-size", //alignment } implicits := android.Paths{pem, key} if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_SIGNAPK") { diff --git a/bazel/configurability.go b/bazel/configurability.go index 282c6061a..35f194dfe 100644 --- a/bazel/configurability.go +++ b/bazel/configurability.go @@ -91,6 +91,11 @@ var ( conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map. } + platformBionicMap = map[string]string{ + "bionic": "//build/bazel/platforms/os:bionic", + conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map. + } + platformOsArchMap = map[string]string{ osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm", osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64", @@ -117,6 +122,7 @@ const ( arch os osArch + bionic productVariables ) @@ -126,6 +132,7 @@ func (ct configurationType) String() string { arch: "arch", os: "os", osArch: "arch_os", + bionic: "bionic", productVariables: "product_variables", }[ct] } @@ -148,6 +155,10 @@ func (ct configurationType) validateConfig(config string) { if _, ok := platformOsArchMap[config]; !ok { panic(fmt.Errorf("Unknown os+arch: %s", config)) } + case bionic: + if _, ok := platformBionicMap[config]; !ok { + panic(fmt.Errorf("Unknown for %s: %s", ct.String(), config)) + } case productVariables: // do nothing default: @@ -167,6 +178,8 @@ func (ct configurationType) SelectKey(config string) string { return platformOsMap[config] case osArch: return platformOsArchMap[config] + case bionic: + return platformBionicMap[config] case productVariables: if config == conditionsDefault { return ConditionsDefaultSelectKey @@ -186,6 +199,8 @@ var ( OsConfigurationAxis = ConfigurationAxis{configurationType: os} // An axis for arch+os-specific configurations OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch} + // An axis for bionic os-specific configurations + BionicConfigurationAxis = ConfigurationAxis{configurationType: bionic} ) // ProductVariableConfigurationAxis returns an axis for the given product variable diff --git a/bazel/properties.go b/bazel/properties.go index 7ecc92bdb..2656badb5 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -321,7 +321,7 @@ func (la *LabelAttribute) SetSelectValue(axis ConfigurationAxis, config string, switch axis.configurationType { case noConfig: la.Value = &value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: if la.ConfigurableValues == nil { la.ConfigurableValues = make(configurableLabels) } @@ -337,7 +337,7 @@ func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) Lab switch axis.configurationType { case noConfig: return *la.Value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: return *la.ConfigurableValues[axis][config] default: panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) @@ -394,7 +394,7 @@ func (ba *BoolAttribute) SetSelectValue(axis ConfigurationAxis, config string, v switch axis.configurationType { case noConfig: ba.Value = value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: if ba.ConfigurableValues == nil { ba.ConfigurableValues = make(configurableBools) } @@ -410,7 +410,7 @@ func (ba BoolAttribute) SelectValue(axis ConfigurationAxis, config string) *bool switch axis.configurationType { case noConfig: return ba.Value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: if v, ok := ba.ConfigurableValues[axis][config]; ok { return &v } else { @@ -509,7 +509,7 @@ func (lla *LabelListAttribute) SetSelectValue(axis ConfigurationAxis, config str switch axis.configurationType { case noConfig: lla.Value = list - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: if lla.ConfigurableValues == nil { lla.ConfigurableValues = make(configurableLabelLists) } @@ -525,7 +525,7 @@ func (lla *LabelListAttribute) SelectValue(axis ConfigurationAxis, config string switch axis.configurationType { case noConfig: return lla.Value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: return lla.ConfigurableValues[axis][config] default: panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) @@ -682,7 +682,7 @@ func (sla *StringListAttribute) SetSelectValue(axis ConfigurationAxis, config st switch axis.configurationType { case noConfig: sla.Value = list - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: if sla.ConfigurableValues == nil { sla.ConfigurableValues = make(configurableStringLists) } @@ -698,7 +698,7 @@ func (sla *StringListAttribute) SelectValue(axis ConfigurationAxis, config strin switch axis.configurationType { case noConfig: return sla.Value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: return sla.ConfigurableValues[axis][config] default: panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go index fbf6fa289..f4a1016bc 100644 --- a/bp2build/apex_conversion_test.go +++ b/bp2build/apex_conversion_test.go @@ -46,3 +46,23 @@ apex { manifest = "manifest.json", )`}}) } + +func TestApexBundleHasBazelModuleProps(t *testing.T) { + runApexTestCase(t, bp2buildTestCase{ + description: "apex - has bazel module props", + moduleTypeUnderTest: "apex", + moduleTypeUnderTestFactory: apex.BundleFactory, + moduleTypeUnderTestBp2BuildMutator: apex.ApexBundleBp2Build, + filesystem: map[string]string{}, + blueprint: ` +apex { + name: "apogee", + manifest: "manifest.json", + bazel_module: { bp2build_available: true }, +} +`, + expectedBazelTargets: []string{`apex( + name = "apogee", + manifest = "manifest.json", +)`}}) +} diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 4f720f56c..662d9d11a 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -118,6 +118,7 @@ func TestCcLibrarySimple(t *testing.T) { moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, filesystem: map[string]string{ "android.cpp": "", + "bionic.cpp": "", "darwin.cpp": "", // Refer to cc.headerExts for the supported header extensions in Soong. "header.h": "", @@ -164,6 +165,9 @@ cc_library { darwin: { srcs: ["darwin.cpp"], }, + bionic: { + srcs: ["bionic.cpp"] + }, }, } `, @@ -190,6 +194,9 @@ cc_library { "//build/bazel/platforms/os:darwin": ["darwin.cpp"], "//build/bazel/platforms/os:linux": ["linux.cpp"], "//conditions:default": [], + }) + select({ + "//build/bazel/platforms/os:bionic": ["bionic.cpp"], + "//conditions:default": [], }), )`}}) } diff --git a/cc/Android.bp b/cc/Android.bp index 05fff1244..164d32b12 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -59,6 +59,7 @@ bootstrap_go_package { "binary.go", "binary_sdk_member.go", "fuzz.go", + "fuzz_common.go", "library.go", "library_headers.go", "library_sdk_member.go", diff --git a/cc/androidmk.go b/cc/androidmk.go index e58d166a3..bda10067b 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -401,24 +401,24 @@ func (fuzz *fuzzBinary) AndroidMkEntries(ctx AndroidMkContext, entries *android. ctx.subAndroidMk(entries, fuzz.binaryDecorator) var fuzzFiles []string - for _, d := range fuzz.corpus { + for _, d := range fuzz.fuzzPackagedModule.Corpus { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.corpusIntermediateDir.String())+":corpus/"+d.Base()) + filepath.Dir(fuzz.fuzzPackagedModule.CorpusIntermediateDir.String())+":corpus/"+d.Base()) } - for _, d := range fuzz.data { + for _, d := range fuzz.fuzzPackagedModule.Data { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.dataIntermediateDir.String())+":data/"+d.Rel()) + filepath.Dir(fuzz.fuzzPackagedModule.DataIntermediateDir.String())+":data/"+d.Rel()) } - if fuzz.dictionary != nil { + if fuzz.fuzzPackagedModule.Dictionary != nil { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.dictionary.String())+":"+fuzz.dictionary.Base()) + filepath.Dir(fuzz.fuzzPackagedModule.Dictionary.String())+":"+fuzz.fuzzPackagedModule.Dictionary.Base()) } - if fuzz.config != nil { + if fuzz.fuzzPackagedModule.Config != nil { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.config.String())+":config.json") + filepath.Dir(fuzz.fuzzPackagedModule.Config.String())+":config.json") } entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { diff --git a/cc/bp2build.go b/cc/bp2build.go index 536f1125d..484e922d1 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -72,36 +72,34 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) { allDeps = append(allDeps, baseLinkerProps.Whole_static_libs...) allDeps = append(allDeps, baseLinkerProps.Shared_libs...) allDeps = append(allDeps, baseLinkerProps.Exclude_shared_libs...) + allDeps = append(allDeps, baseLinkerProps.System_shared_libs...) } } } // Deps in the static: { .. } and shared: { .. } props of a cc_library. if lib, ok := module.compiler.(*libraryDecorator); ok { - appendDeps := func(deps []string, p StaticOrSharedProperties) []string { + appendDeps := func(deps []string, p StaticOrSharedProperties, system bool) []string { deps = append(deps, p.Static_libs...) deps = append(deps, p.Whole_static_libs...) deps = append(deps, p.Shared_libs...) + // TODO(b/186024507, b/186489250): Temporarily exclude adding + // system_shared_libs deps until libc and libm builds. + if system { + allDeps = append(allDeps, p.System_shared_libs...) + } return deps } - 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. - if lib.static() { - allDeps = append(allDeps, lib.StaticProperties.Static.System_shared_libs...) - } else if lib.shared() { - allDeps = append(allDeps, lib.SharedProperties.Shared.System_shared_libs...) - } + allDeps = appendDeps(allDeps, lib.SharedProperties.Shared, lib.shared()) + allDeps = appendDeps(allDeps, lib.StaticProperties.Static, lib.static()) // Deps in the target/arch nested static: { .. } and shared: { .. } props of a cc_library. // target: { <target>: shared: { ... } } for _, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) { for _, props := range configToProps { if p, ok := props.(*SharedProperties); ok { - allDeps = appendDeps(allDeps, p.Shared) + allDeps = appendDeps(allDeps, p.Shared, lib.shared()) } } } @@ -109,7 +107,7 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) { for _, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) { for _, props := range configToProps { if p, ok := props.(*StaticProperties); ok { - allDeps = appendDeps(allDeps, p.Static) + allDeps = appendDeps(allDeps, p.Static, lib.static()) } } } diff --git a/cc/builder.go b/cc/builder.go index b0842ec72..842ce8515 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -237,7 +237,7 @@ var ( // -w has been added since header-abi-dumper does not need to produce any sort of diagnostic information. sAbiDump, sAbiDumpRE = pctx.RemoteStaticRules("sAbiDump", blueprint.RuleParams{ - Command: "rm -f $out && $reTemplate$sAbiDumper -o ${out} $in $exportDirs -- $cFlags -w -isystem prebuilts/clang-tools/${config.HostPrebuiltTag}/clang-headers", + Command: "rm -f $out && $reTemplate$sAbiDumper --root-dir . --root-dir $$OUT_DIR:out -o ${out} $in $exportDirs -- $cFlags -w -isystem prebuilts/clang-tools/${config.HostPrebuiltTag}/clang-headers", CommandDeps: []string{"$sAbiDumper"}, }, &remoteexec.REParams{ Labels: map[string]string{"type": "abi-dump", "tool": "header-abi-dumper"}, @@ -255,7 +255,7 @@ var ( // sAbi dump file. sAbiLink, sAbiLinkRE = pctx.RemoteStaticRules("sAbiLink", blueprint.RuleParams{ - Command: "$reTemplate$sAbiLinker -o ${out} $symbolFilter -arch $arch $exportedHeaderFlags @${out}.rsp ", + Command: "$reTemplate$sAbiLinker --root-dir . --root-dir $$OUT_DIR:out -o ${out} $symbolFilter -arch $arch $exportedHeaderFlags @${out}.rsp", CommandDeps: []string{"$sAbiLinker"}, Rspfile: "${out}.rsp", RspfileContent: "${in}", @@ -756,14 +756,13 @@ func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool { // members of the cc.Module to this decorator. Thus, a cc_binary module has custom linker and // installer logic. type Module struct { - android.ModuleBase - android.DefaultableModuleBase - android.ApexModuleBase + FuzzModule + android.SdkBase android.BazelModuleBase - Properties BaseProperties VendorProperties VendorProperties + Properties BaseProperties // initialize before calling Init hod android.HostOrDeviceSupported diff --git a/cc/config/clang.go b/cc/config/clang.go index 9cfe28f28..53a73066e 100644 --- a/cc/config/clang.go +++ b/cc/config/clang.go @@ -92,64 +92,6 @@ var ClangTidyDisableChecks = []string{ "readability-function-cognitive-complexity", // http://b/175055536 } -func init() { - exportStringListStaticVariable("ClangExtraCflags", []string{ - "-D__compiler_offsetof=__builtin_offsetof", - - // Emit address-significance table which allows linker to perform safe ICF. Clang does - // not emit the table by default on Android since NDK still uses GNU binutils. - "-faddrsig", - - // Turn on -fcommon explicitly, since Clang now defaults to -fno-common. The cleanup bug - // tracking this is http://b/151457797. - "-fcommon", - - // Help catch common 32/64-bit errors. - "-Werror=int-conversion", - - // Enable the new pass manager. - "-fexperimental-new-pass-manager", - - // Disable overly aggressive warning for macros defined with a leading underscore - // This happens in AndroidConfig.h, which is included nearly everywhere. - // TODO: can we remove this now? - "-Wno-reserved-id-macro", - - // Workaround for ccache with clang. - // See http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html. - "-Wno-unused-command-line-argument", - - // Force clang to always output color diagnostics. Ninja will strip the ANSI - // color codes if it is not running in a terminal. - "-fcolor-diagnostics", - - // Warnings from clang-7.0 - "-Wno-sign-compare", - - // Warnings from clang-8.0 - "-Wno-defaulted-function-deleted", - - // Disable -Winconsistent-missing-override until we can clean up the existing - // codebase for it. - "-Wno-inconsistent-missing-override", - - // Warnings from clang-10 - // Nested and array designated initialization is nice to have. - "-Wno-c99-designator", - - // Warnings from clang-12 - "-Wno-gnu-folding-constant", - - // Calls to the APIs that are newer than the min sdk version of the caller should be - // guarded with __builtin_available. - "-Wunguarded-availability", - // This macro allows the bionic versioning.h to indirectly determine whether the - // option -Wunguarded-availability is on or not. - "-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__", - }) - -} - func ClangFilterUnknownCflags(cflags []string) []string { result, _ := android.FilterList(cflags, ClangUnknownCflags) return result diff --git a/cc/config/global.go b/cc/config/global.go index bcee06afa..dfbe6c4f5 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -55,6 +55,59 @@ var ( "-Werror=pragma-pack-suspicious-include", "-Werror=string-plus-int", "-Werror=unreachable-code-loop-increment", + + "-D__compiler_offsetof=__builtin_offsetof", + + // Emit address-significance table which allows linker to perform safe ICF. Clang does + // not emit the table by default on Android since NDK still uses GNU binutils. + "-faddrsig", + + // Turn on -fcommon explicitly, since Clang now defaults to -fno-common. The cleanup bug + // tracking this is http://b/151457797. + "-fcommon", + + // Help catch common 32/64-bit errors. + "-Werror=int-conversion", + + // Enable the new pass manager. + "-fexperimental-new-pass-manager", + + // Disable overly aggressive warning for macros defined with a leading underscore + // This happens in AndroidConfig.h, which is included nearly everywhere. + // TODO: can we remove this now? + "-Wno-reserved-id-macro", + + // Workaround for ccache with clang. + // See http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html. + "-Wno-unused-command-line-argument", + + // Force clang to always output color diagnostics. Ninja will strip the ANSI + // color codes if it is not running in a terminal. + "-fcolor-diagnostics", + + // Warnings from clang-7.0 + "-Wno-sign-compare", + + // Warnings from clang-8.0 + "-Wno-defaulted-function-deleted", + + // Disable -Winconsistent-missing-override until we can clean up the existing + // codebase for it. + "-Wno-inconsistent-missing-override", + + // Warnings from clang-10 + // Nested and array designated initialization is nice to have. + "-Wno-c99-designator", + + // Warnings from clang-12 + "-Wno-gnu-folding-constant", + + // Calls to the APIs that are newer than the min sdk version of the caller should be + // guarded with __builtin_available. + "-Wunguarded-availability", + // This macro allows the bionic versioning.h to indirectly determine whether the + // option -Wunguarded-availability is on or not. + "-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__", } commonGlobalConlyflags = []string{} @@ -246,7 +299,6 @@ func init() { bazelCommonGlobalCflags := append( commonGlobalCflags, []string{ - "${ClangExtraCflags}", // Default to zero initialization. "-ftrivial-auto-var-init=zero", "-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang", @@ -255,7 +307,6 @@ func init() { pctx.VariableFunc("CommonGlobalCflags", func(ctx android.PackageVarContext) string { flags := commonGlobalCflags - flags = append(flags, "${ClangExtraCflags}") // http://b/131390872 // Automatically initialize any uninitialized stack variables. diff --git a/cc/fuzz.go b/cc/fuzz.go index c780b6f97..8b0f93e0e 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -94,19 +94,14 @@ type fuzzBinary struct { *binaryDecorator *baseCompiler - Properties FuzzProperties - dictionary android.Path - corpus android.Paths - corpusIntermediateDir android.Path - config android.Path - data android.Paths - dataIntermediateDir android.Path - installedSharedDeps []string + fuzzPackagedModule FuzzPackagedModule + + installedSharedDeps []string } func (fuzz *fuzzBinary) linkerProps() []interface{} { props := fuzz.binaryDecorator.linkerProps() - props = append(props, &fuzz.Properties) + props = append(props, &fuzz.fuzzPackagedModule.FuzzProperties) return props } @@ -257,41 +252,41 @@ func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzz.binaryDecorator.baseInstaller.install(ctx, file) - fuzz.corpus = android.PathsForModuleSrc(ctx, fuzz.Properties.Corpus) + fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus) builder := android.NewRuleBuilder(pctx, ctx) intermediateDir := android.PathForModuleOut(ctx, "corpus") - for _, entry := range fuzz.corpus { + for _, entry := range fuzz.fuzzPackagedModule.Corpus { builder.Command().Text("cp"). Input(entry). Output(intermediateDir.Join(ctx, entry.Base())) } builder.Build("copy_corpus", "copy corpus") - fuzz.corpusIntermediateDir = intermediateDir + fuzz.fuzzPackagedModule.CorpusIntermediateDir = intermediateDir - fuzz.data = android.PathsForModuleSrc(ctx, fuzz.Properties.Data) + fuzz.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Data) builder = android.NewRuleBuilder(pctx, ctx) intermediateDir = android.PathForModuleOut(ctx, "data") - for _, entry := range fuzz.data { + for _, entry := range fuzz.fuzzPackagedModule.Data { builder.Command().Text("cp"). Input(entry). Output(intermediateDir.Join(ctx, entry.Rel())) } builder.Build("copy_data", "copy data") - fuzz.dataIntermediateDir = intermediateDir + fuzz.fuzzPackagedModule.DataIntermediateDir = intermediateDir - if fuzz.Properties.Dictionary != nil { - fuzz.dictionary = android.PathForModuleSrc(ctx, *fuzz.Properties.Dictionary) - if fuzz.dictionary.Ext() != ".dict" { + if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil { + fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary) + if fuzz.fuzzPackagedModule.Dictionary.Ext() != ".dict" { ctx.PropertyErrorf("dictionary", "Fuzzer dictionary %q does not have '.dict' extension", - fuzz.dictionary.String()) + fuzz.fuzzPackagedModule.Dictionary.String()) } } - if fuzz.Properties.Fuzz_config != nil { + if fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil { configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json") - android.WriteFileRule(ctx, configPath, fuzz.Properties.Fuzz_config.String()) - fuzz.config = configPath + android.WriteFileRule(ctx, configPath, fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config.String()) + fuzz.fuzzPackagedModule.Config = configPath } // Grab the list of required shared libraries. @@ -359,32 +354,20 @@ func NewFuzz(hod android.HostOrDeviceSupported) *Module { // Responsible for generating GNU Make rules that package fuzz targets into // their architecture & target/host specific zip file. -type fuzzPackager struct { - packages android.Paths +type ccFuzzPackager struct { + FuzzPackager sharedLibInstallStrings []string - fuzzTargets map[string]bool } func fuzzPackagingFactory() android.Singleton { - return &fuzzPackager{} -} - -type fileToZip struct { - SourceFilePath android.Path - DestinationPathPrefix string -} - -type archOs struct { - hostOrTarget string - arch string - dir string + return &ccFuzzPackager{} } -func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { +func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { // Map between each architecture + host/device combination, and the files that // need to be packaged (in the tuple of {source file, destination folder in // archive}). - archDirs := make(map[archOs][]fileToZip) + archDirs := make(map[ArchOs][]FileToZip) // Map tracking whether each shared library has an install rule to avoid duplicate install rules from // multiple fuzzers that depend on the same shared library. @@ -392,29 +375,21 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { // List of individual fuzz targets, so that 'make fuzz' also installs the targets // to the correct output directories as well. - s.fuzzTargets = make(map[string]bool) + s.FuzzTargets = make(map[string]bool) ctx.VisitAllModules(func(module android.Module) { - // Discard non-fuzz targets. ccModule, ok := module.(*Module) - if !ok { + if !ok || ccModule.Properties.PreventInstall { return } - fuzzModule, ok := ccModule.compiler.(*fuzzBinary) - if !ok { - return - } - - // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of - // fuzz targets we're going to package anyway. - if !ccModule.Enabled() || ccModule.Properties.PreventInstall || - ccModule.InRamdisk() || ccModule.InVendorRamdisk() || ccModule.InRecovery() { + // Discard non-fuzz targets. + if ok := IsValid(ccModule.FuzzModule); !ok { return } - // Discard modules that are in an unavailable namespace. - if !ccModule.ExportedToMake() { + fuzzModule, ok := ccModule.compiler.(*fuzzBinary) + if !ok { return } @@ -425,42 +400,21 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { archString := ccModule.Arch().ArchType.String() archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString) - archOs := archOs{hostOrTarget: hostOrTargetString, arch: archString, dir: archDir.String()} + archOs := ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()} // Grab the list of required shared libraries. sharedLibraries := collectAllSharedDependencies(ctx, module) - var files []fileToZip + var files []FileToZip builder := android.NewRuleBuilder(pctx, ctx) - // Package the corpora into a zipfile. - if fuzzModule.corpus != nil { - corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip") - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", corpusZip) - rspFile := corpusZip.ReplaceExtension(ctx, "rsp") - command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.corpus) - files = append(files, fileToZip{corpusZip, ""}) - } - - // Package the data into a zipfile. - if fuzzModule.data != nil { - dataZip := archDir.Join(ctx, module.Name()+"_data.zip") - command := builder.Command().BuiltTool("soong_zip"). - FlagWithOutput("-o ", dataZip) - for _, f := range fuzzModule.data { - intermediateDir := strings.TrimSuffix(f.String(), f.Rel()) - command.FlagWithArg("-C ", intermediateDir) - command.FlagWithInput("-f ", f) - } - files = append(files, fileToZip{dataZip, ""}) - } + // Package the corpus, data, dict and config into a zipfile. + files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder) // Find and mark all the transiently-dependent shared libraries for // packaging. for _, library := range sharedLibraries { - files = append(files, fileToZip{library, "lib"}) + files = append(files, FileToZip{library, "lib"}) // For each architecture-specific shared library dependency, we need to // install it to the output directory. Setup the install destination here, @@ -492,83 +446,20 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { } // The executable. - files = append(files, fileToZip{ccModule.UnstrippedOutputFile(), ""}) + files = append(files, FileToZip{ccModule.UnstrippedOutputFile(), ""}) - // The dictionary. - if fuzzModule.dictionary != nil { - files = append(files, fileToZip{fuzzModule.dictionary, ""}) - } - - // Additional fuzz config. - if fuzzModule.config != nil { - files = append(files, fileToZip{fuzzModule.config, ""}) - } - - fuzzZip := archDir.Join(ctx, module.Name()+".zip") - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", fuzzZip) - for _, file := range files { - if file.DestinationPathPrefix != "" { - command.FlagWithArg("-P ", file.DestinationPathPrefix) - } else { - command.Flag("-P ''") - } - command.FlagWithInput("-f ", file.SourceFilePath) - } - - builder.Build("create-"+fuzzZip.String(), - "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString) - - // Don't add modules to 'make haiku' that are set to not be exported to the - // fuzzing infrastructure. - if config := fuzzModule.Properties.Fuzz_config; config != nil { - if ccModule.Host() && !BoolDefault(config.Fuzz_on_haiku_host, true) { - return - } else if !BoolDefault(config.Fuzz_on_haiku_device, true) { - return - } + archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs) + if !ok { + return } - - s.fuzzTargets[module.Name()] = true - archDirs[archOs] = append(archDirs[archOs], fileToZip{fuzzZip, ""}) }) - var archOsList []archOs - for archOs := range archDirs { - archOsList = append(archOsList, archOs) - } - sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].dir < archOsList[j].dir }) + s.CreateFuzzPackage(ctx, archDirs, Cc) - for _, archOs := range archOsList { - filesToZip := archDirs[archOs] - arch := archOs.arch - hostOrTarget := archOs.hostOrTarget - builder := android.NewRuleBuilder(pctx, ctx) - outputFile := android.PathForOutput(ctx, "fuzz-"+hostOrTarget+"-"+arch+".zip") - s.packages = append(s.packages, outputFile) - - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", outputFile). - Flag("-L 0") // No need to try and re-compress the zipfiles. - - for _, fileToZip := range filesToZip { - if fileToZip.DestinationPathPrefix != "" { - command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix) - } else { - command.Flag("-P ''") - } - command.FlagWithInput("-f ", fileToZip.SourceFilePath) - } - - builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget, - "Create fuzz target packages for "+arch+"-"+hostOrTarget) - } } -func (s *fuzzPackager) MakeVars(ctx android.MakeVarsContext) { - packages := s.packages.Strings() +func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) { + packages := s.Packages.Strings() sort.Strings(packages) sort.Strings(s.sharedLibInstallStrings) // TODO(mitchp): Migrate this to use MakeVarsContext::DistForGoal() when it's @@ -580,10 +471,5 @@ func (s *fuzzPackager) MakeVars(ctx android.MakeVarsContext) { strings.Join(s.sharedLibInstallStrings, " ")) // Preallocate the slice of fuzz targets to minimise memory allocations. - fuzzTargets := make([]string, 0, len(s.fuzzTargets)) - for target, _ := range s.fuzzTargets { - fuzzTargets = append(fuzzTargets, target) - } - sort.Strings(fuzzTargets) - ctx.Strict("ALL_FUZZ_TARGETS", strings.Join(fuzzTargets, " ")) + s.PreallocateSlice(ctx, "ALL_FUZZ_TARGETS") } diff --git a/cc/fuzz_common.go b/cc/fuzz_common.go new file mode 100644 index 000000000..98ed7f4bc --- /dev/null +++ b/cc/fuzz_common.go @@ -0,0 +1,201 @@ +// 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 cc + +// This file contains the common code for compiling C/C++ and Rust fuzzers for Android. + +import ( + "sort" + "strings" + + "android/soong/android" +) + +type Lang string + +const ( + Cc Lang = "" + Rust Lang = "rust" +) + +type FuzzModule struct { + android.ModuleBase + android.DefaultableModuleBase + android.ApexModuleBase +} + +type FuzzPackager struct { + Packages android.Paths + FuzzTargets map[string]bool +} + +type FileToZip struct { + SourceFilePath android.Path + DestinationPathPrefix string +} + +type ArchOs struct { + HostOrTarget string + Arch string + Dir string +} + +type FuzzPackagedModule struct { + FuzzProperties FuzzProperties + Dictionary android.Path + Corpus android.Paths + CorpusIntermediateDir android.Path + Config android.Path + Data android.Paths + DataIntermediateDir android.Path +} + +func IsValid(fuzzModule FuzzModule) bool { + // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of + // fuzz targets we're going to package anyway. + if !fuzzModule.Enabled() || fuzzModule.InRamdisk() || fuzzModule.InVendorRamdisk() || fuzzModule.InRecovery() { + return false + } + + // Discard modules that are in an unavailable namespace. + if !fuzzModule.ExportedToMake() { + return false + } + + return true +} + +func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip { + // Package the corpora into a zipfile. + var files []FileToZip + if fuzzModule.Corpus != nil { + corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip") + command := builder.Command().BuiltTool("soong_zip"). + Flag("-j"). + FlagWithOutput("-o ", corpusZip) + rspFile := corpusZip.ReplaceExtension(ctx, "rsp") + command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.Corpus) + files = append(files, FileToZip{corpusZip, ""}) + } + + // Package the data into a zipfile. + if fuzzModule.Data != nil { + dataZip := archDir.Join(ctx, module.Name()+"_data.zip") + command := builder.Command().BuiltTool("soong_zip"). + FlagWithOutput("-o ", dataZip) + for _, f := range fuzzModule.Data { + intermediateDir := strings.TrimSuffix(f.String(), f.Rel()) + command.FlagWithArg("-C ", intermediateDir) + command.FlagWithInput("-f ", f) + } + files = append(files, FileToZip{dataZip, ""}) + } + + // The dictionary. + if fuzzModule.Dictionary != nil { + files = append(files, FileToZip{fuzzModule.Dictionary, ""}) + } + + // Additional fuzz config. + if fuzzModule.Config != nil { + files = append(files, FileToZip{fuzzModule.Config, ""}) + } + + return files +} + +func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) { + fuzzZip := archDir.Join(ctx, module.Name()+".zip") + + command := builder.Command().BuiltTool("soong_zip"). + Flag("-j"). + FlagWithOutput("-o ", fuzzZip) + + for _, file := range files { + if file.DestinationPathPrefix != "" { + command.FlagWithArg("-P ", file.DestinationPathPrefix) + } else { + command.Flag("-P ''") + } + command.FlagWithInput("-f ", file.SourceFilePath) + } + + builder.Build("create-"+fuzzZip.String(), + "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString) + + // Don't add modules to 'make haiku-rust' that are set to not be + // exported to the fuzzing infrastructure. + if config := fuzzModule.FuzzProperties.Fuzz_config; config != nil { + if strings.Contains(hostOrTargetString, "host") && !BoolDefault(config.Fuzz_on_haiku_host, true) { + return archDirs[archOs], false + } else if !BoolDefault(config.Fuzz_on_haiku_device, true) { + return archDirs[archOs], false + } + } + + s.FuzzTargets[module.Name()] = true + archDirs[archOs] = append(archDirs[archOs], FileToZip{fuzzZip, ""}) + + return archDirs[archOs], true +} + +func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, lang Lang) { + var archOsList []ArchOs + for archOs := range archDirs { + archOsList = append(archOsList, archOs) + } + sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].Dir < archOsList[j].Dir }) + + for _, archOs := range archOsList { + filesToZip := archDirs[archOs] + arch := archOs.Arch + hostOrTarget := archOs.HostOrTarget + builder := android.NewRuleBuilder(pctx, ctx) + zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip" + if lang == Rust { + zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip" + } + outputFile := android.PathForOutput(ctx, zipFileName) + + s.Packages = append(s.Packages, outputFile) + + command := builder.Command().BuiltTool("soong_zip"). + Flag("-j"). + FlagWithOutput("-o ", outputFile). + Flag("-L 0") // No need to try and re-compress the zipfiles. + + for _, fileToZip := range filesToZip { + + if fileToZip.DestinationPathPrefix != "" { + command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix) + } else { + command.Flag("-P ''") + } + command.FlagWithInput("-f ", fileToZip.SourceFilePath) + + } + builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget, + "Create fuzz target packages for "+arch+"-"+hostOrTarget) + } +} + +func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets string) { + fuzzTargets := make([]string, 0, len(s.FuzzTargets)) + for target, _ := range s.FuzzTargets { + fuzzTargets = append(fuzzTargets, target) + } + sort.Strings(fuzzTargets) + ctx.Strict(targets, strings.Join(fuzzTargets, " ")) +} diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index bdf0daeaf..1ce9911b8 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -579,25 +579,9 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android. // Create hidden API input structure. input := b.createHiddenAPIFlagInput(ctx, contents, fragments) - var output *HiddenAPIOutput - - // Hidden API processing is conditional as a temporary workaround as not all - // bootclasspath_fragments provide the appropriate information needed for hidden API processing - // which leads to breakages of the build. - // TODO(b/179354495): Stop hidden API processing being conditional once all bootclasspath_fragment - // modules have been updated to support it. - if input.canPerformHiddenAPIProcessing(ctx, b.properties) { - // Delegate the production of the hidden API all-flags.csv file to a module type specific method. - common := ctx.Module().(commonBootclasspathFragment) - output = common.produceHiddenAPIOutput(ctx, contents, input) - } else { - // As hidden API processing cannot be performed fall back to trying to retrieve the legacy - // encoded boot dex files, i.e. those files encoded by the individual libraries and returned - // from the DexJarBuildPath() method. - output = &HiddenAPIOutput{ - EncodedBootDexFilesByModule: retrieveLegacyEncodedBootDexFiles(ctx, contents), - } - } + // Delegate the production of the hidden API all-flags.csv file to a module type specific method. + common := ctx.Module().(commonBootclasspathFragment) + output := common.produceHiddenAPIOutput(ctx, contents, input) // Initialize a HiddenAPIInfo structure. hiddenAPIInfo := HiddenAPIInfo{ @@ -615,7 +599,7 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android. // The monolithic hidden API processing also needs access to all the output files produced by // hidden API processing of this fragment. - hiddenAPIInfo.HiddenAPIFlagOutput = (*output).HiddenAPIFlagOutput + hiddenAPIInfo.HiddenAPIFlagOutput = output.HiddenAPIFlagOutput // Provide it for use by other modules. ctx.SetProvider(HiddenAPIInfoProvider, hiddenAPIInfo) @@ -912,10 +896,10 @@ func (module *prebuiltBootclasspathFragmentModule) Name() string { // produceHiddenAPIOutput returns a path to the prebuilt all-flags.csv or nil if none is specified. func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput { - pathForOptionalSrc := func(src *string) android.Path { + pathForSrc := func(property string, src *string) android.Path { if src == nil { - // TODO(b/179354495): Fail if this is not provided once prebuilts have been updated. - return nil + ctx.PropertyErrorf(property, "is required but was not specified") + return android.PathForModuleSrc(ctx, "missing", property) } return android.PathForModuleSrc(ctx, *src) } @@ -926,11 +910,11 @@ func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an output := HiddenAPIOutput{ HiddenAPIFlagOutput: HiddenAPIFlagOutput{ - StubFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags), - AnnotationFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Annotation_flags), - MetadataPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Metadata), - IndexPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Index), - AllFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags), + AnnotationFlagsPath: pathForSrc("hidden_api.annotation_flags", module.prebuiltProperties.Hidden_api.Annotation_flags), + MetadataPath: pathForSrc("hidden_api.metadata", module.prebuiltProperties.Hidden_api.Metadata), + IndexPath: pathForSrc("hidden_api.index", module.prebuiltProperties.Hidden_api.Index), + StubFlagsPath: pathForSrc("hidden_api.stub_flags", module.prebuiltProperties.Hidden_api.Stub_flags), + AllFlagsPath: pathForSrc("hidden_api.all_flags", module.prebuiltProperties.Hidden_api.All_flags), }, EncodedBootDexFilesByModule: encodedBootDexJarsByModule, } diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index c4832d2f8..86ab8253e 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -20,7 +20,6 @@ import ( "android/soong/android" "github.com/google/blueprint" - "github.com/google/blueprint/proptools" ) // Contains support for processing hiddenAPI in a modular fashion. @@ -511,14 +510,6 @@ func (s FlagFilesByCategory) append(other FlagFilesByCategory) { } } -// dedup removes duplicates in the flag files, while maintaining the order in which they were -// appended. -func (s FlagFilesByCategory) dedup() { - for category, paths := range s { - s[category] = android.FirstUniquePaths(paths) - } -} - // HiddenAPIInfo contains information provided by the hidden API processing. // // That includes paths resolved from HiddenAPIFlagFileProperties and also generated by hidden API @@ -712,42 +703,6 @@ func newHiddenAPIFlagInput() HiddenAPIFlagInput { return input } -// canPerformHiddenAPIProcessing determines whether hidden API processing should be performed. -// -// A temporary workaround to avoid existing bootclasspath_fragments that do not provide the -// appropriate information needed for hidden API processing breaking the build. -// TODO(b/179354495): Remove this workaround. -func (i *HiddenAPIFlagInput) canPerformHiddenAPIProcessing(ctx android.ModuleContext, properties bootclasspathFragmentProperties) bool { - // Performing hidden API processing without stubs is not supported and it is unlikely to ever be - // required as the whole point of adding something to the bootclasspath fragment is to add it to - // the bootclasspath in order to be used by something else in the system. Without any stubs it - // cannot do that. - if len(i.StubDexJarsByScope) == 0 { - return false - } - - // Hidden API processing is always enabled in tests. - if ctx.Config().TestProductVariables != nil { - return true - } - - // A module that has fragments should have access to the information it needs in order to perform - // hidden API processing. - if len(properties.Fragments) != 0 { - return true - } - - // The art bootclasspath fragment does not depend on any other fragments but already supports - // hidden API processing. - imageName := proptools.String(properties.Image_name) - if imageName == "art" { - return true - } - - // Disable it for everything else. - return false -} - // gatherStubLibInfo gathers information from the stub libs needed by hidden API processing from the // dependencies added in hiddenAPIAddStubLibDependencies. // diff --git a/java/hiddenapi_monolithic.go b/java/hiddenapi_monolithic.go index 52f0770f3..404b4c133 100644 --- a/java/hiddenapi_monolithic.go +++ b/java/hiddenapi_monolithic.go @@ -58,68 +58,33 @@ func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory F // Merge all the information from the classpathElements. The fragments form a DAG so it is possible that // this will introduce duplicates so they will be resolved after processing all the classpathElements. for _, element := range classpathElements { - var classesJars android.Paths switch e := element.(type) { case *ClasspathLibraryElement: - classesJars = retrieveClassesJarsFromModule(e.Module()) + classesJars := retrieveClassesJarsFromModule(e.Module()) + monolithicInfo.ClassesJars = append(monolithicInfo.ClassesJars, classesJars...) case *ClasspathFragmentElement: fragment := e.Module() if ctx.OtherModuleHasProvider(fragment, HiddenAPIInfoProvider) { info := ctx.OtherModuleProvider(fragment, HiddenAPIInfoProvider).(HiddenAPIInfo) monolithicInfo.append(&info) - - // If the bootclasspath fragment actually perform hidden API processing itself then use the - // CSV files it provides and do not bother processing the classesJars files. This ensures - // consistent behavior between source and prebuilt as prebuilt modules do not provide - // classesJars. - if info.AllFlagsPath != nil { - continue - } + } else { + ctx.ModuleErrorf("%s does not provide hidden API information", fragment) } - - classesJars = extractClassesJarsFromModules(e.Contents) } - - monolithicInfo.ClassesJars = append(monolithicInfo.ClassesJars, classesJars...) } - // Dedup paths. - monolithicInfo.dedup() - return monolithicInfo } // append appends all the files from the supplied info to the corresponding files in this struct. func (i *MonolithicHiddenAPIInfo) append(other *HiddenAPIInfo) { i.FlagsFilesByCategory.append(other.FlagFilesByCategory) - - // The output may not be set if the bootclasspath_fragment has not yet been updated to support - // hidden API processing. - // TODO(b/179354495): Switch back to append once all bootclasspath_fragment modules have been - // updated to support hidden API processing properly. - appendIfNotNil := func(paths android.Paths, path android.Path) android.Paths { - if path == nil { - return paths - } - return append(paths, path) - } - i.StubFlagsPaths = appendIfNotNil(i.StubFlagsPaths, other.StubFlagsPath) - i.AnnotationFlagsPaths = appendIfNotNil(i.AnnotationFlagsPaths, other.AnnotationFlagsPath) - i.MetadataPaths = appendIfNotNil(i.MetadataPaths, other.MetadataPath) - i.IndexPaths = appendIfNotNil(i.IndexPaths, other.IndexPath) - i.AllFlagsPaths = appendIfNotNil(i.AllFlagsPaths, other.AllFlagsPath) -} - -// dedup removes duplicates in all the paths, while maintaining the order in which they were -// appended. -func (i *MonolithicHiddenAPIInfo) dedup() { - i.FlagsFilesByCategory.dedup() - i.StubFlagsPaths = android.FirstUniquePaths(i.StubFlagsPaths) - i.AnnotationFlagsPaths = android.FirstUniquePaths(i.AnnotationFlagsPaths) - i.MetadataPaths = android.FirstUniquePaths(i.MetadataPaths) - i.IndexPaths = android.FirstUniquePaths(i.IndexPaths) - i.AllFlagsPaths = android.FirstUniquePaths(i.AllFlagsPaths) + i.StubFlagsPaths = append(i.StubFlagsPaths, other.StubFlagsPath) + i.AnnotationFlagsPaths = append(i.AnnotationFlagsPaths, other.AnnotationFlagsPath) + i.MetadataPaths = append(i.MetadataPaths, other.MetadataPath) + i.IndexPaths = append(i.IndexPaths, other.IndexPath) + i.AllFlagsPaths = append(i.AllFlagsPaths, other.AllFlagsPath) } var MonolithicHiddenAPIInfoProvider = blueprint.NewProvider(MonolithicHiddenAPIInfo{}) diff --git a/java/java.go b/java/java.go index 83e9fe1cb..e38a7143b 100644 --- a/java/java.go +++ b/java/java.go @@ -130,11 +130,19 @@ var ( PropertyName: "java_boot_libs", SupportsSdk: true, }, - // Temporarily export implementation classes jar for java_boot_libs as it is required for the - // hiddenapi processing. - // TODO(b/179354495): Revert once hiddenapi processing has been modularized. - exportImplementationClassesJar, - sdkSnapshotFilePathForJar, + func(ctx android.SdkMemberContext, j *Library) android.Path { + // Java boot libs are only provided in the SDK to provide access to their dex implementation + // jar for use by dexpreopting and boot jars package check. They do not need to provide an + // actual implementation jar but the java_import will need a file that exists so just copy an + // empty file. Any attempt to use that file as a jar will cause a build error. + return ctx.SnapshotBuilder().EmptyFile() + }, + func(osPrefix, name string) string { + // Create a special name for the implementation jar to try and provide some useful information + // to a developer that attempts to compile against this. + // TODO(b/175714559): Provide a proper error message in Soong not ninja. + return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) + }, onlyCopyJarToSnapshot, } diff --git a/java/sdk_library.go b/java/sdk_library.go index d1b4a4727..268e7970d 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -981,13 +981,15 @@ func (e *EmbeddableSdkLibraryComponent) SdkLibraryName() *string { } // to satisfy SdkLibraryComponentDependency -func (e *EmbeddableSdkLibraryComponent) OptionalImplicitSdkLibrary() *string { - return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack -} - -// to satisfy SdkLibraryComponentDependency func (e *EmbeddableSdkLibraryComponent) OptionalSdkLibraryImplementation() *string { - // Currently implementation library name is the same as the SDK library name. + // For shared libraries, this is the same as the SDK library name. If a Java library or app + // depends on a component library (e.g. a stub library) it still needs to know the name of the + // run-time library and the corresponding module that provides the implementation. This name is + // passed to manifest_fixer (to be added to AndroidManifest.xml) and added to CLC (to be used + // in dexpreopt). + // + // For non-shared SDK (component or not) libraries this returns `nil`, as they are not + // <uses-library> and should not be added to the manifest or to CLC. return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack } @@ -999,12 +1001,6 @@ type SdkLibraryComponentDependency interface { // SdkLibraryName returns the name of the java_sdk_library/_import module. SdkLibraryName() *string - // The optional name of the sdk library that should be implicitly added to the - // AndroidManifest of an app that contains code which references the sdk library. - // - // Returns the name of the optional implicit SDK library or nil, if there isn't one. - OptionalImplicitSdkLibrary() *string - // The name of the implementation library for the optional SDK library or nil, if there isn't one. OptionalSdkLibraryImplementation() *string } diff --git a/rust/androidmk.go b/rust/androidmk.go index ea45ebd01..630805a85 100644 --- a/rust/androidmk.go +++ b/rust/androidmk.go @@ -205,24 +205,24 @@ func (fuzz *fuzzDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *andro ctx.SubAndroidMk(entries, fuzz.binaryDecorator) var fuzzFiles []string - for _, d := range fuzz.corpus { + for _, d := range fuzz.fuzzPackagedModule.Corpus { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.corpusIntermediateDir.String())+":corpus/"+d.Base()) + filepath.Dir(fuzz.fuzzPackagedModule.CorpusIntermediateDir.String())+":corpus/"+d.Base()) } - for _, d := range fuzz.data { + for _, d := range fuzz.fuzzPackagedModule.Data { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.dataIntermediateDir.String())+":data/"+d.Rel()) + filepath.Dir(fuzz.fuzzPackagedModule.DataIntermediateDir.String())+":data/"+d.Rel()) } - if fuzz.dictionary != nil { + if fuzz.fuzzPackagedModule.Dictionary != nil { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.dictionary.String())+":"+fuzz.dictionary.Base()) + filepath.Dir(fuzz.fuzzPackagedModule.Dictionary.String())+":"+fuzz.fuzzPackagedModule.Dictionary.Base()) } - if fuzz.config != nil { + if fuzz.fuzzPackagedModule.Config != nil { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.config.String())+":config.json") + filepath.Dir(fuzz.fuzzPackagedModule.Config.String())+":config.json") } entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, diff --git a/rust/fuzz.go b/rust/fuzz.go index 7e1c55a50..18b25130f 100644 --- a/rust/fuzz.go +++ b/rust/fuzz.go @@ -32,13 +32,7 @@ func init() { type fuzzDecorator struct { *binaryDecorator - Properties cc.FuzzProperties - dictionary android.Path - corpus android.Paths - corpusIntermediateDir android.Path - config android.Path - data android.Paths - dataIntermediateDir android.Path + fuzzPackagedModule cc.FuzzPackagedModule } var _ compiler = (*binaryDecorator)(nil) @@ -88,7 +82,7 @@ func (fuzzer *fuzzDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { func (fuzzer *fuzzDecorator) compilerProps() []interface{} { return append(fuzzer.binaryDecorator.compilerProps(), - &fuzzer.Properties) + &fuzzer.fuzzPackagedModule.FuzzProperties) } func (fuzzer *fuzzDecorator) stdLinkage(ctx *depsContext) RustLinkage { @@ -102,32 +96,19 @@ func (fuzzer *fuzzDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep // Responsible for generating GNU Make rules that package fuzz targets into // their architecture & target/host specific zip file. type rustFuzzPackager struct { - packages android.Paths - fuzzTargets map[string]bool + cc.FuzzPackager } func rustFuzzPackagingFactory() android.Singleton { return &rustFuzzPackager{} } -type fileToZip struct { - SourceFilePath android.Path - DestinationPathPrefix string -} - -type archOs struct { - hostOrTarget string - arch string - dir string -} - func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { - // Map between each architecture + host/device combination. - archDirs := make(map[archOs][]fileToZip) + archDirs := make(map[cc.ArchOs][]cc.FileToZip) // List of individual fuzz targets. - s.fuzzTargets = make(map[string]bool) + s.FuzzTargets = make(map[string]bool) ctx.VisitAllModules(func(module android.Module) { // Discard non-fuzz targets. @@ -136,20 +117,12 @@ func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { return } - fuzzModule, ok := rustModule.compiler.(*fuzzDecorator) - if !ok { + if ok := cc.IsValid(rustModule.FuzzModule); !ok || rustModule.Properties.PreventInstall { return } - // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of - // fuzz targets we're going to package anyway. - if !rustModule.Enabled() || rustModule.Properties.PreventInstall || - rustModule.InRamdisk() || rustModule.InVendorRamdisk() || rustModule.InRecovery() { - return - } - - // Discard modules that are in an unavailable namespace. - if !rustModule.ExportedToMake() { + fuzzModule, ok := rustModule.compiler.(*fuzzDecorator) + if !ok { return } @@ -160,126 +133,34 @@ func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { archString := rustModule.Arch().ArchType.String() archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString) - archOs := archOs{hostOrTarget: hostOrTargetString, arch: archString, dir: archDir.String()} + archOs := cc.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()} - var files []fileToZip + var files []cc.FileToZip builder := android.NewRuleBuilder(pctx, ctx) - // Package the corpora into a zipfile. - if fuzzModule.corpus != nil { - corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip") - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", corpusZip) - rspFile := corpusZip.ReplaceExtension(ctx, "rsp") - command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.corpus) - files = append(files, fileToZip{corpusZip, ""}) - } - - // Package the data into a zipfile. - if fuzzModule.data != nil { - dataZip := archDir.Join(ctx, module.Name()+"_data.zip") - command := builder.Command().BuiltTool("soong_zip"). - FlagWithOutput("-o ", dataZip) - for _, f := range fuzzModule.data { - intermediateDir := strings.TrimSuffix(f.String(), f.Rel()) - command.FlagWithArg("-C ", intermediateDir) - command.FlagWithInput("-f ", f) - } - files = append(files, fileToZip{dataZip, ""}) - } + // Package the artifacts (data, corpus, config and dictionary into a zipfile. + files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder) // The executable. - files = append(files, fileToZip{rustModule.unstrippedOutputFile.Path(), ""}) - - // The dictionary. - if fuzzModule.dictionary != nil { - files = append(files, fileToZip{fuzzModule.dictionary, ""}) - } + files = append(files, cc.FileToZip{rustModule.unstrippedOutputFile.Path(), ""}) - // Additional fuzz config. - if fuzzModule.config != nil { - files = append(files, fileToZip{fuzzModule.config, ""}) - } - - fuzzZip := archDir.Join(ctx, module.Name()+".zip") - - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", fuzzZip) - - for _, file := range files { - if file.DestinationPathPrefix != "" { - command.FlagWithArg("-P ", file.DestinationPathPrefix) - } else { - command.Flag("-P ''") - } - command.FlagWithInput("-f ", file.SourceFilePath) - } - - builder.Build("create-"+fuzzZip.String(), - "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString) - - // Don't add modules to 'make haiku-rust' that are set to not be - // exported to the fuzzing infrastructure. - if config := fuzzModule.Properties.Fuzz_config; config != nil { - if rustModule.Host() && !BoolDefault(config.Fuzz_on_haiku_host, true) { - return - } else if !BoolDefault(config.Fuzz_on_haiku_device, true) { - return - } + archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs) + if !ok { + return } - s.fuzzTargets[module.Name()] = true - archDirs[archOs] = append(archDirs[archOs], fileToZip{fuzzZip, ""}) }) - - var archOsList []archOs - for archOs := range archDirs { - archOsList = append(archOsList, archOs) - } - sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].dir < archOsList[j].dir }) - - for _, archOs := range archOsList { - filesToZip := archDirs[archOs] - arch := archOs.arch - hostOrTarget := archOs.hostOrTarget - builder := android.NewRuleBuilder(pctx, ctx) - outputFile := android.PathForOutput(ctx, "fuzz-rust-"+hostOrTarget+"-"+arch+".zip") - s.packages = append(s.packages, outputFile) - - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", outputFile). - Flag("-L 0") // No need to try and re-compress the zipfiles. - - for _, fileToZip := range filesToZip { - if fileToZip.DestinationPathPrefix != "" { - command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix) - } else { - command.Flag("-P ''") - } - command.FlagWithInput("-f ", fileToZip.SourceFilePath) - } - builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget, - "Create fuzz target packages for "+arch+"-"+hostOrTarget) - } - + s.CreateFuzzPackage(ctx, archDirs, cc.Rust) } func (s *rustFuzzPackager) MakeVars(ctx android.MakeVarsContext) { - packages := s.packages.Strings() + packages := s.Packages.Strings() sort.Strings(packages) ctx.Strict("SOONG_RUST_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " ")) - // Preallocate the slice of fuzz targets to minimise memory allocations. - fuzzTargets := make([]string, 0, len(s.fuzzTargets)) - for target, _ := range s.fuzzTargets { - fuzzTargets = append(fuzzTargets, target) - } - sort.Strings(fuzzTargets) - ctx.Strict("ALL_RUST_FUZZ_TARGETS", strings.Join(fuzzTargets, " ")) + // Preallocate the slice of fuzz targets to minimize memory allocations. + s.PreallocateSlice(ctx, "ALL_RUST_FUZZ_TARGETS") } func (fuzz *fuzzDecorator) install(ctx ModuleContext) { @@ -289,13 +170,13 @@ func (fuzz *fuzzDecorator) install(ctx ModuleContext) { "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzz.binaryDecorator.baseCompiler.install(ctx) - if fuzz.Properties.Corpus != nil { - fuzz.corpus = android.PathsForModuleSrc(ctx, fuzz.Properties.Corpus) + if fuzz.fuzzPackagedModule.FuzzProperties.Corpus != nil { + fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus) } - if fuzz.Properties.Data != nil { - fuzz.data = android.PathsForModuleSrc(ctx, fuzz.Properties.Data) + if fuzz.fuzzPackagedModule.FuzzProperties.Data != nil { + fuzz.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Data) } - if fuzz.Properties.Dictionary != nil { - fuzz.dictionary = android.PathForModuleSrc(ctx, *fuzz.Properties.Dictionary) + if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil { + fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary) } } diff --git a/rust/library.go b/rust/library.go index d5ab1a477..8c10e298b 100644 --- a/rust/library.go +++ b/rust/library.go @@ -432,6 +432,12 @@ func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string { func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName()) + if library.dylib() { + // We need to add a dependency on std in order to link crates as dylibs. + // The hack to add this dependency is guarded by the following cfg so + // that we don't force a dependency when it isn't needed. + library.baseCompiler.Properties.Cfgs = append(library.baseCompiler.Properties.Cfgs, "android_dylib") + } flags = library.baseCompiler.compilerFlags(ctx, flags) if library.shared() || library.static() { library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...) diff --git a/rust/library_test.go b/rust/library_test.go index 54cd2a5b3..cb4ef7eec 100644 --- a/rust/library_test.go +++ b/rust/library_test.go @@ -85,6 +85,22 @@ func TestDylibPreferDynamic(t *testing.T) { } } +// Check that we are passing the android_dylib config flag +func TestAndroidDylib(t *testing.T) { + ctx := testRust(t, ` + rust_library_host_dylib { + name: "libfoo", + srcs: ["foo.rs"], + crate_name: "foo", + }`) + + libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Output("libfoo.dylib.so") + + if !strings.Contains(libfooDylib.Args["rustcFlags"], "--cfg 'android_dylib'") { + t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"]) + } +} + func TestValidateLibraryStem(t *testing.T) { testRustError(t, "crate_name must be defined.", ` rust_library_host { diff --git a/rust/rust.go b/rust/rust.go index 38f1742d4..52b409435 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -119,9 +119,7 @@ type BaseProperties struct { } type Module struct { - android.ModuleBase - android.DefaultableModuleBase - android.ApexModuleBase + cc.FuzzModule VendorProperties cc.VendorProperties diff --git a/scripts/hiddenapi/Android.bp b/scripts/hiddenapi/Android.bp index 7472f528b..c50dc24fd 100644 --- a/scripts/hiddenapi/Android.bp +++ b/scripts/hiddenapi/Android.bp @@ -48,6 +48,27 @@ python_binary_host { }, } +python_test_host { + name: "generate_hiddenapi_lists_test", + main: "generate_hiddenapi_lists_test.py", + srcs: [ + "generate_hiddenapi_lists.py", + "generate_hiddenapi_lists_test.py", + ], + version: { + py2: { + enabled: false, + }, + py3: { + enabled: true, + embedded_launcher: true, + }, + }, + test_options: { + unit_test: true, + }, +} + python_binary_host { name: "verify_overlaps", main: "verify_overlaps.py", diff --git a/scripts/hiddenapi/generate_hiddenapi_lists_test.py b/scripts/hiddenapi/generate_hiddenapi_lists_test.py index ff3d70881..b81424b7a 100755 --- a/scripts/hiddenapi/generate_hiddenapi_lists_test.py +++ b/scripts/hiddenapi/generate_hiddenapi_lists_test.py @@ -101,4 +101,4 @@ class TestHiddenapiListGeneration(unittest.TestCase): self.assertEqual(extract_package(signature), expected_package) if __name__ == '__main__': - unittest.main() + unittest.main(verbosity=2) diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go index 1d2ab4218..efd2b5bd9 100644 --- a/sdk/bootclasspath_fragment_sdk_test.go +++ b/sdk/bootclasspath_fragment_sdk_test.go @@ -133,6 +133,13 @@ prebuilt_bootclasspath_fragment { apex_available: ["com.android.art"], image_name: "art", contents: ["mybootlib"], + hidden_api: { + stub_flags: "hiddenapi/stub-flags.csv", + annotation_flags: "hiddenapi/annotation-flags.csv", + metadata: "hiddenapi/metadata.csv", + index: "hiddenapi/index.csv", + all_flags: "hiddenapi/all-flags.csv", + }, } java_import { @@ -140,7 +147,7 @@ java_import { prefer: false, visibility: ["//visibility:public"], apex_available: ["com.android.art"], - jars: ["java/mybootlib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"], } `), checkVersionedAndroidBpContents(` @@ -153,6 +160,13 @@ prebuilt_bootclasspath_fragment { apex_available: ["com.android.art"], image_name: "art", contents: ["mysdk_mybootlib@current"], + hidden_api: { + stub_flags: "hiddenapi/stub-flags.csv", + annotation_flags: "hiddenapi/annotation-flags.csv", + metadata: "hiddenapi/metadata.csv", + index: "hiddenapi/index.csv", + all_flags: "hiddenapi/all-flags.csv", + }, } java_import { @@ -160,7 +174,7 @@ java_import { sdk_member_name: "mybootlib", visibility: ["//visibility:public"], apex_available: ["com.android.art"], - jars: ["java/mybootlib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"], } sdk_snapshot { @@ -171,8 +185,13 @@ sdk_snapshot { } `), checkAllCopyRules(` -.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar -`), +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv +.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar + `), snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot), // Check the behavior of the snapshot without the source. @@ -326,7 +345,7 @@ java_import { prefer: false, visibility: ["//visibility:public"], apex_available: ["myapex"], - jars: ["java/mybootlib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"], permitted_packages: ["mybootlib"], } @@ -410,7 +429,7 @@ java_import { sdk_member_name: "mybootlib", visibility: ["//visibility:public"], apex_available: ["myapex"], - jars: ["java/mybootlib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"], permitted_packages: ["mybootlib"], } @@ -480,7 +499,7 @@ sdk_snapshot { .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv -.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar +.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar .intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt @@ -832,7 +851,7 @@ java_import { prefer: false, visibility: ["//visibility:public"], apex_available: ["myapex"], - jars: ["java/mybootlib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"], permitted_packages: ["mybootlib"], } @@ -867,7 +886,7 @@ my-unsupported-packages.txt -> hiddenapi/my-unsupported-packages.txt .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv -.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar +.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar .intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar .intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt .intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 813dcfd6d..9efb3a49a 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -453,7 +453,7 @@ java_import { prefer: false, visibility: ["//visibility:public"], apex_available: ["//apex_available:platform"], - jars: ["java/myjavalib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar"], permitted_packages: ["pkg.myjavalib"], } `), @@ -465,7 +465,7 @@ java_import { sdk_member_name: "myjavalib", visibility: ["//visibility:public"], apex_available: ["//apex_available:platform"], - jars: ["java/myjavalib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar"], permitted_packages: ["pkg.myjavalib"], } @@ -474,9 +474,10 @@ module_exports_snapshot { visibility: ["//visibility:public"], java_boot_libs: ["myexports_myjavalib@current"], } + `), checkAllCopyRules(` -.intermediates/myjavalib/android_common/withres/myjavalib.jar -> java/myjavalib.jar +.intermediates/myexports/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar `), ) } diff --git a/sdk/update.go b/sdk/update.go index 6da3756be..3ec1bfaf4 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -1029,6 +1029,9 @@ type snapshotBuilder struct { filesToZip android.Paths zipsToMerge android.Paths + // The path to an empty file. + emptyFile android.WritablePath + prebuiltModules map[string]*bpModule prebuiltOrder []*bpModule @@ -1079,6 +1082,19 @@ func (s *snapshotBuilder) UnzipToSnapshot(zipPath android.Path, destDir string) s.zipsToMerge = append(s.zipsToMerge, tmpZipPath) } +func (s *snapshotBuilder) EmptyFile() android.Path { + if s.emptyFile == nil { + ctx := s.ctx + s.emptyFile = android.PathForModuleOut(ctx, "empty") + s.ctx.Build(pctx, android.BuildParams{ + Rule: android.Touch, + Output: s.emptyFile, + }) + } + + return s.emptyFile +} + func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType string) android.BpModule { name := member.Name() if s.prebuiltModules[name] != nil { |