diff options
55 files changed, 965 insertions, 448 deletions
@@ -26,8 +26,6 @@ review request is enough. For more substantial changes, file a bug in our [bug tracker](https://issuetracker.google.com/issues/new?component=381517) or or write us at android-building@googlegroups.com . -For Googlers, see our [internal documentation](http://go/soong). - ## Android.bp file format By design, Android.bp files are very simple. There are no conditionals or diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index e82e754ae..e954b3103 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -79,6 +79,7 @@ var ( "build/soong/scripts": Bp2BuildDefaultTrueRecursively, "cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively, + "cts/libs/json": Bp2BuildDefaultTrueRecursively, "dalvik/tools/dexdeps": Bp2BuildDefaultTrueRecursively, @@ -127,6 +128,7 @@ var ( "external/auto/android-annotation-stubs": Bp2BuildDefaultTrueRecursively, "external/auto/common": Bp2BuildDefaultTrueRecursively, "external/auto/service": Bp2BuildDefaultTrueRecursively, + "external/auto/value": Bp2BuildDefaultTrueRecursively, "external/boringssl": Bp2BuildDefaultTrueRecursively, "external/bouncycastle": Bp2BuildDefaultTrue, "external/brotli": Bp2BuildDefaultTrue, @@ -222,6 +224,8 @@ var ( "frameworks/av/media/module/foundation": Bp2BuildDefaultTrueRecursively, "frameworks/av/media/module/minijail": Bp2BuildDefaultTrueRecursively, "frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively, + "frameworks/base/apex/jobscheduler/service/jni": Bp2BuildDefaultTrueRecursively, + "frameworks/base/core/java": Bp2BuildDefaultTrue, "frameworks/base/libs/androidfw": Bp2BuildDefaultTrue, "frameworks/base/libs/services": Bp2BuildDefaultTrue, "frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue, @@ -232,17 +236,21 @@ var ( "frameworks/base/tools/aapt": Bp2BuildDefaultTrue, "frameworks/base/tools/aapt2": Bp2BuildDefaultTrue, "frameworks/base/tools/codegen": Bp2BuildDefaultTrueRecursively, + "frameworks/base/tools/locked_region_code_injection": Bp2BuildDefaultTrueRecursively, "frameworks/base/tools/streaming_proto": Bp2BuildDefaultTrueRecursively, "frameworks/hardware/interfaces/stats/aidl": Bp2BuildDefaultTrue, "frameworks/libs/modules-utils/build": Bp2BuildDefaultTrueRecursively, + "frameworks/libs/modules-utils/java": Bp2BuildDefaultTrue, "frameworks/libs/net/common/native": Bp2BuildDefaultTrueRecursively, // TODO(b/296014682): Remove this path "frameworks/native": Bp2BuildDefaultTrue, "frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively, "frameworks/native/libs/arect": Bp2BuildDefaultTrueRecursively, + "frameworks/native/libs/binder": Bp2BuildDefaultTrue, "frameworks/native/libs/gui": Bp2BuildDefaultTrue, "frameworks/native/libs/math": Bp2BuildDefaultTrueRecursively, "frameworks/native/libs/nativebase": Bp2BuildDefaultTrueRecursively, "frameworks/native/libs/permission": Bp2BuildDefaultTrueRecursively, + "frameworks/native/libs/ui": Bp2BuildDefaultTrue, "frameworks/native/libs/vr": Bp2BuildDefaultTrueRecursively, "frameworks/native/opengl/tests/gl2_cameraeye": Bp2BuildDefaultTrue, "frameworks/native/opengl/tests/gl2_java": Bp2BuildDefaultTrue, @@ -369,6 +377,7 @@ var ( "system/core/mkbootfs": Bp2BuildDefaultTrueRecursively, "system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively, "system/core/property_service/libpropertyinfoserializer": Bp2BuildDefaultTrueRecursively, + "system/core/trusty/libtrusty": Bp2BuildDefaultTrue, "system/extras/f2fs_utils": Bp2BuildDefaultTrueRecursively, "system/extras/toolchain-extras": Bp2BuildDefaultTrue, "system/extras/verity": Bp2BuildDefaultTrueRecursively, @@ -377,6 +386,7 @@ var ( "system/libartpalette": Bp2BuildDefaultTrueRecursively, "system/libbase": Bp2BuildDefaultTrueRecursively, "system/libfmq": Bp2BuildDefaultTrue, + "system/libhidl": Bp2BuildDefaultTrue, "system/libhidl/libhidlmemory": Bp2BuildDefaultTrue, "system/libhidl/transport": Bp2BuildDefaultTrue, "system/libhidl/transport/allocator/1.0": Bp2BuildDefaultTrue, @@ -417,12 +427,13 @@ var ( "system/tools/xsdc/utils": Bp2BuildDefaultTrueRecursively, "system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively, - "tools/apifinder": Bp2BuildDefaultTrue, - "tools/apksig": Bp2BuildDefaultTrue, - "tools/external_updater": Bp2BuildDefaultTrueRecursively, - "tools/metalava": Bp2BuildDefaultTrueRecursively, - "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively, - "tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively, + "tools/apifinder": Bp2BuildDefaultTrue, + "tools/apksig": Bp2BuildDefaultTrue, + "tools/external_updater": Bp2BuildDefaultTrueRecursively, + "tools/metalava": Bp2BuildDefaultTrueRecursively, + "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively, + "tools/platform-compat/java/androidprocessor": Bp2BuildDefaultTrueRecursively, + "tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively, } Bp2buildKeepExistingBuildFile = map[string]bool{ @@ -545,6 +556,7 @@ var ( "remote-color-resources-compile-colors", // framework-minus-apex + "ImmutabilityAnnotationProcessor", "android.mime.types.minimized", "debian.mime.types.minimized", "framework-javastream-protos", @@ -554,10 +566,8 @@ var ( "apache-commons-math", "cbor-java", "icu4j_calendar_astronomer", - "json", "remote-color-resources-compile-public", "statslog-art-java-gen", - "statslog-framework-java-gen", "AndroidCommonLint", "ImmutabilityAnnotation", @@ -590,10 +600,6 @@ var ( "libandroid_runtime_lazy", "libandroid_runtime_vm_headers", "libaudioclient_aidl_conversion_util", - "libbinder", - "libbinder_device_interface_sources", - "libbinder_aidl", - "libbinder_headers", "libbinder_headers_platform_shared", "libbinderthreadstateutils", "libbluetooth-types-header", @@ -626,9 +632,6 @@ var ( "libtextclassifier_hash_static", "libtflite_kernel_utils", "libtinyxml2", - "libui", - "libui-types", - "libui_headers", "libvorbisidec", "media_ndk_headers", "media_plugin_headers", @@ -636,8 +639,6 @@ var ( "mediaswcodec.xml", "neuralnetworks_types", "libneuralnetworks_common", - // packagemanager_aidl_interface is created implicitly in packagemanager_aidl module - "packagemanager_aidl_interface", "philox_random", "philox_random_headers", "server_configurable_flags", @@ -679,9 +680,6 @@ var ( //external/fec "libfec_rs", - //frameworks/base/core/java - "IDropBoxManagerService_aidl", - //system/extras/ext4_utils "libext4_utils", "mke2fs_conf", @@ -702,10 +700,6 @@ var ( "car-ui-androidx-lifecycle-common-nodeps", "car-ui-androidx-constraintlayout-solver-nodeps", - //system/libhidl - "libhidlbase", // needed by cc_hidl_library - "libhidl_gtest_helper", - //frameworks/native/libs/input "inputconstants_aidl", @@ -714,11 +708,6 @@ var ( "libusb", - // needed by liblogd - "ILogcatManagerService_aidl", - "libincremental_aidl-cpp", - "incremental_aidl", - //frameworks/native/cmds/cmd "libcmd", @@ -864,11 +853,6 @@ var ( "aidl", "libaidl-common", - // java_resources containing only a single filegroup - "libauto_value_plugin", - "auto_value_plugin_resources", - "auto_value_extension", - // Used by xsd_config "xsdc", @@ -919,6 +903,7 @@ var ( "aidl_interface_headers", "bpf", "combined_apis", + "droiddoc_exported_dir", "license", "linker_config", "java_import", @@ -1001,7 +986,6 @@ var ( "conscrypt-for-host", // TODO(b/210751803), we don't handle path property for filegroups "host-libprotobuf-java-full", // TODO(b/210751803), we don't handle path property for filegroups "libprotobuf-internal-python-srcs", // TODO(b/210751803), we don't handle path property for filegroups - "libprotobuf-java-full", // TODO(b/210751803), we don't handle path property for filegroups "libprotobuf-java-util-full", // TODO(b/210751803), we don't handle path property for filegroups // go deps: @@ -1014,15 +998,15 @@ var ( "libtombstoned_client_rust_bridge_code", "libtombstoned_client_wrapper", // rust conversions are not supported // unconverted deps - "apexer_with_DCLA_preprocessing_test", // depends on unconverted modules: apexer_test_host_tools, com.android.example.apex + "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib "adb", // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi "android_icu4j_srcgen", // depends on unconverted modules: currysrc "android_icu4j_srcgen_binary", // depends on unconverted modules: android_icu4j_srcgen, currysrc "apex_compression_test", // depends on unconverted modules: soong_zip, com.android.example.apex "apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full + "apexer_with_DCLA_preprocessing_test", // depends on unconverted modules: apexer_test_host_tools, com.android.example.apex "art-script", // depends on unconverted modules: dalvikvm, dex2oat "bin2c_fastdeployagent", // depends on unconverted modules: deployagent - "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib "com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig "currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9 "dex2oat-script", // depends on unconverted modules: dex2oat @@ -1032,12 +1016,12 @@ var ( "jacoco-stubs", // b/245767077, depends on droidstubs "libapexutil", // depends on unconverted modules: apex-info-list-tinyxml "libart", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support + "libart-runtime", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support + "libart-runtime-for-test", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support "libart-runtime-gtest", // depends on unconverted modules: libgtest_isolated, libart-compiler, libdexfile, libprofile, libartbase, libartbase-art-gtest "libart_headers", // depends on unconverted modules: art_libartbase_headers "libartbase-art-gtest", // depends on unconverted modules: libgtest_isolated, libart, libart-compiler, libdexfile, libprofile "libartbased-art-gtest", // depends on unconverted modules: libgtest_isolated, libartd, libartd-compiler, libdexfiled, libprofiled - "libart-runtime", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support - "libart-runtime-for-test", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support "libartd", // depends on unconverted modules: art_operator_srcs, libcpu_features, libodrstatslog, libelffiled, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfiled, libnativebridge, libnativeloader, libsigchain, libartbased, libprofiled, cpp-define-generator-asm-support, apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api "libartd-runtime", // depends on unconverted modules: art_operator_srcs, libcpu_features, libodrstatslog, libelffiled, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfiled, libnativebridge, libnativeloader, libsigchain, libartbased, libprofiled, cpp-define-generator-asm-support, apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api "libartd-runtime-gtest", // depends on unconverted modules: libgtest_isolated, libartd-compiler, libdexfiled, libprofiled, libartbased, libartbased-art-gtest @@ -1645,6 +1629,16 @@ var ( // Depends on the module defined in the directory not bp2build default allowed "ota_from_raw_img", + + // TODO(b/299924782): Fix linking error + "libbinder_on_trusty_mock", + + // TODO(b/299943581): Depends on aidl filegroups with implicit headers + "libdataloader_aidl-cpp", + "libincremental_manager_aidl-cpp", + + // TODO(b/299974637) Fix linking error + "libbinder_rpc_unstable", } // Bazel prod-mode allowlist. Modules in this list are built by Bazel diff --git a/android/variable.go b/android/variable.go index 02eff25f9..524cdf75c 100644 --- a/android/variable.go +++ b/android/variable.go @@ -438,16 +438,17 @@ type ProductVariables struct { ShippingApiLevel *string `json:",omitempty"` - BuildBrokenPluginValidation []string `json:",omitempty"` - BuildBrokenClangAsFlags bool `json:",omitempty"` - BuildBrokenClangCFlags bool `json:",omitempty"` - BuildBrokenClangProperty bool `json:",omitempty"` - GenruleSandboxing *bool `json:",omitempty"` - BuildBrokenEnforceSyspropOwner bool `json:",omitempty"` - BuildBrokenTrebleSyspropNeverallow bool `json:",omitempty"` - BuildBrokenUsesSoongPython2Modules bool `json:",omitempty"` - BuildBrokenVendorPropertyNamespace bool `json:",omitempty"` - BuildBrokenInputDirModules []string `json:",omitempty"` + BuildBrokenPluginValidation []string `json:",omitempty"` + BuildBrokenClangAsFlags bool `json:",omitempty"` + BuildBrokenClangCFlags bool `json:",omitempty"` + BuildBrokenClangProperty bool `json:",omitempty"` + GenruleSandboxing *bool `json:",omitempty"` + BuildBrokenEnforceSyspropOwner bool `json:",omitempty"` + BuildBrokenTrebleSyspropNeverallow bool `json:",omitempty"` + BuildBrokenUsesSoongPython2Modules bool `json:",omitempty"` + BuildBrokenVendorPropertyNamespace bool `json:",omitempty"` + BuildBrokenIncorrectPartitionImages bool `json:",omitempty"` + BuildBrokenInputDirModules []string `json:",omitempty"` BuildWarningBadOptionalUsesLibsAllowlist []string `json:",omitempty"` diff --git a/apex/builder.go b/apex/builder.go index 4b42b7428..1204dbb97 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -75,6 +75,8 @@ func init() { pctx.HostBinToolVariable("deapexer", "deapexer") pctx.HostBinToolVariable("debugfs_static", "debugfs_static") pctx.SourcePathVariable("genNdkUsedbyApexPath", "build/soong/scripts/gen_ndk_usedby_apex.sh") + pctx.HostBinToolVariable("conv_linker_config", "conv_linker_config") + pctx.HostBinToolVariable("assemble_vintf", "assemble_vintf") } var ( @@ -222,6 +224,18 @@ var ( CommandDeps: []string{"${apex_sepolicy_tests}", "${deapexer}", "${debugfs_static}"}, Description: "run apex_sepolicy_tests", }) + + apexLinkerconfigValidationRule = pctx.StaticRule("apexLinkerconfigValidationRule", blueprint.RuleParams{ + Command: `${conv_linker_config} validate --type apex ${image_dir} && touch ${out}`, + CommandDeps: []string{"${conv_linker_config}"}, + Description: "run apex_linkerconfig_validation", + }, "image_dir") + + apexVintfFragmentsValidationRule = pctx.StaticRule("apexVintfFragmentsValidationRule", blueprint.RuleParams{ + Command: `/bin/bash -c '(shopt -s nullglob; for f in ${image_dir}/etc/vintf/*.xml; do VINTF_IGNORE_TARGET_FCM_VERSION=true ${assemble_vintf} -i "$$f" > /dev/null; done)' && touch ${out}`, + CommandDeps: []string{"${assemble_vintf}"}, + Description: "run apex_vintf_validation", + }, "image_dir") ) // buildManifest creates buile rules to modify the input apex_manifest.json to add information @@ -843,6 +857,10 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { args["outCommaList"] = signedOutputFile.String() } var validations android.Paths + validations = append(validations, runApexLinkerconfigValidation(ctx, unsignedOutputFile.OutputPath, imageDir.OutputPath)) + if !a.testApex && a.SocSpecific() { + validations = append(validations, runApexVintfFragmentsValidation(ctx, unsignedOutputFile.OutputPath, imageDir.OutputPath)) + } // TODO(b/279688635) deapexer supports [ext4] if suffix == imageApexSuffix && ext4 == a.payloadFsType { validations = append(validations, runApexSepolicyTests(ctx, unsignedOutputFile.OutputPath)) @@ -1097,6 +1115,32 @@ func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.Outp return cannedFsConfig.OutputPath } +func runApexLinkerconfigValidation(ctx android.ModuleContext, apexFile android.OutputPath, imageDir android.OutputPath) android.Path { + timestamp := android.PathForModuleOut(ctx, "apex_linkerconfig_validation.timestamp") + ctx.Build(pctx, android.BuildParams{ + Rule: apexLinkerconfigValidationRule, + Input: apexFile, + Output: timestamp, + Args: map[string]string{ + "image_dir": imageDir.String(), + }, + }) + return timestamp +} + +func runApexVintfFragmentsValidation(ctx android.ModuleContext, apexFile android.OutputPath, imageDir android.OutputPath) android.Path { + timestamp := android.PathForModuleOut(ctx, "apex_vintf_fragments_validation.timestamp") + ctx.Build(pctx, android.BuildParams{ + Rule: apexVintfFragmentsValidationRule, + Input: apexFile, + Output: timestamp, + Args: map[string]string{ + "image_dir": imageDir.String(), + }, + }) + return timestamp +} + // Runs apex_sepolicy_tests // // $ deapexer list -Z {apex_file} > {file_contexts} diff --git a/bp2build/Android.bp b/bp2build/Android.bp index b675e5e28..161a7ffcf 100644 --- a/bp2build/Android.bp +++ b/bp2build/Android.bp @@ -62,6 +62,7 @@ bootstrap_go_package { "cc_test_conversion_test.go", "cc_yasm_conversion_test.go", "conversion_test.go", + "droiddoc_exported_dir_conversion_test.go", "filegroup_conversion_test.go", "genrule_conversion_test.go", "gensrcs_conversion_test.go", diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go index a24378cdb..13bb167c2 100644 --- a/bp2build/aar_conversion_test.go +++ b/bp2build/aar_conversion_test.go @@ -35,7 +35,7 @@ func TestConvertAndroidLibrary(t *testing.T) { "res/res.png": "", "manifest/AndroidManifest.xml": "", }, - Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + ` android_library { name: "TestLib", srcs: ["lib.java"], @@ -82,7 +82,7 @@ func TestConvertAndroidLibraryWithNoSources(t *testing.T) { "res/res.png": "", "AndroidManifest.xml": "", }, - Blueprint: simpleModuleDoNotConvertBp2build("android_library", "lib_dep") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("android_library", "lib_dep") + ` android_library { name: "TestLib", srcs: [], @@ -113,8 +113,8 @@ func TestConvertAndroidLibraryImport(t *testing.T) { // Bazel's aar_import can only export *_import targets, so we expect // only "static_import_dep" in exports, but both "static_lib_dep" and // "static_import_dep" in deps - Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + - simpleModuleDoNotConvertBp2build("android_library_import", "static_import_dep") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + + SimpleModuleDoNotConvertBp2build("android_library_import", "static_import_dep") + ` android_library_import { name: "TestImport", aars: ["import.aar"], diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go index f2ee322e6..0d206b0e7 100644 --- a/bp2build/android_app_conversion_test.go +++ b/bp2build/android_app_conversion_test.go @@ -78,7 +78,7 @@ func TestAndroidAppAllSupportedFields(t *testing.T) { "manifest/AndroidManifest.xml": "", "assets_/asset.png": "", }, - Blueprint: simpleModuleDoNotConvertBp2build("android_app", "static_lib_dep") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("android_app", "static_lib_dep") + ` android_app { name: "TestApp", srcs: ["app.java"], @@ -177,7 +177,7 @@ func TestAndroidAppCertIsModule(t *testing.T) { ModuleTypeUnderTest: "android_app", ModuleTypeUnderTestFactory: java.AndroidAppFactory, Filesystem: map[string]string{}, - Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("filegroup", "foocert") + ` android_app { name: "TestApp", certificate: ":foocert", @@ -262,7 +262,7 @@ func TestAndroidAppLibs(t *testing.T) { ModuleTypeUnderTest: "android_app", ModuleTypeUnderTestFactory: java.AndroidAppFactory, Filesystem: map[string]string{}, - Blueprint: simpleModuleDoNotConvertBp2build("java_library", "barLib") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("java_library", "barLib") + ` android_app { name: "foo", libs: ["barLib"], @@ -291,8 +291,8 @@ func TestAndroidAppKotlinSrcs(t *testing.T) { Filesystem: map[string]string{ "res/res.png": "", }, - Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + - simpleModuleDoNotConvertBp2build("java_library", "barLib") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("filegroup", "foocert") + + SimpleModuleDoNotConvertBp2build("java_library", "barLib") + ` android_app { name: "foo", srcs: ["a.java", "b.kt"], diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go index 238324761..d6db6778a 100644 --- a/bp2build/apex_conversion_test.go +++ b/bp2build/apex_conversion_test.go @@ -1263,7 +1263,7 @@ apex { file_contexts: ":com.android.apogee-file_contexts", certificate: ":com.android.apogee.certificate", } -` + simpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee-file_contexts"), +` + SimpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee-file_contexts"), ExpectedBazelTargets: []string{ MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{ "certificate": `":com.android.apogee.certificate"`, @@ -1299,7 +1299,7 @@ apex { binaries: ["bar"], native_shared_libs: ["foo"], } -` + simpleModuleDoNotConvertBp2build("filegroup", "myapex-file_contexts"), +` + SimpleModuleDoNotConvertBp2build("filegroup", "myapex-file_contexts"), ExpectedBazelTargets: []string{ MakeBazelTarget("cc_binary", "bar", AttrNameToString{ "local_includes": `["."]`, @@ -1315,6 +1315,7 @@ apex { "tags": `["apex_available=myapex"]`, }), MakeBazelTarget("cc_stub_suite", "foo_stub_libs", AttrNameToString{ + "api_surface": `"module-libapi"`, "soname": `"foo.so"`, "source_library_label": `"//:foo"`, "symbol_file": `"foo.map.txt"`, @@ -1356,7 +1357,7 @@ apex { file_contexts: ":com.android.apogee-file_contexts", certificate: "com.android.apogee.certificate", } -` + simpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee-file_contexts"), +` + SimpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee-file_contexts"), ExpectedBazelTargets: []string{ MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{ "certificate_name": `"com.android.apogee.certificate"`, diff --git a/bp2build/apex_key_conversion_test.go b/bp2build/apex_key_conversion_test.go index 1230a480b..8f6e843c5 100644 --- a/bp2build/apex_key_conversion_test.go +++ b/bp2build/apex_key_conversion_test.go @@ -89,8 +89,8 @@ apex_key { public_key: ":com.android.apogee.avbpubkey", private_key: ":com.android.apogee.pem", } -` + simpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee.avbpubkey") + - simpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee.pem"), +` + SimpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee.avbpubkey") + + SimpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee.pem"), ExpectedBazelTargets: []string{MakeBazelTargetNoRestrictions("apex_key", "com.android.apogee.key", AttrNameToString{ "private_key": `":com.android.apogee.pem"`, "public_key": `":com.android.apogee.avbpubkey"`, diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go index 5f7b382f0..6c9d90330 100644 --- a/bp2build/bp2build.go +++ b/bp2build/bp2build.go @@ -82,15 +82,25 @@ func Codegen(ctx *CodegenContext) *CodegenMetrics { os.Exit(1) } var bp2buildFiles []BazelFile + productConfig, err := createProductConfigFiles(ctx, res.metrics) ctx.Context().EventHandler.Do("CreateBazelFile", func() { - bp2buildFiles = CreateBazelFiles(nil, res.buildFileToTargets, ctx.mode) + allTargets := make(map[string]BazelTargets) + for k, v := range res.buildFileToTargets { + allTargets[k] = append(allTargets[k], v...) + } + for k, v := range productConfig.bp2buildTargets { + allTargets[k] = append(allTargets[k], v...) + } + bp2buildFiles = CreateBazelFiles(nil, allTargets, ctx.mode) }) - injectionFiles, additionalBp2buildFiles, err := CreateSoongInjectionDirFiles(ctx, res.metrics) + bp2buildFiles = append(bp2buildFiles, productConfig.bp2buildFiles...) + injectionFiles, err := createSoongInjectionDirFiles(ctx, res.metrics) if err != nil { fmt.Printf("%s\n", err.Error()) os.Exit(1) } - bp2buildFiles = append(bp2buildFiles, additionalBp2buildFiles...) + injectionFiles = append(injectionFiles, productConfig.injectionFiles...) + writeFiles(ctx, bp2buildDir, bp2buildFiles) // Delete files under the bp2build root which weren't just written. An // alternative would have been to delete the whole directory and write these @@ -109,26 +119,6 @@ func Codegen(ctx *CodegenContext) *CodegenMetrics { return &res.metrics } -// Wrapper function that will be responsible for all files in soong_injection directory -// This includes -// 1. config value(s) that are hardcoded in Soong -// 2. product_config variables -func CreateSoongInjectionDirFiles(ctx *CodegenContext, metrics CodegenMetrics) ([]BazelFile, []BazelFile, error) { - var ret []BazelFile - - productConfigInjectionFiles, productConfigBp2BuildDirFiles, err := CreateProductConfigFiles(ctx, metrics) - if err != nil { - return nil, nil, err - } - ret = append(ret, productConfigInjectionFiles...) - injectionFiles, err := soongInjectionFiles(ctx.Config(), metrics) - if err != nil { - return nil, nil, err - } - ret = append(injectionFiles, ret...) - return ret, productConfigBp2BuildDirFiles, nil -} - // Get the output directory and create it if it doesn't exist. func getOrCreateOutputDir(outputDir android.OutputPath, ctx android.PathContext, dir string) android.OutputPath { dirPath := outputDir.Join(ctx, dir) diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go index 021494108..50b83582a 100644 --- a/bp2build/bp2build_product_config.go +++ b/bp2build/bp2build_product_config.go @@ -12,14 +12,19 @@ import ( "android/soong/android/soongconfig" "android/soong/starlark_import" - "github.com/google/blueprint" "github.com/google/blueprint/proptools" "go.starlark.net/starlark" ) -func CreateProductConfigFiles( +type createProductConfigFilesResult struct { + injectionFiles []BazelFile + bp2buildFiles []BazelFile + bp2buildTargets map[string]BazelTargets +} + +func createProductConfigFiles( ctx *CodegenContext, - metrics CodegenMetrics) ([]BazelFile, []BazelFile, error) { + metrics CodegenMetrics) (createProductConfigFilesResult, error) { cfg := &ctx.config targetProduct := "unknown" if cfg.HasDeviceProduct() { @@ -32,29 +37,22 @@ func CreateProductConfigFiles( targetBuildVariant = "userdebug" } + var res createProductConfigFilesResult + productVariablesFileName := cfg.ProductVariablesFileName if !strings.HasPrefix(productVariablesFileName, "/") { productVariablesFileName = filepath.Join(ctx.topDir, productVariablesFileName) } productVariablesBytes, err := os.ReadFile(productVariablesFileName) if err != nil { - return nil, nil, err + return res, err } productVariables := android.ProductVariables{} err = json.Unmarshal(productVariablesBytes, &productVariables) if err != nil { - return nil, nil, err + return res, err } - // Visit all modules to determine the list of ndk libraries - // This list will be used to add additional flags for cc stub generation - ndkLibsStringFormatted := []string{} - ctx.Context().VisitAllModules(func(m blueprint.Module) { - if ctx.Context().ModuleType(m) == "ndk_library" { - ndkLibsStringFormatted = append(ndkLibsStringFormatted, fmt.Sprintf(`"%s"`, m.Name())) // name will be `"libc.ndk"` - } - }) - // TODO(b/249685973): the name is product_config_platforms because product_config // was already used for other files. Deduplicate them. currentProductFolder := fmt.Sprintf("product_config_platforms/products/%s-%s", targetProduct, targetBuildVariant) @@ -64,25 +62,36 @@ func CreateProductConfigFiles( "{VARIANT}", targetBuildVariant, "{PRODUCT_FOLDER}", currentProductFolder) - platformMappingContent, err := platformMappingContent( - productReplacer.Replace("@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}"), - &productVariables, - ctx.Config().Bp2buildSoongConfigDefinitions, - metrics.convertedModulePathMap) - if err != nil { - return nil, nil, err - } - productsForTestingMap, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing") if err != nil { - return nil, nil, err + return res, err } productsForTesting := android.SortedKeys(productsForTestingMap) for i := range productsForTesting { productsForTesting[i] = fmt.Sprintf(" \"@//build/bazel/tests/products:%s\",", productsForTesting[i]) } - injectionDirFiles := []BazelFile{ + productLabelsToVariables := make(map[string]*android.ProductVariables) + productLabelsToVariables[productReplacer.Replace("@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}")] = &productVariables + for product, productVariablesStarlark := range productsForTestingMap { + productVariables, err := starlarkMapToProductVariables(productVariablesStarlark) + if err != nil { + return res, err + } + productLabelsToVariables["@//build/bazel/tests/products:"+product] = &productVariables + } + + res.bp2buildTargets = createTargets(productLabelsToVariables) + + platformMappingContent, err := platformMappingContent( + productLabelsToVariables, + ctx.Config().Bp2buildSoongConfigDefinitions, + metrics.convertedModulePathMap) + if err != nil { + return res, err + } + + res.injectionFiles = []BazelFile{ newFile( currentProductFolder, "soong.variables.bzl", @@ -164,30 +173,21 @@ build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_lin productReplacer.Replace(` build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_darwin_x86_64 `)), - newFile( - "cc_toolchain", - "ndk_libs.bzl", - fmt.Sprintf("ndk_libs = [%v]", strings.Join(ndkLibsStringFormatted, ", ")), - ), } - bp2buildDirFiles := []BazelFile{ + res.bp2buildFiles = []BazelFile{ newFile( "", "platform_mappings", platformMappingContent), } - return injectionDirFiles, bp2buildDirFiles, nil + + return res, nil } func platformMappingContent( - mainProductLabel string, - mainProductVariables *android.ProductVariables, + productLabelToVariables map[string]*android.ProductVariables, soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions, convertedModulePathMap map[string]string) (string, error) { - productsForTesting, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing") - if err != nil { - return "", err - } var result strings.Builder mergedConvertedModulePathMap := make(map[string]string) @@ -203,13 +203,8 @@ func platformMappingContent( } result.WriteString("platforms:\n") - platformMappingSingleProduct(mainProductLabel, mainProductVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result) - for product, productVariablesStarlark := range productsForTesting { - productVariables, err := starlarkMapToProductVariables(productVariablesStarlark) - if err != nil { - return "", err - } - platformMappingSingleProduct("@//build/bazel/tests/products:"+product, &productVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result) + for productLabel, productVariables := range productLabelToVariables { + platformMappingSingleProduct(productLabel, productVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result) } return result.String(), nil } @@ -248,7 +243,7 @@ func platformMappingSingleProduct( defaultAppCertificateFilegroup := "//build/bazel/utils:empty_filegroup" if proptools.String(productVariables.DefaultAppCertificate) != "" { - defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":android_certificate_directory" + defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":generated_android_certificate_directory" } for _, suffix := range bazelPlatformSuffixes { @@ -261,6 +256,7 @@ func platformMappingSingleProduct( result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:binder32bit=%t\n", proptools.Bool(productVariables.Binder32bit))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_from_text_stub=%t\n", proptools.Bool(productVariables.Build_from_text_stub))) + result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_broken_incorrect_partition_images=%t\n", productVariables.BuildBrokenIncorrectPartitionImages)) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_id=%s\n", proptools.String(productVariables.BuildId))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_version_tags=%s\n", strings.Join(productVariables.BuildVersionTags, ","))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:cfi_exclude_paths=%s\n", strings.Join(productVariables.CFIExcludePaths, ","))) @@ -418,3 +414,33 @@ func starlarkMapToProductVariables(in map[string]starlark.Value) (android.Produc return result, nil } + +func createTargets(productLabelsToVariables map[string]*android.ProductVariables) map[string]BazelTargets { + res := make(map[string]BazelTargets) + var allDefaultAppCertificateDirs []string + for _, productVariables := range productLabelsToVariables { + if proptools.String(productVariables.DefaultAppCertificate) != "" { + d := filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + if !android.InList(d, allDefaultAppCertificateDirs) { + allDefaultAppCertificateDirs = append(allDefaultAppCertificateDirs, d) + } + } + } + for _, dir := range allDefaultAppCertificateDirs { + content := fmt.Sprintf(ruleTargetTemplate, "filegroup", "generated_android_certificate_directory", propsToAttributes(map[string]string{ + "srcs": `glob([ + "*.pk8", + "*.pem", + "*.avbpubkey", + ])`, + "visibility": `["//visibility:public"]`, + })) + res[dir] = append(res[dir], BazelTarget{ + name: "generated_android_certificate_directory", + packageName: dir, + content: content, + ruleClass: "filegroup", + }) + } + return res +} diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go index 3887c5da9..489756633 100644 --- a/bp2build/build_conversion_test.go +++ b/bp2build/build_conversion_test.go @@ -1743,7 +1743,7 @@ func TestCommonBp2BuildModuleAttrs(t *testing.T) { Description: "Required into data test", ModuleTypeUnderTest: "filegroup", ModuleTypeUnderTestFactory: android.FileGroupFactory, - Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("filegroup", "reqd") + ` filegroup { name: "fg_foo", required: ["reqd"], @@ -1759,7 +1759,7 @@ filegroup { Description: "Required into data test, cyclic self reference is filtered out", ModuleTypeUnderTest: "filegroup", ModuleTypeUnderTestFactory: android.FileGroupFactory, - Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("filegroup", "reqd") + ` filegroup { name: "fg_foo", required: ["reqd", "fg_foo"], @@ -1775,8 +1775,8 @@ filegroup { Description: "Required via arch into data test", ModuleTypeUnderTest: "python_library", ModuleTypeUnderTestFactory: python.PythonLibraryFactory, - Blueprint: simpleModuleDoNotConvertBp2build("python_library", "reqdx86") + - simpleModuleDoNotConvertBp2build("python_library", "reqdarm") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("python_library", "reqdx86") + + SimpleModuleDoNotConvertBp2build("python_library", "reqdarm") + ` python_library { name: "fg_foo", arch: { @@ -1809,7 +1809,7 @@ python_library { "data.bin": "", "src.py": "", }, - Blueprint: simpleModuleDoNotConvertBp2build("python_library", "reqd") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("python_library", "reqd") + ` python_library { name: "fg_foo", data: ["data.bin"], @@ -1831,7 +1831,7 @@ python_library { Description: "All props-to-attrs at once together test", ModuleTypeUnderTest: "filegroup", ModuleTypeUnderTestFactory: android.FileGroupFactory, - Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("filegroup", "reqd") + ` filegroup { name: "fg_foo", required: ["reqd"], diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go index 90db36573..3d3b860fa 100644 --- a/bp2build/cc_binary_conversion_test.go +++ b/bp2build/cc_binary_conversion_test.go @@ -276,7 +276,7 @@ func TestCcBinarySplitSrcsByLang(t *testing.T) { ], include_build_directory: false, } -` + simpleModuleDoNotConvertBp2build("filegroup", "fg_foo"), +` + SimpleModuleDoNotConvertBp2build("filegroup", "fg_foo"), targets: []testBazelTarget{ {"cc_binary", "foo", AttrNameToString{ "srcs": `[ @@ -326,12 +326,12 @@ genrule { export_generated_headers: ["export_generated_hdr"], } ` + - simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep") + - simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep") + - simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep") + - simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep") + - simpleModuleDoNotConvertBp2build("cc_library", "shared_dep") + - simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep"), + SimpleModuleDoNotConvertBp2build("cc_library_static", "static_dep") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep") + + SimpleModuleDoNotConvertBp2build("cc_library", "shared_dep") + + SimpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep"), targets: []testBazelTarget{ {"cc_binary", "foo", AttrNameToString{ "deps": `[ @@ -1226,7 +1226,7 @@ func TestCcBinaryStatic_SystemSharedLibUsedAsDep(t *testing.T) { runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{ description: "cc_library_static system_shared_lib empty for linux_bionic variant", blueprint: soongCcLibraryStaticPreamble + - simpleModuleDoNotConvertBp2build("cc_library", "libc") + ` + SimpleModuleDoNotConvertBp2build("cc_library", "libc") + ` cc_library { name: "libm", diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 9bb171330..b667fe9dc 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -94,7 +94,7 @@ func TestCcLibrarySimple(t *testing.T) { "foo-dir/a.h": "", }, Blueprint: soongCcLibraryPreamble + - simpleModuleDoNotConvertBp2build("cc_library_headers", "some-headers") + ` + SimpleModuleDoNotConvertBp2build("cc_library_headers", "some-headers") + ` cc_library { name: "foo-lib", srcs: ["impl.cpp"], @@ -176,7 +176,7 @@ func TestCcLibraryTrimmedLdAndroid(t *testing.T) { "linker_cfi.h": "", }, Blueprint: soongCcLibraryPreamble + - simpleModuleDoNotConvertBp2build("cc_library_headers", "libc_headers") + ` + SimpleModuleDoNotConvertBp2build("cc_library_headers", "libc_headers") + ` cc_library { name: "fake-ld-android", srcs: ["ld_android.cpp"], @@ -457,24 +457,24 @@ cc_library { }, include_build_directory: false, } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_shared") + - simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_shared") + - simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_static") + - simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_static") + - simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_both") + - simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_both") + - simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_shared") + - simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_shared") + - simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_static") + - simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_static") + - simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_both") + - simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_both") + - simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_shared") + - simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_shared") + - simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_static") + - simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_static") + - simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_both") + - simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_both"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_shared") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_shared") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_static") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_static") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_both") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_both") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_shared") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_shared") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_static") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_static") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_both") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_both") + + SimpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_shared") + + SimpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_shared") + + SimpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_static") + + SimpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_static") + + SimpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_both") + + SimpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_both"), ExpectedBazelTargets: []string{ MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{ "copts": `[ @@ -2549,10 +2549,10 @@ func TestCcLibraryProtoFilegroups(t *testing.T) { ModuleTypeUnderTest: "cc_library", ModuleTypeUnderTestFactory: cc.LibraryFactory, Blueprint: soongCcProtoPreamble + - simpleModuleDoNotConvertBp2build("filegroup", "a_fg_proto") + - simpleModuleDoNotConvertBp2build("filegroup", "b_protos") + - simpleModuleDoNotConvertBp2build("filegroup", "c-proto-srcs") + - simpleModuleDoNotConvertBp2build("filegroup", "proto-srcs-d") + ` + SimpleModuleDoNotConvertBp2build("filegroup", "a_fg_proto") + + SimpleModuleDoNotConvertBp2build("filegroup", "b_protos") + + SimpleModuleDoNotConvertBp2build("filegroup", "c-proto-srcs") + + SimpleModuleDoNotConvertBp2build("filegroup", "proto-srcs-d") + ` cc_library { name: "a", srcs: [":a_fg_proto"], @@ -2809,6 +2809,7 @@ func TestCcLibraryStubs(t *testing.T) { "stubs_symbol_file": `"a.map.txt"`, }) expectedBazelTargets = append(expectedBazelTargets, makeCcStubSuiteTargets("a", AttrNameToString{ + "api_surface": `"module-libapi"`, "soname": `"a.so"`, "source_library_label": `"//foo/bar:a"`, "stubs_symbol_file": `"a.map.txt"`, @@ -2882,7 +2883,7 @@ func TestCcLibraryExcludesLibsHost(t *testing.T) { Filesystem: map[string]string{ "bar.map.txt": "", }, - Blueprint: simpleModuleDoNotConvertBp2build("cc_library", "bazlib") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("cc_library", "bazlib") + ` cc_library { name: "quxlib", stubs: { symbol_file: "bar.map.txt", versions: ["current"] }, @@ -3537,10 +3538,10 @@ cc_library_static { "baz-shared", ], }` + - simpleModuleDoNotConvertBp2build("cc_library_static", "bar-static") + - simpleModuleDoNotConvertBp2build("cc_library_static", "baz-static") + - simpleModuleDoNotConvertBp2build("cc_library", "bar-shared") + - simpleModuleDoNotConvertBp2build("cc_library", "baz-shared"), + SimpleModuleDoNotConvertBp2build("cc_library_static", "bar-static") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "baz-static") + + SimpleModuleDoNotConvertBp2build("cc_library", "bar-shared") + + SimpleModuleDoNotConvertBp2build("cc_library", "baz-shared"), ExpectedBazelTargets: []string{ MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{ "srcs": `["Foo.aidl"]`, @@ -4744,7 +4745,7 @@ cc_library_static { canonical_path_from_root: true, } } -` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), +` + SimpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), Filesystem: map[string]string{ "bar/Android.bp": "", "baz/subbaz/Android.bp": "", @@ -4812,7 +4813,7 @@ cc_library_static { canonical_path_from_root: false, } } -` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), +` + SimpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), Filesystem: map[string]string{ "bar/Android.bp": "", "baz/subbaz/Android.bp": "", @@ -4882,7 +4883,7 @@ cc_library_static { include_dirs: ["bar"], } } -` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), +` + SimpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), Filesystem: map[string]string{ "bar/Android.bp": "", "bar/bar.proto": "", @@ -4953,7 +4954,7 @@ cc_library_static { include_dirs: ["baz"], } } -` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), +` + SimpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), Filesystem: map[string]string{ "bar/Android.bp": "", // package boundary "baz/Android.bp": "", @@ -4988,7 +4989,7 @@ func TestProtoLocalIncludeDirs(t *testing.T) { Description: "cc_library depends on .proto files using proto.local_include_dirs", ModuleTypeUnderTest: "cc_library", ModuleTypeUnderTestFactory: cc.LibraryFactory, - Blueprint: simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), + Blueprint: SimpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), Filesystem: map[string]string{ "foo/Android.bp": `cc_library_static { name: "foo", @@ -5045,7 +5046,7 @@ func TestProtoLibraryForIncludeDirsIsOsAgnostic(t *testing.T) { Description: "proto_library generated for proto.include_dirs is compatible for all axes", ModuleTypeUnderTest: "cc_library", ModuleTypeUnderTestFactory: cc.LibraryFactory, - Blueprint: simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite") + ` cc_library { name: "foo_device", device_supported: true, // this is the default behavior, but added explicitly here for illustration diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go index a592ca978..40e84510b 100644 --- a/bp2build/cc_library_headers_conversion_test.go +++ b/bp2build/cc_library_headers_conversion_test.go @@ -340,7 +340,7 @@ cc_library_headers { static_libs: ["foo_export", "foo_no_reexport"], bazel_module: { bp2build_available: true }, } -` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"), +` + SimpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"), ExpectedBazelTargets: []string{ MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{ "deps": `[":foo_export"]`, @@ -362,7 +362,7 @@ cc_library_headers { shared_libs: ["foo_export", "foo_no_reexport"], bazel_module: { bp2build_available: true }, } -` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"), +` + SimpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"), ExpectedBazelTargets: []string{ MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{ "deps": `[":foo_export"]`, @@ -384,7 +384,7 @@ cc_library_headers { header_libs: ["foo_export", "foo_no_reexport"], bazel_module: { bp2build_available: true }, } -` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"), +` + SimpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"), ExpectedBazelTargets: []string{ MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{ "deps": `[":foo_export"]`, @@ -405,7 +405,7 @@ cc_library_headers { whole_static_libs: ["foo_export"], bazel_module: { bp2build_available: true }, } -` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"), +` + SimpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"), ExpectedBazelTargets: []string{ MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{ "deps": `[":foo_export"]`, diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 44b97227e..d470810fb 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -543,6 +543,7 @@ cc_library_shared { }, Blueprint: soongCcLibraryPreamble, ExpectedBazelTargets: []string{makeCcStubSuiteTargets("a", AttrNameToString{ + "api_surface": `"module-libapi"`, "soname": `"a.so"`, "source_library_label": `"//foo/bar:a"`, "stubs_symbol_file": `"a.map.txt"`, @@ -1442,6 +1443,7 @@ cc_library_shared { `, ExpectedBazelTargets: []string{ makeCcStubSuiteTargets("a", AttrNameToString{ + "api_surface": `"module-libapi"`, "soname": `"a.so"`, "source_library_label": `"//:a"`, "stubs_symbol_file": `"a.map.txt"`, @@ -1456,6 +1458,7 @@ cc_library_shared { "stubs_symbol_file": `"a.map.txt"`, }), makeCcStubSuiteTargets("b", AttrNameToString{ + "api_surface": `"module-libapi"`, "soname": `"b.so"`, "source_library_label": `"//:b"`, "stubs_symbol_file": `"b.map.txt"`, diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index 89ec8f9a7..b9508e95b 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -1045,17 +1045,17 @@ func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) { "for-x86.cpp": "", "not-for-x86.cpp": "", "not-for-everything.cpp": "", - "dep/Android.bp": simpleModuleDoNotConvertBp2build("genrule", "generated_src_other_pkg") + - simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg") + - simpleModuleDoNotConvertBp2build("genrule", "generated_src_other_pkg_x86") + - simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg_x86") + - simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg_android"), + "dep/Android.bp": SimpleModuleDoNotConvertBp2build("genrule", "generated_src_other_pkg") + + SimpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg") + + SimpleModuleDoNotConvertBp2build("genrule", "generated_src_other_pkg_x86") + + SimpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg_x86") + + SimpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg_android"), }, Blueprint: soongCcLibraryStaticPreamble + - simpleModuleDoNotConvertBp2build("genrule", "generated_src") + - simpleModuleDoNotConvertBp2build("genrule", "generated_src_not_x86") + - simpleModuleDoNotConvertBp2build("genrule", "generated_src_android") + - simpleModuleDoNotConvertBp2build("genrule", "generated_hdr") + ` + SimpleModuleDoNotConvertBp2build("genrule", "generated_src") + + SimpleModuleDoNotConvertBp2build("genrule", "generated_src_not_x86") + + SimpleModuleDoNotConvertBp2build("genrule", "generated_src_android") + + SimpleModuleDoNotConvertBp2build("genrule", "generated_hdr") + ` cc_library_static { name: "foo_static", srcs: ["common.cpp", "not-for-*.cpp"], @@ -1460,7 +1460,7 @@ func TestStaticLibrary_SystemSharedLibsBionic(t *testing.T) { runCcLibraryStaticTestCase(t, Bp2buildTestCase{ Description: "cc_library_static system_shared_libs set for bionic variant", Blueprint: soongCcLibraryStaticPreamble + - simpleModuleDoNotConvertBp2build("cc_library", "libc") + ` + SimpleModuleDoNotConvertBp2build("cc_library", "libc") + ` cc_library { name: "libc_musl", bazel_module: { bp2build_available: false }, @@ -1493,8 +1493,8 @@ func TestStaticLibrary_SystemSharedLibsLinuxRootAndLinuxBionic(t *testing.T) { runCcLibraryStaticTestCase(t, Bp2buildTestCase{ Description: "cc_library_static system_shared_libs set for root and linux_bionic variant", Blueprint: soongCcLibraryStaticPreamble + - simpleModuleDoNotConvertBp2build("cc_library", "libc") + - simpleModuleDoNotConvertBp2build("cc_library", "libm") + ` + SimpleModuleDoNotConvertBp2build("cc_library", "libc") + + SimpleModuleDoNotConvertBp2build("cc_library", "libm") + ` cc_library { name: "libc_musl", bazel_module: { bp2build_available: false }, @@ -1527,7 +1527,7 @@ func TestCcLibrarystatic_SystemSharedLibUsedAsDep(t *testing.T) { runCcLibraryStaticTestCase(t, Bp2buildTestCase{ Description: "cc_library_static system_shared_lib empty for linux_bionic variant", Blueprint: soongCcLibraryStaticPreamble + - simpleModuleDoNotConvertBp2build("cc_library", "libc") + ` + SimpleModuleDoNotConvertBp2build("cc_library", "libc") + ` cc_library { name: "libm", @@ -2269,7 +2269,7 @@ genrule { name: "myprotogen", out: ["myproto.proto"], } -` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), +` + SimpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), ExpectedBazelTargets: []string{ MakeBazelTarget("cc_library_static", "mylib", AttrNameToString{ "local_includes": `["."]`, diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go index b88960e0e..8c33be3c9 100644 --- a/bp2build/cc_prebuilt_library_conversion_test.go +++ b/bp2build/cc_prebuilt_library_conversion_test.go @@ -17,6 +17,7 @@ import ( "fmt" "testing" + "android/soong/android" "android/soong/cc" ) @@ -360,3 +361,52 @@ cc_prebuilt_library { }, }) } + +func TestPrebuiltNdkStlConversion(t *testing.T) { + registerNdkStlModuleTypes := func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("ndk_prebuilt_static_stl", cc.NdkPrebuiltStaticStlFactory) + ctx.RegisterModuleType("ndk_prebuilt_shared_stl", cc.NdkPrebuiltSharedStlFactory) + } + RunBp2BuildTestCase(t, registerNdkStlModuleTypes, Bp2buildTestCase{ + Description: "TODO", + Blueprint: ` +ndk_prebuilt_static_stl { + name: "ndk_libfoo_static", + export_include_dirs: ["dir1", "dir2"], +} +ndk_prebuilt_shared_stl { + name: "ndk_libfoo_shared", + export_include_dirs: ["dir1", "dir2"], +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_static", "ndk_libfoo_static", AttrNameToString{ + "static_library": `select({ + "//build/bazel/platforms/os_arch:android_arm": "current/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libfoo_static.a", + "//build/bazel/platforms/os_arch:android_arm64": "current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libfoo_static.a", + "//build/bazel/platforms/os_arch:android_riscv64": "current/sources/cxx-stl/llvm-libc++/libs/riscv64/libfoo_static.a", + "//build/bazel/platforms/os_arch:android_x86": "current/sources/cxx-stl/llvm-libc++/libs/x86/libfoo_static.a", + "//build/bazel/platforms/os_arch:android_x86_64": "current/sources/cxx-stl/llvm-libc++/libs/x86_64/libfoo_static.a", + "//conditions:default": None, + })`, + "export_system_includes": `[ + "dir1", + "dir2", + ]`, + }), + MakeBazelTarget("cc_prebuilt_library_shared", "ndk_libfoo_shared", AttrNameToString{ + "shared_library": `select({ + "//build/bazel/platforms/os_arch:android_arm": "current/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libfoo_shared.so", + "//build/bazel/platforms/os_arch:android_arm64": "current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libfoo_shared.so", + "//build/bazel/platforms/os_arch:android_riscv64": "current/sources/cxx-stl/llvm-libc++/libs/riscv64/libfoo_shared.so", + "//build/bazel/platforms/os_arch:android_x86": "current/sources/cxx-stl/llvm-libc++/libs/x86/libfoo_shared.so", + "//build/bazel/platforms/os_arch:android_x86_64": "current/sources/cxx-stl/llvm-libc++/libs/x86_64/libfoo_shared.so", + "//conditions:default": None, + })`, + "export_system_includes": `[ + "dir1", + "dir2", + ]`, + }), + }, + }) +} diff --git a/bp2build/cc_test_conversion_test.go b/bp2build/cc_test_conversion_test.go index 9639ab98f..74a5c0d11 100644 --- a/bp2build/cc_test_conversion_test.go +++ b/bp2build/cc_test_conversion_test.go @@ -89,14 +89,14 @@ cc_test_library { host_supported: true, include_build_directory: false, } -` + simpleModuleDoNotConvertBp2build("cc_library", "foolib") + - simpleModuleDoNotConvertBp2build("cc_library_static", "hostlib") + - simpleModuleDoNotConvertBp2build("genrule", "data_mod") + - simpleModuleDoNotConvertBp2build("cc_binary", "cc_bin") + - simpleModuleDoNotConvertBp2build("cc_library", "cc_lib") + - simpleModuleDoNotConvertBp2build("cc_test_library", "cc_test_lib2") + - simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + - simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), +` + SimpleModuleDoNotConvertBp2build("cc_library", "foolib") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "hostlib") + + SimpleModuleDoNotConvertBp2build("genrule", "data_mod") + + SimpleModuleDoNotConvertBp2build("cc_binary", "cc_bin") + + SimpleModuleDoNotConvertBp2build("cc_library", "cc_lib") + + SimpleModuleDoNotConvertBp2build("cc_test_library", "cc_test_lib2") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), targets: []testBazelTarget{ {"cc_library_shared", "cc_test_lib1", AttrNameToString{}}, {"cc_library_static", "cc_test_lib1_bp2build_cc_library_static", AttrNameToString{}}, @@ -196,8 +196,8 @@ cc_test { srcs: ["test.cpp"], test_options: { tags: ["no-remote"] }, } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + - simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), targets: []testBazelTarget{ {"cc_test", "mytest", AttrNameToString{ "tags": `["no-remote"]`, @@ -236,8 +236,8 @@ cc_test { srcs: ["test.cpp"], test_config: "test_config.xml", } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + - simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), targets: []testBazelTarget{ {"cc_test", "mytest", AttrNameToString{ "local_includes": `["."]`, @@ -274,8 +274,8 @@ cc_test { name: "mytest", srcs: ["test.cpp"], } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + - simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), targets: []testBazelTarget{ {"cc_test", "mytest", AttrNameToString{ "local_includes": `["."]`, @@ -315,8 +315,8 @@ cc_test { auto_gen_config: true, isolated: true, } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + - simpleModuleDoNotConvertBp2build("cc_library", "liblog"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + + SimpleModuleDoNotConvertBp2build("cc_library", "liblog"), targets: []testBazelTarget{ {"cc_test", "mytest", AttrNameToString{ "auto_generate_test_config": "True", @@ -354,8 +354,8 @@ cc_test { srcs: ["test.cpp"], static_libs: ["libgtest"], } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + - simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), targets: []testBazelTarget{ {"cc_test", "mytest", AttrNameToString{ "local_includes": `["."]`, @@ -389,8 +389,8 @@ cc_test { srcs: ["test.cpp"], isolated: true, } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + - simpleModuleDoNotConvertBp2build("cc_library", "liblog"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + + SimpleModuleDoNotConvertBp2build("cc_library", "liblog"), targets: []testBazelTarget{ {"cc_test", "mytest", AttrNameToString{ "local_includes": `["."]`, @@ -425,8 +425,8 @@ cc_test { name: "mytest_with_no_gtest", gtest: false, } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + - simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") + + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"), targets: []testBazelTarget{ {"cc_test", "mytest_with_gtest", AttrNameToString{ "local_includes": `["."]`, @@ -477,8 +477,8 @@ cc_test { memtag_heap: false, }, } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + - simpleModuleDoNotConvertBp2build("cc_library", "liblog"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + + SimpleModuleDoNotConvertBp2build("cc_library", "liblog"), targets: []testBazelTarget{ {"cc_test", "mytest", AttrNameToString{ "local_includes": `["."]`, @@ -513,8 +513,8 @@ cc_test { } }, } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + - simpleModuleDoNotConvertBp2build("cc_library", "liblog"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + + SimpleModuleDoNotConvertBp2build("cc_library", "liblog"), targets: []testBazelTarget{ {"cc_test", "mytest", AttrNameToString{ "local_includes": `["."]`, @@ -549,8 +549,8 @@ cc_test { } }, } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + - simpleModuleDoNotConvertBp2build("cc_library", "liblog"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + + SimpleModuleDoNotConvertBp2build("cc_library", "liblog"), targets: []testBazelTarget{ {"cc_test", "mytest", AttrNameToString{ "local_includes": `["."]`, @@ -594,8 +594,8 @@ cc_test { } }, } -` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + - simpleModuleDoNotConvertBp2build("cc_library", "liblog"), +` + SimpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + + SimpleModuleDoNotConvertBp2build("cc_library", "liblog"), targets: []testBazelTarget{ {"cc_test", "mytest", AttrNameToString{ "local_includes": `["."]`, diff --git a/bp2build/conversion.go b/bp2build/conversion.go index da4b5cf1f..c69723587 100644 --- a/bp2build/conversion.go +++ b/bp2build/conversion.go @@ -15,6 +15,7 @@ import ( rust_config "android/soong/rust/config" "android/soong/starlark_fmt" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -24,16 +25,28 @@ type BazelFile struct { Contents string } -// PRIVATE: Use CreateSoongInjectionDirFiles instead -func soongInjectionFiles(cfg android.Config, metrics CodegenMetrics) ([]BazelFile, error) { +// createSoongInjectionDirFiles returns most of the files to write to the soong_injection directory. +// Some other files also come from CreateProductConfigFiles +func createSoongInjectionDirFiles(ctx *CodegenContext, metrics CodegenMetrics) ([]BazelFile, error) { + cfg := ctx.Config() var files []BazelFile files = append(files, newFile("android", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package. files = append(files, newFile("android", "constants.bzl", android.BazelCcToolchainVars(cfg))) + // Visit all modules to determine the list of ndk libraries + // This list will be used to add additional flags for cc stub generation + ndkLibsStringFormatted := []string{} + ctx.Context().VisitAllModules(func(m blueprint.Module) { + if ctx.Context().ModuleType(m) == "ndk_library" { + ndkLibsStringFormatted = append(ndkLibsStringFormatted, fmt.Sprintf(`"%s"`, m.Name())) // name will be `"libc.ndk"` + } + }) + files = append(files, newFile("cc_toolchain", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package. files = append(files, newFile("cc_toolchain", "config_constants.bzl", cc_config.BazelCcToolchainVars(cfg))) files = append(files, newFile("cc_toolchain", "sanitizer_constants.bzl", cc.BazelCcSanitizerToolchainVars(cfg))) + files = append(files, newFile("cc_toolchain", "ndk_libs.bzl", fmt.Sprintf("ndk_libs = [%v]", strings.Join(ndkLibsStringFormatted, ", ")))) files = append(files, newFile("java_toolchain", GeneratedBuildFileName, "")) // Creates a //java_toolchain package. files = append(files, newFile("java_toolchain", "constants.bzl", java_config.BazelJavaToolchainVars(cfg))) diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go index 89dd38ef0..6b100772c 100644 --- a/bp2build/conversion_test.go +++ b/bp2build/conversion_test.go @@ -83,7 +83,8 @@ func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) { func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) { testConfig := android.TestConfig("", make(map[string]string), "", make(map[string][]byte)) - files, err := soongInjectionFiles(testConfig, CreateCodegenMetrics()) + codegenCtx := NewCodegenContext(testConfig, android.NewTestContext(testConfig).Context, Bp2Build, "") + files, err := createSoongInjectionDirFiles(codegenCtx, CreateCodegenMetrics()) if err != nil { t.Error(err) } @@ -106,6 +107,10 @@ func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) { }, { dir: "cc_toolchain", + basename: "ndk_libs.bzl", + }, + { + dir: "cc_toolchain", basename: "sanitizer_constants.bzl", }, { @@ -182,15 +187,45 @@ func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) { }, } - if len(files) != len(expectedFilePaths) { - t.Errorf("Expected %d file, got %d", len(expectedFilePaths), len(files)) + less := func(a bazelFilepath, b bazelFilepath) bool { + return a.dir+"/"+a.basename < b.dir+"/"+b.basename } - for i := range files { - actualFile, expectedFile := files[i], expectedFilePaths[i] + fileToFilepath := func(a BazelFile) bazelFilepath { + return bazelFilepath{basename: a.Basename, dir: a.Dir} + } - if actualFile.Dir != expectedFile.dir || actualFile.Basename != expectedFile.basename { - t.Errorf("Did not find expected file %s/%s", actualFile.Dir, actualFile.Basename) + sort.Slice(expectedFilePaths, func(i, j int) bool { + return less(expectedFilePaths[i], expectedFilePaths[j]) + }) + sort.Slice(files, func(i, j int) bool { + return less(fileToFilepath(files[i]), fileToFilepath(files[j])) + }) + + i := 0 + j := 0 + for i < len(expectedFilePaths) && j < len(files) { + expectedFile, actualFile := expectedFilePaths[i], files[j] + + if actualFile.Dir == expectedFile.dir && actualFile.Basename == expectedFile.basename { + i++ + j++ + } else if less(expectedFile, fileToFilepath(actualFile)) { + t.Errorf("Did not find expected file %s/%s", expectedFile.dir, expectedFile.basename) + i++ + } else { + t.Errorf("Found unexpected file %s/%s", actualFile.Dir, actualFile.Basename) + j++ } } + for i < len(expectedFilePaths) { + expectedFile := expectedFilePaths[i] + t.Errorf("Did not find expected file %s/%s", expectedFile.dir, expectedFile.basename) + i++ + } + for j < len(files) { + actualFile := files[j] + t.Errorf("Found unexpected file %s/%s", actualFile.Dir, actualFile.Basename) + j++ + } } diff --git a/bp2build/droiddoc_exported_dir_conversion_test.go b/bp2build/droiddoc_exported_dir_conversion_test.go new file mode 100644 index 000000000..dee67f4ed --- /dev/null +++ b/bp2build/droiddoc_exported_dir_conversion_test.go @@ -0,0 +1,60 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bp2build + +import ( + "regexp" + "testing" + + "android/soong/java" +) + +func TestDroiddocExportedDir(t *testing.T) { + bp := ` + droiddoc_exported_dir { + name: "test-module", + path: "docs", + } + ` + p := regexp.MustCompile(`\t*\|`) + dedent := func(s string) string { + return p.ReplaceAllString(s, "") + } + expectedBazelTargets := []string{ + MakeBazelTargetNoRestrictions( + "droiddoc_exported_dir", + "test-module", + AttrNameToString{ + "dir": `"docs"`, + "srcs": dedent(`[ + | "docs/android/1.txt", + | "docs/android/nested-1/2.txt", + | "//docs/android/nested-2:3.txt", + | "//docs/android/nested-2:Android.bp", + | ]`), + }), + //note we are not excluding Android.bp files from subpackages for now + } + RunBp2BuildTestCase(t, java.RegisterDocsBuildComponents, Bp2buildTestCase{ + Blueprint: bp, + ExpectedBazelTargets: expectedBazelTargets, + Filesystem: map[string]string{ + "docs/android/1.txt": "", + "docs/android/nested-1/2.txt": "", + "docs/android/nested-2/Android.bp": "", + "docs/android/nested-2/3.txt": "", + }, + }) +} diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go index 512c1e102..8c782172e 100644 --- a/bp2build/java_library_conversion_test.go +++ b/bp2build/java_library_conversion_test.go @@ -677,7 +677,7 @@ func TestConvertArmNeonVariant(t *testing.T) { Description: "Android Library - simple arch feature", ModuleTypeUnderTest: "android_library", ModuleTypeUnderTestFactory: java.AndroidLibraryFactory, - Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + ` android_library { name: "TestLib", manifest: "manifest/AndroidManifest.xml", @@ -715,7 +715,7 @@ func TestConvertMultipleArchFeatures(t *testing.T) { Description: "Android Library - multiple arch features", ModuleTypeUnderTest: "android_library", ModuleTypeUnderTestFactory: java.AndroidLibraryFactory, - Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + ` android_library { name: "TestLib", manifest: "manifest/AndroidManifest.xml", @@ -761,7 +761,7 @@ func TestConvertExcludeSrcsArchFeature(t *testing.T) { Description: "Android Library - exclude_srcs with arch feature", ModuleTypeUnderTest: "android_library", ModuleTypeUnderTestFactory: java.AndroidLibraryFactory, - Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + ` + Blueprint: SimpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + ` android_library { name: "TestLib", manifest: "manifest/AndroidManifest.xml", diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go index 5d6b08814..dfef6973c 100644 --- a/bp2build/java_proto_conversion_test.go +++ b/bp2build/java_proto_conversion_test.go @@ -137,3 +137,50 @@ func TestJavaProtoDefault(t *testing.T) { }, }) } + +func TestJavaLibsAndOnlyProtoSrcs(t *testing.T) { + runJavaProtoTestCase(t, Bp2buildTestCase{ + Description: "java_library that has only proto srcs", + Blueprint: `java_library_static { + name: "java-protos", + srcs: ["a.proto"], + libs: ["java-lib"], + java_version: "7", + sdk_version: "current", +} + +java_library_static { + name: "java-lib", + bazel_module: { bp2build_available: false }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{ + "srcs": `["a.proto"]`, + }), + MakeBazelTarget( + "java_lite_proto_library", + "java-protos_java_proto_lite", + AttrNameToString{ + "deps": `[":java-protos_proto"]`, + "java_version": `"7"`, + "sdk_version": `"current"`, + }), + MakeBazelTarget("java_library", "java-protos", AttrNameToString{ + "exports": `[ + ":java-protos_java_proto_lite", + ":java-lib-neverlink", + ]`, + "java_version": `"7"`, + "sdk_version": `"current"`, + }), + MakeNeverlinkDuplicateTargetWithAttrs( + "java_library", + "java-protos", + AttrNameToString{ + "java_version": `"7"`, + "sdk_version": `"current"`, + }), + }, + }) +} diff --git a/bp2build/python_binary_conversion_test.go b/bp2build/python_binary_conversion_test.go index 1b538d066..4ccdba786 100644 --- a/bp2build/python_binary_conversion_test.go +++ b/bp2build/python_binary_conversion_test.go @@ -298,8 +298,8 @@ python_defaults { "r1", "r2", ], -}` + simpleModuleDoNotConvertBp2build("genrule", "r1") + - simpleModuleDoNotConvertBp2build("genrule", "r2"), +}` + SimpleModuleDoNotConvertBp2build("genrule", "r1") + + SimpleModuleDoNotConvertBp2build("genrule", "r2"), ExpectedBazelTargets: []string{ MakeBazelTarget("py_binary", "foo", AttrNameToString{ diff --git a/bp2build/symlink_forest.go b/bp2build/symlink_forest.go index 5c333085d..966b94a80 100644 --- a/bp2build/symlink_forest.go +++ b/bp2build/symlink_forest.go @@ -43,7 +43,7 @@ import ( // clean the whole symlink forest and recreate it. This number can be bumped whenever there's // an incompatible change to the forest layout or a bug in incrementality that needs to be fixed // on machines that may still have the bug present in their forest. -const symlinkForestVersion = 1 +const symlinkForestVersion = 2 type instructionsNode struct { name string diff --git a/bp2build/testing.go b/bp2build/testing.go index 997df64a4..2924e9ae6 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -570,7 +570,7 @@ func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) { ctx.RegisterForBazelConversion() } -func simpleModuleDoNotConvertBp2build(typ, name string) string { +func SimpleModuleDoNotConvertBp2build(typ, name string) string { return fmt.Sprintf(` %s { name: "%s", @@ -644,6 +644,7 @@ func makeCcStubSuiteTargets(name string, attrs AttrNameToString) string { return "" } STUB_SUITE_ATTRS := map[string]string{ + "api_surface": "api_surface", "stubs_symbol_file": "symbol_file", "stubs_versions": "versions", "soname": "soname", diff --git a/cc/bp2build.go b/cc/bp2build.go index 62416f79d..039a3cf74 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -1380,10 +1380,10 @@ func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversion // having stubs or not, so Bazel select() statement can be used to choose // source/stub variants of them. apexAvailable := module.ApexAvailable() - setStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.export, &la.dynamicDeps, 0, false) - setStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.implementation, &la.implementationDynamicDeps, 1, false) + SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.export, &la.dynamicDeps, 0, false) + SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.implementation, &la.implementationDynamicDeps, 1, false) if len(systemSharedLibs) > 0 { - setStubsForDynamicDeps(ctx, axis, config, apexAvailable, bazelLabelForSharedDeps(ctx, systemSharedLibs), &la.systemDynamicDeps, 2, true) + SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, bazelLabelForSharedDeps(ctx, systemSharedLibs), &la.systemDynamicDeps, 2, true) } } @@ -1583,7 +1583,7 @@ func useStubOrImplInApexWithName(ssi stubSelectionInfo) { } } -func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis, +func SetStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis, config string, apexAvailable []string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int, buildNonApexWithStubs bool) { // Create a config_setting for each apex_available. @@ -879,16 +879,16 @@ type Module struct { installer installer bazelHandler BazelHandler - features []feature - stl *stl - sanitize *sanitize - coverage *coverage - fuzzer *fuzzer - sabi *sabi - vndkdep *vndkdep - lto *lto - afdo *afdo - pgo *pgo + features []feature + stl *stl + sanitize *sanitize + coverage *coverage + fuzzer *fuzzer + sabi *sabi + vndkdep *vndkdep + lto *lto + afdo *afdo + pgo *pgo orderfile *orderfile library libraryInterface @@ -1104,6 +1104,16 @@ func (c *Module) CcLibraryInterface() bool { return false } +func (c *Module) IsNdkPrebuiltStl() bool { + if c.linker == nil { + return false + } + if _, ok := c.linker.(*ndkPrebuiltStlLinker); ok { + return true + } + return false +} + func (c *Module) RlibStd() bool { panic(fmt.Errorf("RlibStd called on non-Rust module: %q", c.BaseModuleName())) } @@ -4158,6 +4168,7 @@ const ( headerLibrary testBin // testBinary already declared ndkLibrary + ndkPrebuiltStl ) func (c *Module) typ() moduleType { @@ -4196,6 +4207,8 @@ func (c *Module) typ() moduleType { return sharedLibrary } else if c.isNDKStubLibrary() { return ndkLibrary + } else if c.IsNdkPrebuiltStl() { + return ndkPrebuiltStl } return unknownType } @@ -4240,6 +4253,8 @@ func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { } else { sharedOrStaticLibraryBp2Build(ctx, c, false) } + case ndkPrebuiltStl: + ndkPrebuiltStlBp2build(ctx, c) default: ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "") } diff --git a/cc/config/global.go b/cc/config/global.go index 174b12cfd..a586a3f70 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -67,10 +67,6 @@ var ( // 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", @@ -253,6 +249,8 @@ var ( // (anything for which IsThirdPartyPath() in build/soong/android/paths.go // returns true - includes external/, most of vendor/ and most of hardware/) noOverrideExternalGlobalCflags = []string{ + // http://b/151457797 + "-fcommon", // http://b/191699019 "-Wno-format-insufficient-args", // http://b/296321145 diff --git a/cc/library.go b/cc/library.go index 2d4d60440..7e0c55ac2 100644 --- a/cc/library.go +++ b/cc/library.go @@ -494,6 +494,7 @@ func createStubsBazelTargetIfNeeded(ctx android.TopDownMutatorContext, m *Module Soname: &soname, Source_library_label: proptools.StringPtr(m.GetBazelLabel(ctx, m)), Deps: baseAttributes.deps, + Api_surface: proptools.StringPtr("module-libapi"), } ctx.CreateBazelTargetModule(stubSuitesProps, android.CommonAttributes{Name: m.Name() + "_stub_libs"}, @@ -3121,6 +3122,7 @@ type bazelCcStubSuiteAttributes struct { Source_library_label *string Soname *string Deps bazel.LabelListAttribute + Api_surface *string } type bazelCcHeaderAbiCheckerAttributes struct { diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go index d0ae4a56d..1a8e90fd9 100644 --- a/cc/ndk_headers.go +++ b/cc/ndk_headers.go @@ -82,6 +82,7 @@ type headerModule struct { properties headerProperties + srcPaths android.Paths installPaths android.Paths licensePath android.Path } @@ -125,8 +126,8 @@ func (m *headerModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License)) - srcFiles := android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs) - for _, header := range srcFiles { + m.srcPaths = android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs) + for _, header := range m.srcPaths { installDir := getHeaderInstallDir(ctx, header, String(m.properties.From), String(m.properties.To)) installedPath := ctx.InstallFile(installDir, header.Base(), header) @@ -193,6 +194,7 @@ type versionedHeaderModule struct { properties versionedHeaderProperties + srcPaths android.Paths installPaths android.Paths licensePath android.Path } @@ -211,9 +213,9 @@ func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleCo fromSrcPath := android.PathForModuleSrc(ctx, String(m.properties.From)) toOutputPath := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To)) - srcFiles := ctx.GlobFiles(headerGlobPattern(fromSrcPath.String()), nil) + m.srcPaths = ctx.GlobFiles(headerGlobPattern(fromSrcPath.String()), nil) var installPaths []android.WritablePath - for _, header := range srcFiles { + for _, header := range m.srcPaths { installDir := getHeaderInstallDir(ctx, header, String(m.properties.From), String(m.properties.To)) installPath := installDir.Join(ctx, header.Base()) installPaths = append(installPaths, installPath) @@ -224,11 +226,11 @@ func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleCo ctx.ModuleErrorf("glob %q matched zero files", String(m.properties.From)) } - processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, srcFiles, installPaths) + processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, m.srcPaths, installPaths) } func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path, - srcFiles android.Paths, installPaths []android.WritablePath) android.Path { + srcPaths android.Paths, installPaths []android.WritablePath) android.Path { // The versioner depends on a dependencies directory to simplify determining include paths // when parsing headers. This directory contains architecture specific directories as well // as a common directory, each of which contains symlinks to the actually directories to @@ -253,7 +255,7 @@ func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir andro Rule: versionBionicHeaders, Description: "versioner preprocess " + srcDir.Rel(), Output: timestampFile, - Implicits: append(srcFiles, depsGlob...), + Implicits: append(srcPaths, depsGlob...), ImplicitOutputs: installPaths, Args: map[string]string{ "depsPath": depsPath.String(), @@ -317,6 +319,7 @@ type preprocessedHeadersModule struct { properties preprocessedHeadersProperties + srcPaths android.Paths installPaths android.Paths licensePath android.Path } @@ -329,9 +332,9 @@ func (m *preprocessedHeadersModule) GenerateAndroidBuildActions(ctx android.Modu preprocessor := android.PathForModuleSrc(ctx, String(m.properties.Preprocessor)) m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License)) - srcFiles := android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs) + m.srcPaths = android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs) installDir := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To)) - for _, src := range srcFiles { + for _, src := range m.srcPaths { installPath := installDir.Join(ctx, src.Base()) m.installPaths = append(m.installPaths, installPath) diff --git a/cc/ndk_library.go b/cc/ndk_library.go index 9281aebb5..b201dd88a 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -43,11 +43,17 @@ var ( CommandDeps: []string{"$ndkStubGenerator"}, }, "arch", "apiLevel", "apiMap", "flags") + // $headersList should include paths to public headers. All types + // that are defined outside of public headers will be excluded from + // ABI monitoring. + // + // STG tool doesn't access content of files listed in $headersList, + // so there is no need to add them to dependencies. stg = pctx.AndroidStaticRule("stg", blueprint.RuleParams{ - Command: "$stg -S :$symbolList --elf $in -o $out", + Command: "$stg -S :$symbolList --file-filter :$headersList --elf $in -o $out", CommandDeps: []string{"$stg"}, - }, "symbolList") + }, "symbolList", "headersList") stgdiff = pctx.AndroidStaticRule("stgdiff", blueprint.RuleParams{ @@ -347,14 +353,19 @@ func (this *stubDecorator) dumpAbi(ctx ModuleContext, symbolList android.Path) { this.abiDumpPath = getNdkAbiDumpInstallBase(ctx).Join(ctx, this.apiLevel.String(), ctx.Arch().ArchType.String(), this.libraryName(ctx), "abi.stg") + headersList := getNdkABIHeadersFile(ctx) ctx.Build(pctx, android.BuildParams{ Rule: stg, Description: fmt.Sprintf("stg %s", implementationLibrary), Input: implementationLibrary, - Implicit: symbolList, - Output: this.abiDumpPath, + Implicits: []android.Path{ + symbolList, + headersList, + }, + Output: this.abiDumpPath, Args: map[string]string{ - "symbolList": symbolList.String(), + "symbolList": symbolList.String(), + "headersList": headersList.String(), }, }) } diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go index d3a0a002e..c2382b33e 100644 --- a/cc/ndk_prebuilt.go +++ b/cc/ndk_prebuilt.go @@ -15,9 +15,11 @@ package cc import ( + "path/filepath" "strings" "android/soong/android" + "android/soong/bazel" ) func init() { @@ -64,6 +66,7 @@ func NdkPrebuiltSharedStlFactory() android.Module { module.Properties.Sdk_version = StringPtr("minimum") module.Properties.AlwaysSdk = true module.stl.Properties.Stl = StringPtr("none") + module.bazelable = true return module.Init() } @@ -84,12 +87,16 @@ func NdkPrebuiltStaticStlFactory() android.Module { module.Properties.AlwaysSdk = true module.Properties.Sdk_version = StringPtr("current") module.stl.Properties.Stl = StringPtr("none") + module.bazelable = true return module.Init() } +const ( + libDir = "current/sources/cxx-stl/llvm-libc++/libs" +) + func getNdkStlLibDir(ctx android.ModuleContext) android.SourcePath { - libDir := "prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs" - return android.PathForSource(ctx, libDir).Join(ctx, ctx.Arch().Abi[0]) + return android.PathForSource(ctx, ctx.ModuleDir(), libDir).Join(ctx, ctx.Arch().Abi[0]) } func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags, @@ -128,3 +135,81 @@ func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags, return lib } + +var ( + archToAbiDirMap = map[string]string{ + "android_arm": "armeabi-v7a", + "android_arm64": "arm64-v8a", + "android_riscv64": "riscv64", + "android_x86": "x86", + "android_x86_64": "x86_64", + } +) + +// stlSrcBp2build returns a bazel label for the checked-in .so/.a file +// It contains a select statement for each ABI +func stlSrcBp2build(ctx android.TopDownMutatorContext, c *Module) bazel.LabelAttribute { + libName := strings.TrimPrefix(c.Name(), "ndk_") + libExt := ".so" // TODO - b/201079053: Support windows + if ctx.ModuleType() == "ndk_prebuilt_static_stl" { + libExt = ".a" + } + src := bazel.LabelAttribute{} + for arch, abiDir := range archToAbiDirMap { + srcPath := filepath.Join(libDir, abiDir, libName+libExt) + src.SetSelectValue( + bazel.OsArchConfigurationAxis, + arch, + android.BazelLabelForModuleSrcSingle(ctx, srcPath), + ) + } + return src +} + +// stlIncludesBp2build returns the includes exported by the STL +func stlIncludesBp2build(c *Module) bazel.StringListAttribute { + linker, _ := c.linker.(*ndkPrebuiltStlLinker) + includeDirs := append( + []string{}, + linker.libraryDecorator.flagExporter.Properties.Export_include_dirs..., + ) + includeDirs = append( + includeDirs, + linker.libraryDecorator.flagExporter.Properties.Export_system_include_dirs..., + ) + return bazel.MakeStringListAttribute(android.FirstUniqueStrings(includeDirs)) +} + +func ndkPrebuiltStlBp2build(ctx android.TopDownMutatorContext, c *Module) { + if ctx.ModuleType() == "ndk_prebuilt_static_stl" { + ndkPrebuiltStaticStlBp2build(ctx, c) + } else { + ndkPrebuiltSharedStlBp2build(ctx, c) + } +} + +func ndkPrebuiltStaticStlBp2build(ctx android.TopDownMutatorContext, c *Module) { + props := bazel.BazelTargetModuleProperties{ + Rule_class: "cc_prebuilt_library_static", + Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_library_static.bzl", + } + attrs := &bazelPrebuiltLibraryStaticAttributes{ + Static_library: stlSrcBp2build(ctx, c), + Export_system_includes: stlIncludesBp2build(c), // The exports are always as system + } + // TODO: min_sdk_version + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: c.Name()}, attrs) +} + +func ndkPrebuiltSharedStlBp2build(ctx android.TopDownMutatorContext, c *Module) { + props := bazel.BazelTargetModuleProperties{ + Rule_class: "cc_prebuilt_library_shared", + Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_library_shared.bzl", + } + attrs := &bazelPrebuiltLibrarySharedAttributes{ + Shared_library: stlSrcBp2build(ctx, c), + Export_system_includes: stlIncludesBp2build(c), // The exports are always as system + } + // TODO: min_sdk_version + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: c.Name()}, attrs) +} diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go index feb388037..9ec2ae4ea 100644 --- a/cc/ndk_sysroot.go +++ b/cc/ndk_sysroot.go @@ -54,6 +54,7 @@ package cc import ( "android/soong/android" + "strings" ) func init() { @@ -96,15 +97,56 @@ func getNdkFullTimestampFile(ctx android.PathContext) android.WritablePath { return android.PathForOutput(ctx, "ndk.timestamp") } +// The list of all NDK headers as they are located in the repo. +// Used for ABI monitoring to track only structures defined in NDK headers. +func getNdkABIHeadersFile(ctx android.PathContext) android.WritablePath { + return android.PathForOutput(ctx, "ndk_abi_headers.txt") +} + func NdkSingleton() android.Singleton { return &ndkSingleton{} } +// Collect all NDK exported headers paths into a file that is used to +// detect public types that should be ABI monitored. +// +// Assume that we have the following code in exported header: +// +// typedef struct Context Context; +// typedef struct Output { +// ... +// } Output; +// void DoSomething(Context* ctx, Output* output); +// +// If none of public headers exported to end-users contain definition of +// "struct Context", then "struct Context" layout and members shouldn't be +// monitored. However we use DWARF information from a real library, which +// may have access to the definition of "string Context" from +// implementation headers, and it will leak to ABI. +// +// STG tool doesn't access source and header files, only DWARF information +// from compiled library. And the DWARF contains file name where a type is +// defined. So we need a rule to build a list of paths to public headers, +// so STG can distinguish private types from public and do not monitor +// private types that are not accessible to library users. +func writeNdkAbiSrcFilter(ctx android.BuilderContext, + headerSrcPaths android.Paths, outputFile android.WritablePath) { + var filterBuilder strings.Builder + filterBuilder.WriteString("[decl_file_allowlist]\n") + for _, headerSrcPath := range headerSrcPaths { + filterBuilder.WriteString(headerSrcPath.String()) + filterBuilder.WriteString("\n") + } + + android.WriteFileRule(ctx, outputFile, filterBuilder.String()) +} + type ndkSingleton struct{} func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { var staticLibInstallPaths android.Paths - var headerPaths android.Paths + var headerSrcPaths android.Paths + var headerInstallPaths android.Paths var installPaths android.Paths var licensePaths android.Paths ctx.VisitAllModules(func(module android.Module) { @@ -113,19 +155,22 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { } if m, ok := module.(*headerModule); ok { - headerPaths = append(headerPaths, m.installPaths...) + headerSrcPaths = append(headerSrcPaths, m.srcPaths...) + headerInstallPaths = append(headerInstallPaths, m.installPaths...) installPaths = append(installPaths, m.installPaths...) licensePaths = append(licensePaths, m.licensePath) } if m, ok := module.(*versionedHeaderModule); ok { - headerPaths = append(headerPaths, m.installPaths...) + headerSrcPaths = append(headerSrcPaths, m.srcPaths...) + headerInstallPaths = append(headerInstallPaths, m.installPaths...) installPaths = append(installPaths, m.installPaths...) licensePaths = append(licensePaths, m.licensePath) } if m, ok := module.(*preprocessedHeadersModule); ok { - headerPaths = append(headerPaths, m.installPaths...) + headerSrcPaths = append(headerSrcPaths, m.srcPaths...) + headerInstallPaths = append(headerInstallPaths, m.installPaths...) installPaths = append(installPaths, m.installPaths...) licensePaths = append(licensePaths, m.licensePath) } @@ -175,9 +220,11 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { ctx.Build(pctx, android.BuildParams{ Rule: android.Touch, Output: getNdkHeadersTimestampFile(ctx), - Implicits: headerPaths, + Implicits: headerInstallPaths, }) + writeNdkAbiSrcFilter(ctx, headerSrcPaths, getNdkABIHeadersFile(ctx)) + fullDepPaths := append(staticLibInstallPaths, getNdkBaseTimestampFile(ctx)) // There's a phony "ndk" rule defined in core/main.mk that depends on this. @@ -172,6 +172,7 @@ func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps { // The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have // its own includes. The includes are handled in CCBase.Flags(). deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...) + deps.HeaderLibs = append([]string{"ndk_system"}, deps.HeaderLibs...) case "ndk_libc++_shared", "ndk_libc++_static": if stl.Properties.SelectedStl == "ndk_libc++_shared" { deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl) @@ -219,8 +220,7 @@ func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags { case "libstdc++": // Nothing case "ndk_system": - ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include") - flags.Local.CFlags = append(flags.Local.CFlags, "-isystem "+ndkSrcRoot.String()) + // Nothing: The exports of ndk_system will be added automatically to the local cflags case "ndk_libc++_shared", "ndk_libc++_static": if ctx.Arch().ArchType == android.Arm { // Make sure the _Unwind_XXX symbols are not re-exported. diff --git a/cc/testing.go b/cc/testing.go index d1632aaa6..24d6b0f5f 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -558,7 +558,7 @@ var PrepareForTestWithCcBuildComponents = android.GroupFixturePreparers( // This includes files that are needed by all, or at least most, instances of a cc module type. android.MockFS{ // Needed for ndk_prebuilt_(shared|static)_stl. - "prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs": nil, + "defaults/cc/common/current/sources/cxx-stl/llvm-libc++/libs": nil, }.AddToFixture(), ) diff --git a/filesystem/avb_add_hash_footer.go b/filesystem/avb_add_hash_footer.go index f3fecd042..dabbc461b 100644 --- a/filesystem/avb_add_hash_footer.go +++ b/filesystem/avb_add_hash_footer.go @@ -68,6 +68,9 @@ type avbAddHashFooterProperties struct { // List of properties to add to the footer Props []avbProp + // The index used to prevent rollback of the image on device. + Rollback_index *int64 + // Include descriptors from images Include_descriptors_from_images []string `android:"path,arch_variant"` } @@ -128,6 +131,14 @@ func (a *avbAddHashFooter) GenerateAndroidBuildActions(ctx android.ModuleContext addAvbProp(ctx, cmd, prop) } + if a.properties.Rollback_index != nil { + rollbackIndex := proptools.Int(a.properties.Rollback_index) + if rollbackIndex < 0 { + ctx.PropertyErrorf("rollback_index", "Rollback index must be non-negative") + } + cmd.Flag(fmt.Sprintf(" --rollback_index %x", rollbackIndex)) + } + cmd.FlagWithOutput("--image ", a.output) builder.Build("avbAddHashFooter", fmt.Sprintf("avbAddHashFooter %s", ctx.ModuleName())) diff --git a/java/app.go b/java/app.go index d533b713a..7ee0e3857 100755 --- a/java/app.go +++ b/java/app.go @@ -1632,15 +1632,6 @@ type bazelAndroidAppAttributes struct { // ConvertWithBp2build is used to convert android_app to Bazel. func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { - commonAttrs, bp2BuildInfo, supported := a.convertLibraryAttrsBp2Build(ctx) - if !supported { - return - } - depLabels := bp2BuildInfo.DepLabels - - deps := depLabels.Deps - deps.Append(depLabels.StaticDeps) - aapt, supported := a.convertAaptAttrsWithBp2Build(ctx) if !supported { return @@ -1711,8 +1702,16 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { }) appAttrs.Proguard_specs.Add(bazel.MakeLabelAttribute(":" + generatedFlagFileRuleName)) } + } + commonAttrs, bp2BuildInfo, supported := a.convertLibraryAttrsBp2Build(ctx) + if !supported { + return } + depLabels := bp2BuildInfo.DepLabels + + deps := depLabels.Deps + deps.Append(depLabels.StaticDeps) props := bazel.BazelTargetModuleProperties{ Rule_class: "android_binary", diff --git a/java/app_import.go b/java/app_import.go index 1718d936c..c5d09fdf1 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -19,6 +19,7 @@ package java import ( "fmt" "reflect" + "strings" "github.com/google/blueprint" @@ -51,27 +52,11 @@ var ( Description: "Uncompress dex files", }) - checkDexLibsAreUncompressedRule = pctx.AndroidStaticRule("check-dex-libs-are-uncompressed", blueprint.RuleParams{ - // grep -v ' stor ' will search for lines that don't have ' stor '. stor means the file is stored uncompressed - Command: "if (zipinfo $in '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then " + - "echo $in: Contains compressed JNI libraries and/or dex files >&2;" + - "exit 1; " + - "else " + - "touch $out; " + - "fi", - Description: "Check for compressed JNI libs or dex files", - }) - - checkJniLibsAreUncompressedRule = pctx.AndroidStaticRule("check-jni-libs-are-uncompressed", blueprint.RuleParams{ - // grep -v ' stor ' will search for lines that don't have ' stor '. stor means the file is stored uncompressed - Command: "if (zipinfo $in 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then " + - "echo $in: Contains compressed JNI libraries >&2;" + - "exit 1; " + - "else " + - "touch $out; " + - "fi", - Description: "Check for compressed JNI libs or dex files", - }) + checkPresignedApkRule = pctx.AndroidStaticRule("check-presigned-apk", blueprint.RuleParams{ + Command: "build/soong/scripts/check_prebuilt_presigned_apk.py --aapt2 ${config.Aapt2Cmd} --zipalign ${config.ZipAlign} $extraArgs $in $out", + CommandDeps: []string{"build/soong/scripts/check_prebuilt_presigned_apk.py", "${config.Aapt2Cmd}", "${config.ZipAlign}"}, + Description: "Check presigned apk", + }, "extraArgs") ) func RegisterAppImportBuildComponents(ctx android.RegistrationContext) { @@ -352,20 +337,14 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext // Sign or align the package if package has not been preprocessed if proptools.Bool(a.properties.Preprocessed) { - var output android.WritablePath - if !proptools.Bool(a.properties.Skip_preprocessed_apk_checks) { - output = android.PathForModuleOut(ctx, "validated-prebuilt", apkFilename) - a.validatePreprocessedApk(ctx, srcApk, output) - } else { - // If using the input APK unmodified, still make a copy of it so that the output filename has the - // right basename. - output = android.PathForModuleOut(ctx, apkFilename) - ctx.Build(pctx, android.BuildParams{ - Rule: android.Cp, - Input: srcApk, - Output: output, - }) - } + validationStamp := a.validatePresignedApk(ctx, srcApk) + output := android.PathForModuleOut(ctx, apkFilename) + ctx.Build(pctx, android.BuildParams{ + Rule: android.Cp, + Input: srcApk, + Output: output, + Validation: validationStamp, + }) a.outputFile = output a.certificate = PresignedCertificate } else if !Bool(a.properties.Presigned) { @@ -384,13 +363,9 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext SignAppPackage(ctx, signed, jnisUncompressed, certificates, nil, lineageFile, rotationMinSdkVersion) a.outputFile = signed } else { - // Presigned without Preprocessed shouldn't really be a thing, currently we disallow - // it for apps with targetSdk >= 30, because on those targetSdks you must be using signature - // v2 or later, and signature v2 would be wrecked by uncompressing libs / zipaligning. - // But ideally we would disallow it for all prebuilt apks, and remove the presigned property. - targetSdkCheck := a.validateTargetSdkLessThan30(ctx, srcApk) + validationStamp := a.validatePresignedApk(ctx, srcApk) alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename) - TransformZipAlign(ctx, alignedApk, jnisUncompressed, []android.Path{targetSdkCheck}) + TransformZipAlign(ctx, alignedApk, jnisUncompressed, []android.Path{validationStamp}) a.outputFile = alignedApk a.certificate = PresignedCertificate } @@ -406,52 +381,28 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext // TODO: androidmk converter jni libs } -func (a *AndroidAppImport) validatePreprocessedApk(ctx android.ModuleContext, srcApk android.Path, dstApk android.WritablePath) { - var validations android.Paths - - alignmentStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "alignment.stamp") - ctx.Build(pctx, android.BuildParams{ - Rule: checkZipAlignment, - Input: srcApk, - Output: alignmentStamp, - }) - - validations = append(validations, alignmentStamp) - jniCompressionStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "jni_compression.stamp") - ctx.Build(pctx, android.BuildParams{ - Rule: checkJniLibsAreUncompressedRule, - Input: srcApk, - Output: jniCompressionStamp, - }) - validations = append(validations, jniCompressionStamp) - +func (a *AndroidAppImport) validatePresignedApk(ctx android.ModuleContext, srcApk android.Path) android.Path { + stamp := android.PathForModuleOut(ctx, "validated-prebuilt", "check.stamp") + var extraArgs []string if a.Privileged() { - // It's ok for non-privileged apps to have compressed dex files, see go/gms-uncompressed-jni-slides - dexCompressionStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "dex_compression.stamp") - ctx.Build(pctx, android.BuildParams{ - Rule: checkDexLibsAreUncompressedRule, - Input: srcApk, - Output: dexCompressionStamp, - }) - validations = append(validations, dexCompressionStamp) + extraArgs = append(extraArgs, "--privileged") + } + if proptools.Bool(a.properties.Skip_preprocessed_apk_checks) { + extraArgs = append(extraArgs, "--skip-preprocessed-apk-checks") + } + if proptools.Bool(a.properties.Preprocessed) { + extraArgs = append(extraArgs, "--preprocessed") } ctx.Build(pctx, android.BuildParams{ - Rule: android.Cp, - Input: srcApk, - Output: dstApk, - Validations: validations, - }) -} - -func (a *AndroidAppImport) validateTargetSdkLessThan30(ctx android.ModuleContext, srcApk android.Path) android.Path { - alignmentStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "old_target_sdk.stamp") - ctx.Build(pctx, android.BuildParams{ - Rule: checkBelowTargetSdk30ForNonPreprocessedApks, + Rule: checkPresignedApkRule, Input: srcApk, - Output: alignmentStamp, + Output: stamp, + Args: map[string]string{ + "extraArgs": strings.Join(extraArgs, " "), + }, }) - return alignmentStamp + return stamp } func (a *AndroidAppImport) Prebuilt() *android.Prebuilt { diff --git a/java/app_import_test.go b/java/app_import_test.go index 506c7344b..8f29bb373 100644 --- a/java/app_import_test.go +++ b/java/app_import_test.go @@ -659,14 +659,19 @@ func TestAndroidAppImport_Preprocessed(t *testing.T) { apkName := "foo.apk" variant := ctx.ModuleForTests("foo", "android_common") - outputBuildParams := variant.Output("validated-prebuilt/" + apkName).BuildParams + outputBuildParams := variant.Output(apkName).BuildParams if outputBuildParams.Rule.String() != android.Cp.String() { t.Errorf("Unexpected prebuilt android_app_import rule: " + outputBuildParams.Rule.String()) } // Make sure compression and aligning were validated. - if len(outputBuildParams.Validations) != 2 { - t.Errorf("Expected compression/alignment validation rules, found %d validations", len(outputBuildParams.Validations)) + if outputBuildParams.Validation == nil { + t.Errorf("Expected validation rule, but was not found") + } + + validationBuildParams := variant.Output("validated-prebuilt/check.stamp").BuildParams + if validationBuildParams.Rule.String() != checkPresignedApkRule.String() { + t.Errorf("Unexpected validation rule: " + validationBuildParams.Rule.String()) } } diff --git a/java/builder.go b/java/builder.go index bf919175d..ee7e225a8 100644 --- a/java/builder.go +++ b/java/builder.go @@ -259,32 +259,11 @@ var ( }, ) - checkZipAlignment = pctx.AndroidStaticRule("checkzipalign", - blueprint.RuleParams{ - Command: "if ! ${config.ZipAlign} -c -p 4 $in > /dev/null; then " + - "echo $in: Improper package alignment >&2; " + - "exit 1; " + - "else " + - "touch $out; " + - "fi", - CommandDeps: []string{"${config.ZipAlign}"}, - Description: "Check zip alignment", - }, - ) - convertImplementationJarToHeaderJarRule = pctx.AndroidStaticRule("convertImplementationJarToHeaderJar", blueprint.RuleParams{ Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} -x 'META-INF/services/**/*'`, CommandDeps: []string{"${config.Zip2ZipCmd}"}, }) - - checkBelowTargetSdk30ForNonPreprocessedApks = pctx.AndroidStaticRule("checkBelowTargetSdk30ForNonPreprocessedApks", - blueprint.RuleParams{ - Command: "build/soong/scripts/check_target_sdk_less_than_30.py ${config.Aapt2Cmd} $in $out", - CommandDeps: []string{"build/soong/scripts/check_target_sdk_less_than_30.py", "${config.Aapt2Cmd}"}, - Description: "Check prebuilt target sdk version", - }, - ) ) func init() { diff --git a/java/droiddoc.go b/java/droiddoc.go index 3ba306554..fe0643a78 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -22,6 +22,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/bazel" "android/soong/java/config" ) @@ -844,6 +845,7 @@ type ExportedDroiddocDirProperties struct { type ExportedDroiddocDir struct { android.ModuleBase + android.BazelModuleBase properties ExportedDroiddocDirProperties @@ -856,6 +858,7 @@ func ExportedDroiddocDirFactory() android.Module { module := &ExportedDroiddocDir{} module.AddProperties(&module.properties) android.InitAndroidModule(module) + android.InitBazelModule(module) return module } @@ -867,6 +870,28 @@ func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleCont d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")}) } +// ConvertWithBp2build implements android.BazelModule. +func (d *ExportedDroiddocDir) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + props := bazel.BazelTargetModuleProperties{ + // Use the native py_library rule. + Rule_class: "droiddoc_exported_dir", + Bzl_load_location: "//build/bazel/rules/droiddoc:droiddoc_exported_dir.bzl", + } + + type BazelAttrs struct { + Dir *string + Srcs bazel.LabelListAttribute + } + + attrs := &BazelAttrs{ + Dir: proptools.StringPtr(*d.properties.Path), + Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, []string{filepath.Join(*d.properties.Path, "**/*")})), + } + + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: d.Name()}, attrs) + +} + // Defaults type DocDefaults struct { android.ModuleBase diff --git a/java/droidstubs.go b/java/droidstubs.go index f05ef1fdd..1d5dd7624 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -539,7 +539,7 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi // Force metalava to sort overloaded methods by their order in the source code. // See b/285312164 for more information. - cmd.FlagWithArg("--api-overloaded-method-order ", "source") + cmd.FlagWithArg("--format-defaults ", "overloaded-method-order=source") return cmd } diff --git a/java/java.go b/java/java.go index 99bb1b3ee..270f45615 100644 --- a/java/java.go +++ b/java/java.go @@ -1798,6 +1798,7 @@ func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.Ru Flag("-jar"). Flag("-write_if_changed"). Flag("-ignore_missing_files"). + Flag("-quiet"). FlagWithArg("-C ", unzippedSrcJarDir.String()). FlagWithInput("-l ", classFilesList). FlagWithOutput("-o ", al.stubsJarWithoutStaticLibs) @@ -2885,8 +2886,9 @@ type javaAidlLibraryAttributes struct { // depending on the module type. type bp2BuildJavaInfo struct { // separates dependencies into dynamic dependencies and static dependencies. - DepLabels *javaDependencyLabels - hasKotlin bool + DepLabels *javaDependencyLabels + hasKotlin bool + onlyProtoInSrcs bool } func javaXsdTargetName(xsd android.XsdConfigBp2buildTargets) string { @@ -2949,6 +2951,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) staticDeps.Append(srcPartitions[xsdSrcPartition]) + _, protoInSrcs := srcPartitions[protoSrcPartition] + onlyProtoInSrcs := protoInSrcs && len(srcPartitions) == 1 + if !srcPartitions[logtagSrcPartition].IsEmpty() { logtagsLibName := m.Name() + "_logtags" ctx.CreateBazelTargetModule( @@ -3086,8 +3091,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) } bp2BuildInfo := &bp2BuildJavaInfo{ - DepLabels: depLabels, - hasKotlin: hasKotlin, + DepLabels: depLabels, + hasKotlin: hasKotlin, + onlyProtoInSrcs: onlyProtoInSrcs, } return commonAttrs, bp2BuildInfo, true @@ -3127,16 +3133,29 @@ func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { depLabels := bp2BuildInfo.DepLabels deps := depLabels.Deps + exports := depLabels.StaticDeps if !commonAttrs.Srcs.IsEmpty() { - deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them + deps.Append(exports) // we should only append these if there are sources to use them } else if !deps.IsEmpty() { - ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") + if bp2BuildInfo.onlyProtoInSrcs { + // java_library does not accept deps when there are no srcs because + // there is no compilation happening, but it accepts exports. + // bp2build converts this module to 2 java_libraries + java_xx_proto_library + proto_library + // the non-empty deps here are not necessary for compiling the protos, in which case + // they're unnecessary as deps on the java_library as well since they aren't + // being propagated to any dependencies. + // so we can put the deps to exports and drop deps here. + exports.Append(deps) + deps = bazel.LabelListAttribute{} + } else { + ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") + } } var props bazel.BazelTargetModuleProperties attrs := &javaLibraryAttributes{ javaCommonAttributes: commonAttrs, Deps: deps, - Exports: depLabels.StaticDeps, + Exports: exports, } name := m.Name() diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go index 08ac2ef7d..564168b9e 100644 --- a/rust/config/arm64_device.go +++ b/rust/config/arm64_device.go @@ -21,7 +21,9 @@ import ( ) var ( - Arm64RustFlags = []string{} + Arm64RustFlags = []string{ + "-C force-frame-pointers=y", + } Arm64ArchFeatureRustFlags = map[string][]string{} Arm64LinkFlags = []string{} diff --git a/rust/config/global.go b/rust/config/global.go index 4bd495d86..c976617f1 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -25,7 +25,7 @@ var ( pctx = android.NewPackageContext("android/soong/rust/config") exportedVars = android.NewExportedVariables(pctx) - RustDefaultVersion = "1.71.0" + RustDefaultVersion = "1.72.0" RustDefaultBase = "prebuilts/rust/" DefaultEdition = "2021" Stdlibs = []string{ diff --git a/rust/config/riscv64_device.go b/rust/config/riscv64_device.go index d014dbf8b..e9aa8ef61 100644 --- a/rust/config/riscv64_device.go +++ b/rust/config/riscv64_device.go @@ -21,7 +21,9 @@ import ( ) var ( - Riscv64RustFlags = []string{} + Riscv64RustFlags = []string{ + "-C force-frame-pointers=y", + } Riscv64ArchFeatureRustFlags = map[string][]string{"": {}} Riscv64LinkFlags = []string{} diff --git a/rust/config/x86_64_device.go b/rust/config/x86_64_device.go index 3458ec900..45d1fd0a1 100644 --- a/rust/config/x86_64_device.go +++ b/rust/config/x86_64_device.go @@ -21,7 +21,9 @@ import ( ) var ( - x86_64RustFlags = []string{} + x86_64RustFlags = []string{ + "-C force-frame-pointers=y", + } x86_64ArchFeatureRustFlags = map[string][]string{} x86_64LinkFlags = []string{} diff --git a/scripts/check_prebuilt_presigned_apk.py b/scripts/check_prebuilt_presigned_apk.py new file mode 100755 index 000000000..abedfb770 --- /dev/null +++ b/scripts/check_prebuilt_presigned_apk.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 + +import subprocess +import argparse +import re +import sys +import zipfile + +def check_target_sdk_less_than_30(args): + if not args.aapt2: + sys.exit('--aapt2 is required') + regex = re.compile(r"targetSdkVersion: *'([0-9]+)'") + output = subprocess.check_output([args.aapt2, "dump", "badging", args.apk], text=True) + targetSdkVersion = None + for line in output.splitlines(): + match = regex.fullmatch(line.strip()) + if match: + targetSdkVersion = int(match.group(1)) + break + + if targetSdkVersion is None or targetSdkVersion >= 30: + sys.exit(args.apk + ": Prebuilt, presigned apks with targetSdkVersion >= 30 (or a codename targetSdkVersion) must set preprocessed: true in the Android.bp definition (because they must be signed with signature v2, and the build system would wreck that signature otherwise)") + +def has_preprocessed_issues(args, *, fail=False): + if not args.zipalign: + sys.exit('--zipalign is required') + ret = subprocess.run([args.zipalign, '-c', '-p', '4', args.apk], stdout=subprocess.DEVNULL).returncode + if ret != 0: + if fail: + sys.exit(args.apk + ': Improper zip alignment') + return True + + with zipfile.ZipFile(args.apk) as zf: + for info in zf.infolist(): + if info.filename.startswith('lib/') and info.filename.endswith('.so') and info.compress_type != zipfile.ZIP_STORED: + if fail: + sys.exit(args.apk + ': Contains compressed JNI libraries') + return True + # It's ok for non-privileged apps to have compressed dex files, see go/gms-uncompressed-jni-slides + if args.privileged: + if info.filename.endswith('.dex') and info.compress_type != zipfile.ZIP_STORED: + if fail: + sys.exit(args.apk + ': Contains compressed dex files and is privileged') + return True + return False + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--aapt2', help = "the path to the aapt2 executable") + parser.add_argument('--zipalign', help = "the path to the zipalign executable") + parser.add_argument('--skip-preprocessed-apk-checks', action = 'store_true', help = "the value of the soong property with the same name") + parser.add_argument('--preprocessed', action = 'store_true', help = "the value of the soong property with the same name") + parser.add_argument('--privileged', action = 'store_true', help = "the value of the soong property with the same name") + parser.add_argument('apk', help = "the apk to check") + parser.add_argument('stampfile', help = "a file to touch if successful") + args = parser.parse_args() + + if not args.preprocessed: + check_target_sdk_less_than_30(args) + elif args.skip_preprocessed_apk_checks: + if not has_preprocessed_issues(args): + sys.exit('This module sets `skip_preprocessed_apk_checks: true`, but does not actually have any issues. Please remove `skip_preprocessed_apk_checks`.') + else: + has_preprocessed_issues(args, fail=True) + + subprocess.check_call(["touch", args.stampfile]) + +if __name__ == "__main__": + main() diff --git a/scripts/check_target_sdk_less_than_30.py b/scripts/check_target_sdk_less_than_30.py deleted file mode 100755 index 69b0bf011..000000000 --- a/scripts/check_target_sdk_less_than_30.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 - -import subprocess -import argparse -import re -import sys - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument('aapt2', help = "the path to the aapt2 executable") - parser.add_argument('apk', help = "the apk to check") - parser.add_argument('stampfile', help = "a file to touch if successful") - args = parser.parse_args() - - regex = re.compile(r"targetSdkVersion: *'([0-9]+)'") - output = subprocess.check_output([args.aapt2, "dump", "badging", args.apk], text=True) - targetSdkVersion = None - for line in output.splitlines(): - match = regex.fullmatch(line.strip()) - if match: - targetSdkVersion = int(match.group(1)) - break - - if targetSdkVersion is None or targetSdkVersion >= 30: - sys.exit(args.apk + ": Prebuilt, presigned apks with targetSdkVersion >= 30 (or a codename targetSdkVersion) must set preprocessed: true in the Android.bp definition (because they must be signed with signature v2, and the build system would wreck that signature otherwise)") - - subprocess.check_call(["touch", args.stampfile]) - -if __name__ == "__main__": - main() diff --git a/scripts/conv_linker_config.py b/scripts/conv_linker_config.py index 3ac1b7e5e..c6aa3d0dc 100644 --- a/scripts/conv_linker_config.py +++ b/scripts/conv_linker_config.py @@ -120,6 +120,37 @@ def Merge(args): f.write(pb.SerializeToString()) +def Validate(args): + if os.path.isdir(args.input): + config_file = os.path.join(args.input, 'etc/linker.config.pb') + if os.path.exists(config_file): + args.input = config_file + Validate(args) + # OK if there's no linker config file. + return + + if not os.path.isfile(args.input): + sys.exit(f"{args.input} is not a file") + + pb = linker_config_pb2.LinkerConfig() + with open(args.input, 'rb') as f: + pb.ParseFromString(f.read()) + + if args.type == 'apex': + # Shouldn't use provideLibs/requireLibs in APEX linker.config.pb + if getattr(pb, 'provideLibs'): + sys.exit(f'{args.input}: provideLibs is set. Use provideSharedLibs in apex_manifest') + if getattr(pb, 'requireLibs'): + sys.exit(f'{args.input}: requireLibs is set. Use requireSharedLibs in apex_manifest') + elif args.type == 'system': + if getattr(pb, 'visible'): + sys.exit(f'{args.input}: do not use visible, which is for APEX') + if getattr(pb, 'permittedPaths'): + sys.exit(f'{args.input}: do not use permittedPaths, which is for APEX') + else: + sys.exit(f'Unknown type: {args.type}') + + def GetArgParser(): parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() @@ -227,6 +258,18 @@ def GetArgParser(): help='Linker configuration files to merge.') append.set_defaults(func=Merge) + validate = subparsers.add_parser('validate', help='Validate configuration') + validate.add_argument( + '--type', + required=True, + choices=['apex', 'system'], + help='Type of linker configuration') + validate.add_argument( + 'input', + help='Input can be a directory which has etc/linker.config.pb or a path' + ' to the linker config file') + validate.set_defaults(func=Validate) + return parser diff --git a/ui/build/ninja.go b/ui/build/ninja.go index 61aaad86b..b69e938f8 100644 --- a/ui/build/ninja.go +++ b/ui/build/ninja.go @@ -194,6 +194,10 @@ func runNinjaForBuild(ctx Context, config Config) { // LLVM compiler wrapper options "TOOLCHAIN_RUSAGE_OUTPUT", + + // We don't want this build broken flag to cause reanalysis, so allow it through to the + // actions. + "BUILD_BROKEN_INCORRECT_PARTITION_IMAGES", }, config.BuildBrokenNinjaUsesEnvVars()...)...) } diff --git a/zip/cmd/main.go b/zip/cmd/main.go index 5231faec9..37537ab8b 100644 --- a/zip/cmd/main.go +++ b/zip/cmd/main.go @@ -174,6 +174,7 @@ func main() { traceFile := flags.String("trace", "", "write trace to file") sha256Checksum := flags.Bool("sha256", false, "add a zip header to each file containing its SHA256 digest") doNotWrite := flags.Bool("n", false, "Nothing is written to disk -- all other work happens") + quiet := flags.Bool("quiet", false, "do not print warnings to console") flags.Var(&rootPrefix{}, "P", "path prefix within the zip at which to place files") flags.Var(&listFiles{}, "l", "file containing list of files to zip") @@ -238,6 +239,7 @@ func main() { IgnoreMissingFiles: *ignoreMissingFiles, Sha256Checksum: *sha256Checksum, DoNotWrite: *doNotWrite, + Quiet: *quiet, }) if err != nil { fmt.Fprintln(os.Stderr, "error:", err.Error()) diff --git a/zip/zip.go b/zip/zip.go index 30a2ee762..f91a5f2cb 100644 --- a/zip/zip.go +++ b/zip/zip.go @@ -283,6 +283,7 @@ type ZipArgs struct { IgnoreMissingFiles bool Sha256Checksum bool DoNotWrite bool + Quiet bool Stderr io.Writer Filesystem pathtools.FileSystem @@ -340,7 +341,9 @@ func zipTo(args ZipArgs, w io.Writer) error { Err: os.ErrNotExist, } if args.IgnoreMissingFiles { - fmt.Fprintln(z.stderr, "warning:", err) + if !args.Quiet { + fmt.Fprintln(z.stderr, "warning:", err) + } } else { return err } @@ -357,7 +360,9 @@ func zipTo(args ZipArgs, w io.Writer) error { Err: os.ErrNotExist, } if args.IgnoreMissingFiles { - fmt.Fprintln(z.stderr, "warning:", err) + if !args.Quiet { + fmt.Fprintln(z.stderr, "warning:", err) + } } else { return err } @@ -368,7 +373,9 @@ func zipTo(args ZipArgs, w io.Writer) error { Err: syscall.ENOTDIR, } if args.IgnoreMissingFiles { - fmt.Fprintln(z.stderr, "warning:", err) + if !args.Quiet { + fmt.Fprintln(z.stderr, "warning:", err) + } } else { return err } |