1// Copyright (C) 2018 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package apex 16 17import ( 18 "fmt" 19 "path/filepath" 20 "sort" 21 "strings" 22 "sync" 23 24 "github.com/google/blueprint" 25 "github.com/google/blueprint/bootstrap" 26 "github.com/google/blueprint/proptools" 27 28 "android/soong/android" 29 "android/soong/cc" 30 prebuilt_etc "android/soong/etc" 31 "android/soong/java" 32 "android/soong/python" 33 "android/soong/sh" 34) 35 36const ( 37 imageApexSuffix = ".apex" 38 zipApexSuffix = ".zipapex" 39 flattenedSuffix = ".flattened" 40 41 imageApexType = "image" 42 zipApexType = "zip" 43 flattenedApexType = "flattened" 44) 45 46type dependencyTag struct { 47 blueprint.BaseDependencyTag 48 name string 49 50 // determines if the dependent will be part of the APEX payload 51 payload bool 52} 53 54var ( 55 sharedLibTag = dependencyTag{name: "sharedLib", payload: true} 56 jniLibTag = dependencyTag{name: "jniLib", payload: true} 57 executableTag = dependencyTag{name: "executable", payload: true} 58 javaLibTag = dependencyTag{name: "javaLib", payload: true} 59 prebuiltTag = dependencyTag{name: "prebuilt", payload: true} 60 testTag = dependencyTag{name: "test", payload: true} 61 keyTag = dependencyTag{name: "key"} 62 certificateTag = dependencyTag{name: "certificate"} 63 usesTag = dependencyTag{name: "uses"} 64 androidAppTag = dependencyTag{name: "androidApp", payload: true} 65 rroTag = dependencyTag{name: "rro", payload: true} 66 67 apexAvailBaseline = makeApexAvailableBaseline() 68 69 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline) 70) 71 72// Transform the map of apex -> modules to module -> apexes. 73func invertApexBaseline(m map[string][]string) map[string][]string { 74 r := make(map[string][]string) 75 for apex, modules := range m { 76 for _, module := range modules { 77 r[module] = append(r[module], apex) 78 } 79 } 80 return r 81} 82 83// Retrieve the baseline of apexes to which the supplied module belongs. 84func BaselineApexAvailable(moduleName string) []string { 85 return inverseApexAvailBaseline[normalizeModuleName(moduleName)] 86} 87 88// This is a map from apex to modules, which overrides the 89// apex_available setting for that particular module to make 90// it available for the apex regardless of its setting. 91// TODO(b/147364041): remove this 92func makeApexAvailableBaseline() map[string][]string { 93 // The "Module separator"s below are employed to minimize merge conflicts. 94 m := make(map[string][]string) 95 // 96 // Module separator 97 // 98 m["com.android.bluetooth.updatable"] = []string{ 99 "android.hardware.audio.common@5.0", 100 "android.hardware.bluetooth.a2dp@1.0", 101 "android.hardware.bluetooth.audio@2.0", 102 "android.hardware.bluetooth@1.0", 103 "android.hardware.bluetooth@1.1", 104 "android.hardware.graphics.bufferqueue@1.0", 105 "android.hardware.graphics.bufferqueue@2.0", 106 "android.hardware.graphics.common@1.0", 107 "android.hardware.graphics.common@1.1", 108 "android.hardware.graphics.common@1.2", 109 "android.hardware.media@1.0", 110 "android.hidl.safe_union@1.0", 111 "android.hidl.token@1.0", 112 "android.hidl.token@1.0-utils", 113 "avrcp-target-service", 114 "avrcp_headers", 115 "bluetooth-protos-lite", 116 "bluetooth.mapsapi", 117 "com.android.vcard", 118 "dnsresolver_aidl_interface-V2-java", 119 "ipmemorystore-aidl-interfaces-V5-java", 120 "ipmemorystore-aidl-interfaces-java", 121 "internal_include_headers", 122 "lib-bt-packets", 123 "lib-bt-packets-avrcp", 124 "lib-bt-packets-base", 125 "libFraunhoferAAC", 126 "libaudio-a2dp-hw-utils", 127 "libaudio-hearing-aid-hw-utils", 128 "libbinder_headers", 129 "libbluetooth", 130 "libbluetooth-types", 131 "libbluetooth-types-header", 132 "libbluetooth_gd", 133 "libbluetooth_headers", 134 "libbluetooth_jni", 135 "libbt-audio-hal-interface", 136 "libbt-bta", 137 "libbt-common", 138 "libbt-hci", 139 "libbt-platform-protos-lite", 140 "libbt-protos-lite", 141 "libbt-sbc-decoder", 142 "libbt-sbc-encoder", 143 "libbt-stack", 144 "libbt-utils", 145 "libbtcore", 146 "libbtdevice", 147 "libbte", 148 "libbtif", 149 "libchrome", 150 "libevent", 151 "libfmq", 152 "libg722codec", 153 "libgui_headers", 154 "libmedia_headers", 155 "libmodpb64", 156 "libosi", 157 "libstagefright_foundation_headers", 158 "libstagefright_headers", 159 "libstatslog", 160 "libstatssocket", 161 "libtinyxml2", 162 "libudrv-uipc", 163 "libz", 164 "media_plugin_headers", 165 "net-utils-services-common", 166 "netd_aidl_interface-unstable-java", 167 "netd_event_listener_interface-java", 168 "netlink-client", 169 "networkstack-client", 170 "sap-api-java-static", 171 "services.net", 172 } 173 // 174 // Module separator 175 // 176 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"} 177 // 178 // Module separator 179 // 180 m["com.android.neuralnetworks"] = []string{ 181 "android.hardware.neuralnetworks@1.0", 182 "android.hardware.neuralnetworks@1.1", 183 "android.hardware.neuralnetworks@1.2", 184 "android.hardware.neuralnetworks@1.3", 185 "android.hidl.allocator@1.0", 186 "android.hidl.memory.token@1.0", 187 "android.hidl.memory@1.0", 188 "android.hidl.safe_union@1.0", 189 "libarect", 190 "libbuildversion", 191 "libmath", 192 "libprocpartition", 193 "libsync", 194 } 195 // 196 // Module separator 197 // 198 m["com.android.media"] = []string{ 199 "android.frameworks.bufferhub@1.0", 200 "android.hardware.cas.native@1.0", 201 "android.hardware.cas@1.0", 202 "android.hardware.configstore-utils", 203 "android.hardware.configstore@1.0", 204 "android.hardware.configstore@1.1", 205 "android.hardware.graphics.allocator@2.0", 206 "android.hardware.graphics.allocator@3.0", 207 "android.hardware.graphics.bufferqueue@1.0", 208 "android.hardware.graphics.bufferqueue@2.0", 209 "android.hardware.graphics.common@1.0", 210 "android.hardware.graphics.common@1.1", 211 "android.hardware.graphics.common@1.2", 212 "android.hardware.graphics.mapper@2.0", 213 "android.hardware.graphics.mapper@2.1", 214 "android.hardware.graphics.mapper@3.0", 215 "android.hardware.media.omx@1.0", 216 "android.hardware.media@1.0", 217 "android.hidl.allocator@1.0", 218 "android.hidl.memory.token@1.0", 219 "android.hidl.memory@1.0", 220 "android.hidl.token@1.0", 221 "android.hidl.token@1.0-utils", 222 "bionic_libc_platform_headers", 223 "exoplayer2-extractor", 224 "exoplayer2-extractor-annotation-stubs", 225 "gl_headers", 226 "jsr305", 227 "libEGL", 228 "libEGL_blobCache", 229 "libEGL_getProcAddress", 230 "libFLAC", 231 "libFLAC-config", 232 "libFLAC-headers", 233 "libGLESv2", 234 "libaacextractor", 235 "libamrextractor", 236 "libarect", 237 "libaudio_system_headers", 238 "libaudioclient", 239 "libaudioclient_headers", 240 "libaudiofoundation", 241 "libaudiofoundation_headers", 242 "libaudiomanager", 243 "libaudiopolicy", 244 "libaudioutils", 245 "libaudioutils_fixedfft", 246 "libbinder_headers", 247 "libbluetooth-types-header", 248 "libbufferhub", 249 "libbufferhub_headers", 250 "libbufferhubqueue", 251 "libc_malloc_debug_backtrace", 252 "libcamera_client", 253 "libcamera_metadata", 254 "libdexfile_external_headers", 255 "libdexfile_support", 256 "libdvr_headers", 257 "libexpat", 258 "libfifo", 259 "libflacextractor", 260 "libgrallocusage", 261 "libgraphicsenv", 262 "libgui", 263 "libgui_headers", 264 "libhardware_headers", 265 "libinput", 266 "liblzma", 267 "libmath", 268 "libmedia", 269 "libmedia_codeclist", 270 "libmedia_headers", 271 "libmedia_helper", 272 "libmedia_helper_headers", 273 "libmedia_midiiowrapper", 274 "libmedia_omx", 275 "libmediautils", 276 "libmidiextractor", 277 "libmkvextractor", 278 "libmp3extractor", 279 "libmp4extractor", 280 "libmpeg2extractor", 281 "libnativebase_headers", 282 "libnativebridge-headers", 283 "libnativebridge_lazy", 284 "libnativeloader-headers", 285 "libnativeloader_lazy", 286 "libnativewindow_headers", 287 "libnblog", 288 "liboggextractor", 289 "libpackagelistparser", 290 "libpdx", 291 "libpdx_default_transport", 292 "libpdx_headers", 293 "libpdx_uds", 294 "libprocinfo", 295 "libsonivox", 296 "libspeexresampler", 297 "libspeexresampler", 298 "libstagefright_esds", 299 "libstagefright_flacdec", 300 "libstagefright_flacdec", 301 "libstagefright_foundation", 302 "libstagefright_foundation_headers", 303 "libstagefright_foundation_without_imemory", 304 "libstagefright_headers", 305 "libstagefright_id3", 306 "libstagefright_metadatautils", 307 "libstagefright_mpeg2extractor", 308 "libstagefright_mpeg2support", 309 "libsync", 310 "libui", 311 "libui_headers", 312 "libunwindstack", 313 "libvibrator", 314 "libvorbisidec", 315 "libwavextractor", 316 "libwebm", 317 "media_ndk_headers", 318 "media_plugin_headers", 319 "updatable-media", 320 } 321 // 322 // Module separator 323 // 324 m["com.android.media.swcodec"] = []string{ 325 "android.frameworks.bufferhub@1.0", 326 "android.hardware.common-ndk_platform", 327 "android.hardware.configstore-utils", 328 "android.hardware.configstore@1.0", 329 "android.hardware.configstore@1.1", 330 "android.hardware.graphics.allocator@2.0", 331 "android.hardware.graphics.allocator@3.0", 332 "android.hardware.graphics.bufferqueue@1.0", 333 "android.hardware.graphics.bufferqueue@2.0", 334 "android.hardware.graphics.common-ndk_platform", 335 "android.hardware.graphics.common@1.0", 336 "android.hardware.graphics.common@1.1", 337 "android.hardware.graphics.common@1.2", 338 "android.hardware.graphics.mapper@2.0", 339 "android.hardware.graphics.mapper@2.1", 340 "android.hardware.graphics.mapper@3.0", 341 "android.hardware.graphics.mapper@4.0", 342 "android.hardware.media.bufferpool@2.0", 343 "android.hardware.media.c2@1.0", 344 "android.hardware.media.omx@1.0", 345 "android.hardware.media@1.0", 346 "android.hardware.media@1.0", 347 "android.hidl.memory.token@1.0", 348 "android.hidl.memory@1.0", 349 "android.hidl.safe_union@1.0", 350 "android.hidl.token@1.0", 351 "android.hidl.token@1.0-utils", 352 "libEGL", 353 "libFLAC", 354 "libFLAC-config", 355 "libFLAC-headers", 356 "libFraunhoferAAC", 357 "libLibGuiProperties", 358 "libarect", 359 "libaudio_system_headers", 360 "libaudioutils", 361 "libaudioutils", 362 "libaudioutils_fixedfft", 363 "libavcdec", 364 "libavcenc", 365 "libavservices_minijail", 366 "libavservices_minijail", 367 "libbinder_headers", 368 "libbinderthreadstateutils", 369 "libbluetooth-types-header", 370 "libbufferhub_headers", 371 "libcodec2", 372 "libcodec2_headers", 373 "libcodec2_hidl@1.0", 374 "libcodec2_hidl@1.1", 375 "libcodec2_internal", 376 "libcodec2_soft_aacdec", 377 "libcodec2_soft_aacenc", 378 "libcodec2_soft_amrnbdec", 379 "libcodec2_soft_amrnbenc", 380 "libcodec2_soft_amrwbdec", 381 "libcodec2_soft_amrwbenc", 382 "libcodec2_soft_av1dec_gav1", 383 "libcodec2_soft_avcdec", 384 "libcodec2_soft_avcenc", 385 "libcodec2_soft_common", 386 "libcodec2_soft_flacdec", 387 "libcodec2_soft_flacenc", 388 "libcodec2_soft_g711alawdec", 389 "libcodec2_soft_g711mlawdec", 390 "libcodec2_soft_gsmdec", 391 "libcodec2_soft_h263dec", 392 "libcodec2_soft_h263enc", 393 "libcodec2_soft_hevcdec", 394 "libcodec2_soft_hevcenc", 395 "libcodec2_soft_mp3dec", 396 "libcodec2_soft_mpeg2dec", 397 "libcodec2_soft_mpeg4dec", 398 "libcodec2_soft_mpeg4enc", 399 "libcodec2_soft_opusdec", 400 "libcodec2_soft_opusenc", 401 "libcodec2_soft_rawdec", 402 "libcodec2_soft_vorbisdec", 403 "libcodec2_soft_vp8dec", 404 "libcodec2_soft_vp8enc", 405 "libcodec2_soft_vp9dec", 406 "libcodec2_soft_vp9enc", 407 "libcodec2_vndk", 408 "libdexfile_support", 409 "libdvr_headers", 410 "libfmq", 411 "libfmq", 412 "libgav1", 413 "libgralloctypes", 414 "libgrallocusage", 415 "libgraphicsenv", 416 "libgsm", 417 "libgui_bufferqueue_static", 418 "libgui_headers", 419 "libhardware", 420 "libhardware_headers", 421 "libhevcdec", 422 "libhevcenc", 423 "libion", 424 "libjpeg", 425 "liblzma", 426 "libmath", 427 "libmedia_codecserviceregistrant", 428 "libmedia_headers", 429 "libmpeg2dec", 430 "libnativebase_headers", 431 "libnativebridge_lazy", 432 "libnativeloader_lazy", 433 "libnativewindow_headers", 434 "libpdx_headers", 435 "libscudo_wrapper", 436 "libsfplugin_ccodec_utils", 437 "libstagefright_amrnb_common", 438 "libstagefright_amrnbdec", 439 "libstagefright_amrnbenc", 440 "libstagefright_amrwbdec", 441 "libstagefright_amrwbenc", 442 "libstagefright_bufferpool@2.0.1", 443 "libstagefright_bufferqueue_helper", 444 "libstagefright_enc_common", 445 "libstagefright_flacdec", 446 "libstagefright_foundation", 447 "libstagefright_foundation_headers", 448 "libstagefright_headers", 449 "libstagefright_m4vh263dec", 450 "libstagefright_m4vh263enc", 451 "libstagefright_mp3dec", 452 "libsync", 453 "libui", 454 "libui_headers", 455 "libunwindstack", 456 "libvorbisidec", 457 "libvpx", 458 "libyuv", 459 "libyuv_static", 460 "media_ndk_headers", 461 "media_plugin_headers", 462 "mediaswcodec", 463 } 464 // 465 // Module separator 466 // 467 m["com.android.mediaprovider"] = []string{ 468 "MediaProvider", 469 "MediaProviderGoogle", 470 "fmtlib_ndk", 471 "libbase_ndk", 472 "libfuse", 473 "libfuse_jni", 474 } 475 // 476 // Module separator 477 // 478 m["com.android.permission"] = []string{ 479 "kotlin-annotations", 480 "kotlin-stdlib", 481 "kotlin-stdlib-jdk7", 482 "kotlin-stdlib-jdk8", 483 "kotlinx-coroutines-android", 484 "kotlinx-coroutines-android-nodeps", 485 "kotlinx-coroutines-core", 486 "kotlinx-coroutines-core-nodeps", 487 "permissioncontroller-statsd", 488 } 489 // 490 // Module separator 491 // 492 m["com.android.runtime"] = []string{ 493 "bionic_libc_platform_headers", 494 "libarm-optimized-routines-math", 495 "libc_aeabi", 496 "libc_bionic", 497 "libc_bionic_ndk", 498 "libc_bootstrap", 499 "libc_common", 500 "libc_common_shared", 501 "libc_common_static", 502 "libc_dns", 503 "libc_dynamic_dispatch", 504 "libc_fortify", 505 "libc_freebsd", 506 "libc_freebsd_large_stack", 507 "libc_gdtoa", 508 "libc_init_dynamic", 509 "libc_init_static", 510 "libc_jemalloc_wrapper", 511 "libc_netbsd", 512 "libc_nomalloc", 513 "libc_nopthread", 514 "libc_openbsd", 515 "libc_openbsd_large_stack", 516 "libc_openbsd_ndk", 517 "libc_pthread", 518 "libc_static_dispatch", 519 "libc_syscalls", 520 "libc_tzcode", 521 "libc_unwind_static", 522 "libdebuggerd", 523 "libdebuggerd_common_headers", 524 "libdebuggerd_handler_core", 525 "libdebuggerd_handler_fallback", 526 "libdexfile_external_headers", 527 "libdexfile_support", 528 "libdexfile_support_static", 529 "libdl_static", 530 "libjemalloc5", 531 "liblinker_main", 532 "liblinker_malloc", 533 "liblz4", 534 "liblzma", 535 "libprocinfo", 536 "libpropertyinfoparser", 537 "libscudo", 538 "libstdc++", 539 "libsystemproperties", 540 "libtombstoned_client_static", 541 "libunwindstack", 542 "libz", 543 "libziparchive", 544 } 545 // 546 // Module separator 547 // 548 m["com.android.tethering"] = []string{ 549 "android.hardware.tetheroffload.config-V1.0-java", 550 "android.hardware.tetheroffload.control-V1.0-java", 551 "android.hidl.base-V1.0-java", 552 "ipmemorystore-aidl-interfaces-java", 553 "libcgrouprc", 554 "libcgrouprc_format", 555 "libtetherutilsjni", 556 "libvndksupport", 557 "net-utils-framework-common", 558 "netd_aidl_interface-V3-java", 559 "netlink-client", 560 "networkstack-aidl-interfaces-java", 561 "tethering-aidl-interfaces-java", 562 "TetheringApiCurrentLib", 563 } 564 // 565 // Module separator 566 // 567 m["com.android.wifi"] = []string{ 568 "PlatformProperties", 569 "android.hardware.wifi-V1.0-java", 570 "android.hardware.wifi-V1.0-java-constants", 571 "android.hardware.wifi-V1.1-java", 572 "android.hardware.wifi-V1.2-java", 573 "android.hardware.wifi-V1.3-java", 574 "android.hardware.wifi-V1.4-java", 575 "android.hardware.wifi.hostapd-V1.0-java", 576 "android.hardware.wifi.hostapd-V1.1-java", 577 "android.hardware.wifi.hostapd-V1.2-java", 578 "android.hardware.wifi.supplicant-V1.0-java", 579 "android.hardware.wifi.supplicant-V1.1-java", 580 "android.hardware.wifi.supplicant-V1.2-java", 581 "android.hardware.wifi.supplicant-V1.3-java", 582 "android.hidl.base-V1.0-java", 583 "android.hidl.manager-V1.0-java", 584 "android.hidl.manager-V1.1-java", 585 "android.hidl.manager-V1.2-java", 586 "bouncycastle-unbundled", 587 "dnsresolver_aidl_interface-V2-java", 588 "error_prone_annotations", 589 "framework-wifi-pre-jarjar", 590 "framework-wifi-util-lib", 591 "ipmemorystore-aidl-interfaces-V3-java", 592 "ipmemorystore-aidl-interfaces-java", 593 "ksoap2", 594 "libnanohttpd", 595 "libwifi-jni", 596 "net-utils-services-common", 597 "netd_aidl_interface-V2-java", 598 "netd_aidl_interface-unstable-java", 599 "netd_event_listener_interface-java", 600 "netlink-client", 601 "networkstack-client", 602 "services.net", 603 "wifi-lite-protos", 604 "wifi-nano-protos", 605 "wifi-service-pre-jarjar", 606 "wifi-service-resources", 607 } 608 // 609 // Module separator 610 // 611 m["com.android.sdkext"] = []string{ 612 "fmtlib_ndk", 613 "libbase_ndk", 614 "libprotobuf-cpp-lite-ndk", 615 } 616 // 617 // Module separator 618 // 619 m["com.android.os.statsd"] = []string{ 620 "libstatssocket", 621 } 622 // 623 // Module separator 624 // 625 m[android.AvailableToAnyApex] = []string{ 626 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries 627 "androidx", 628 "androidx-constraintlayout_constraintlayout", 629 "androidx-constraintlayout_constraintlayout-nodeps", 630 "androidx-constraintlayout_constraintlayout-solver", 631 "androidx-constraintlayout_constraintlayout-solver-nodeps", 632 "com.google.android.material_material", 633 "com.google.android.material_material-nodeps", 634 635 "libatomic", 636 "libclang_rt", 637 "libgcc_stripped", 638 "libprofile-clang-extras", 639 "libprofile-clang-extras_ndk", 640 "libprofile-extras", 641 "libprofile-extras_ndk", 642 "libunwind_llvm", 643 } 644 return m 645} 646 647func init() { 648 android.RegisterModuleType("apex", BundleFactory) 649 android.RegisterModuleType("apex_test", testApexBundleFactory) 650 android.RegisterModuleType("apex_vndk", vndkApexBundleFactory) 651 android.RegisterModuleType("apex_defaults", defaultsFactory) 652 android.RegisterModuleType("prebuilt_apex", PrebuiltFactory) 653 android.RegisterModuleType("override_apex", overrideApexFactory) 654 android.RegisterModuleType("apex_set", apexSetFactory) 655 656 android.PreDepsMutators(RegisterPreDepsMutators) 657 android.PostDepsMutators(RegisterPostDepsMutators) 658 659 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) { 660 apexFileContextsInfos := apexFileContextsInfos(ctx.Config()) 661 sort.Strings(*apexFileContextsInfos) 662 ctx.Strict("APEX_FILE_CONTEXTS_INFOS", strings.Join(*apexFileContextsInfos, " ")) 663 }) 664} 665 666func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) { 667 ctx.TopDown("apex_vndk", apexVndkMutator).Parallel() 668 ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel() 669} 670 671func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { 672 ctx.TopDown("apex_deps", apexDepsMutator).Parallel() 673 ctx.BottomUp("apex", apexMutator).Parallel() 674 ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel() 675 ctx.BottomUp("apex_uses", apexUsesMutator).Parallel() 676 ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel() 677} 678 679// Mark the direct and transitive dependencies of apex bundles so that they 680// can be built for the apex bundles. 681func apexDepsMutator(mctx android.TopDownMutatorContext) { 682 if !mctx.Module().Enabled() { 683 return 684 } 685 a, ok := mctx.Module().(*apexBundle) 686 if !ok || a.vndkApex { 687 return 688 } 689 apexInfo := android.ApexInfo{ 690 ApexName: mctx.ModuleName(), 691 MinSdkVersion: a.minSdkVersion(mctx), 692 Updatable: a.Updatable(), 693 } 694 695 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface()) 696 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable) 697 if !useVndk && proptools.Bool(a.properties.Use_vndk_as_stable) { 698 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes") 699 return 700 } 701 702 mctx.WalkDeps(func(child, parent android.Module) bool { 703 am, ok := child.(android.ApexModule) 704 if !ok || !am.CanHaveApexVariants() { 705 return false 706 } 707 if !parent.(android.DepIsInSameApex).DepIsInSameApex(mctx, child) { 708 return false 709 } 710 if excludeVndkLibs { 711 if c, ok := child.(*cc.Module); ok && c.IsVndk() { 712 return false 713 } 714 } 715 716 depName := mctx.OtherModuleName(child) 717 // If the parent is apexBundle, this child is directly depended. 718 _, directDep := parent.(*apexBundle) 719 android.UpdateApexDependency(apexInfo, depName, directDep) 720 am.BuildForApex(apexInfo) 721 return true 722 }) 723} 724 725// mark if a module cannot be available to platform. A module cannot be available 726// to platform if 1) it is explicitly marked as not available (i.e. "//apex_available:platform" 727// is absent) or 2) it depends on another module that isn't (or can't be) available to platform 728func markPlatformAvailability(mctx android.BottomUpMutatorContext) { 729 // Host and recovery are not considered as platform 730 if mctx.Host() || mctx.Module().InstallInRecovery() { 731 return 732 } 733 734 if am, ok := mctx.Module().(android.ApexModule); ok { 735 availableToPlatform := am.AvailableFor(android.AvailableToPlatform) 736 737 // In a rare case when a lib is marked as available only to an apex 738 // but the apex doesn't exist. This can happen in a partial manifest branch 739 // like master-art. Currently, libstatssocket in the stats APEX is causing 740 // this problem. 741 // Include the lib in platform because the module SDK that ought to provide 742 // it doesn't exist, so it would otherwise be left out completely. 743 // TODO(b/154888298) remove this by adding those libraries in module SDKS and skipping 744 // this check for libraries provided by SDKs. 745 if !availableToPlatform && !android.InAnyApex(am.Name()) { 746 availableToPlatform = true 747 } 748 749 // If any of the dep is not available to platform, this module is also considered 750 // as being not available to platform even if it has "//apex_available:platform" 751 mctx.VisitDirectDeps(func(child android.Module) { 752 if !am.DepIsInSameApex(mctx, child) { 753 // if the dependency crosses apex boundary, don't consider it 754 return 755 } 756 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() { 757 availableToPlatform = false 758 // TODO(b/154889534) trigger an error when 'am' has "//apex_available:platform" 759 } 760 }) 761 762 // Exception 1: stub libraries and native bridge libraries are always available to platform 763 if cc, ok := mctx.Module().(*cc.Module); ok && 764 (cc.IsStubs() || cc.Target().NativeBridge == android.NativeBridgeEnabled) { 765 availableToPlatform = true 766 } 767 768 // Exception 2: bootstrap bionic libraries are also always available to platform 769 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) { 770 availableToPlatform = true 771 } 772 773 if !availableToPlatform { 774 am.SetNotAvailableForPlatform() 775 } 776 } 777} 778 779// If a module in an APEX depends on a module from an SDK then it needs an APEX 780// specific variant created for it. Refer to sdk.sdkDepsReplaceMutator. 781func inAnySdk(module android.Module) bool { 782 if sa, ok := module.(android.SdkAware); ok { 783 return sa.IsInAnySdk() 784 } 785 786 return false 787} 788 789// Create apex variations if a module is included in APEX(s). 790func apexMutator(mctx android.BottomUpMutatorContext) { 791 if !mctx.Module().Enabled() { 792 return 793 } 794 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() { 795 am.CreateApexVariations(mctx) 796 } else if a, ok := mctx.Module().(*apexBundle); ok && !a.vndkApex { 797 // apex bundle itself is mutated so that it and its modules have same 798 // apex variant. 799 apexBundleName := mctx.ModuleName() 800 mctx.CreateVariations(apexBundleName) 801 } else if o, ok := mctx.Module().(*OverrideApex); ok { 802 apexBundleName := o.GetOverriddenModuleName() 803 if apexBundleName == "" { 804 mctx.ModuleErrorf("base property is not set") 805 return 806 } 807 mctx.CreateVariations(apexBundleName) 808 } 809 810} 811 812var ( 813 apexFileContextsInfosKey = android.NewOnceKey("apexFileContextsInfosKey") 814 apexFileContextsInfosMutex sync.Mutex 815) 816 817func apexFileContextsInfos(config android.Config) *[]string { 818 return config.Once(apexFileContextsInfosKey, func() interface{} { 819 return &[]string{} 820 }).(*[]string) 821} 822 823func addFlattenedFileContextsInfos(ctx android.BaseModuleContext, fileContextsInfo string) { 824 apexFileContextsInfosMutex.Lock() 825 defer apexFileContextsInfosMutex.Unlock() 826 apexFileContextsInfos := apexFileContextsInfos(ctx.Config()) 827 *apexFileContextsInfos = append(*apexFileContextsInfos, fileContextsInfo) 828} 829 830func apexFlattenedMutator(mctx android.BottomUpMutatorContext) { 831 if !mctx.Module().Enabled() { 832 return 833 } 834 if ab, ok := mctx.Module().(*apexBundle); ok { 835 var variants []string 836 switch proptools.StringDefault(ab.properties.Payload_type, "image") { 837 case "image": 838 variants = append(variants, imageApexType, flattenedApexType) 839 case "zip": 840 variants = append(variants, zipApexType) 841 case "both": 842 variants = append(variants, imageApexType, zipApexType, flattenedApexType) 843 default: 844 mctx.PropertyErrorf("type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type) 845 return 846 } 847 848 modules := mctx.CreateLocalVariations(variants...) 849 850 for i, v := range variants { 851 switch v { 852 case imageApexType: 853 modules[i].(*apexBundle).properties.ApexType = imageApex 854 case zipApexType: 855 modules[i].(*apexBundle).properties.ApexType = zipApex 856 case flattenedApexType: 857 modules[i].(*apexBundle).properties.ApexType = flattenedApex 858 if !mctx.Config().FlattenApex() && ab.Platform() { 859 modules[i].(*apexBundle).MakeAsSystemExt() 860 } 861 } 862 } 863 } else if _, ok := mctx.Module().(*OverrideApex); ok { 864 mctx.CreateVariations(imageApexType, flattenedApexType) 865 } 866} 867 868func apexUsesMutator(mctx android.BottomUpMutatorContext) { 869 if ab, ok := mctx.Module().(*apexBundle); ok { 870 mctx.AddFarVariationDependencies(nil, usesTag, ab.properties.Uses...) 871 } 872} 873 874var ( 875 useVendorAllowListKey = android.NewOnceKey("useVendorAllowList") 876) 877 878// useVendorAllowList returns the list of APEXes which are allowed to use_vendor. 879// When use_vendor is used, native modules are built with __ANDROID_VNDK__ and __ANDROID_APEX__, 880// which may cause compatibility issues. (e.g. libbinder) 881// Even though libbinder restricts its availability via 'apex_available' property and relies on 882// yet another macro __ANDROID_APEX_<NAME>__, we restrict usage of "use_vendor:" from other APEX modules 883// to avoid similar problems. 884func useVendorAllowList(config android.Config) []string { 885 return config.Once(useVendorAllowListKey, func() interface{} { 886 return []string{ 887 // swcodec uses "vendor" variants for smaller size 888 "com.android.media.swcodec", 889 "test_com.android.media.swcodec", 890 } 891 }).([]string) 892} 893 894// setUseVendorAllowListForTest overrides useVendorAllowList and must be 895// called before the first call to useVendorAllowList() 896func setUseVendorAllowListForTest(config android.Config, allowList []string) { 897 config.Once(useVendorAllowListKey, func() interface{} { 898 return allowList 899 }) 900} 901 902type ApexNativeDependencies struct { 903 // List of native libraries 904 Native_shared_libs []string 905 906 // List of JNI libraries 907 Jni_libs []string 908 909 // List of native executables 910 Binaries []string 911 912 // List of native tests 913 Tests []string 914} 915 916type apexMultilibProperties struct { 917 // Native dependencies whose compile_multilib is "first" 918 First ApexNativeDependencies 919 920 // Native dependencies whose compile_multilib is "both" 921 Both ApexNativeDependencies 922 923 // Native dependencies whose compile_multilib is "prefer32" 924 Prefer32 ApexNativeDependencies 925 926 // Native dependencies whose compile_multilib is "32" 927 Lib32 ApexNativeDependencies 928 929 // Native dependencies whose compile_multilib is "64" 930 Lib64 ApexNativeDependencies 931} 932 933type apexBundleProperties struct { 934 // Json manifest file describing meta info of this APEX bundle. Default: 935 // "apex_manifest.json" 936 Manifest *string `android:"path"` 937 938 // AndroidManifest.xml file used for the zip container of this APEX bundle. 939 // If unspecified, a default one is automatically generated. 940 AndroidManifest *string `android:"path"` 941 942 // Canonical name of the APEX bundle. Used to determine the path to the activated APEX on 943 // device (/apex/<apex_name>). 944 // If unspecified, defaults to the value of name. 945 Apex_name *string 946 947 // Determines the file contexts file for setting security context to each file in this APEX bundle. 948 // For platform APEXes, this should points to a file under /system/sepolicy 949 // Default: /system/sepolicy/apex/<module_name>_file_contexts. 950 File_contexts *string `android:"path"` 951 952 ApexNativeDependencies 953 954 // List of java libraries that are embedded inside this APEX bundle 955 Java_libs []string 956 957 // List of prebuilt files that are embedded inside this APEX bundle 958 Prebuilts []string 959 960 // Name of the apex_key module that provides the private key to sign APEX 961 Key *string 962 963 // The type of APEX to build. Controls what the APEX payload is. Either 964 // 'image', 'zip' or 'both'. Default: 'image'. 965 Payload_type *string 966 967 // The name of a certificate in the default certificate directory, blank to use the default product certificate, 968 // or an android_app_certificate module name in the form ":module". 969 Certificate *string 970 971 // Whether this APEX is installable to one of the partitions. Default: true. 972 Installable *bool 973 974 // For native libraries and binaries, use the vendor variant instead of the core (platform) variant. 975 // Default is false. 976 Use_vendor *bool 977 978 // For telling the apex to ignore special handling for system libraries such as bionic. Default is false. 979 Ignore_system_library_special_case *bool 980 981 Multilib apexMultilibProperties 982 983 // List of sanitizer names that this APEX is enabled for 984 SanitizerNames []string `blueprint:"mutated"` 985 986 PreventInstall bool `blueprint:"mutated"` 987 988 HideFromMake bool `blueprint:"mutated"` 989 990 // Indicates this APEX provides C++ shared libaries to other APEXes. Default: false. 991 Provide_cpp_shared_libs *bool 992 993 // List of providing APEXes' names so that this APEX can depend on provided shared libraries. 994 Uses []string 995 996 // package format of this apex variant; could be non-flattened, flattened, or zip. 997 // imageApex, zipApex or flattened 998 ApexType apexPackaging `blueprint:"mutated"` 999 1000 // List of SDKs that are used to build this APEX. A reference to an SDK should be either 1001 // `name#version` or `name` which is an alias for `name#current`. If left empty, `platform#current` 1002 // is implied. This value affects all modules included in this APEX. In other words, they are 1003 // also built with the SDKs specified here. 1004 Uses_sdks []string 1005 1006 // Whenever apex_payload.img of the APEX should include dm-verity hashtree. 1007 // Should be only used in tests#. 1008 Test_only_no_hashtree *bool 1009 1010 // Whenever apex_payload.img of the APEX should not be dm-verity signed. 1011 // Should be only used in tests#. 1012 Test_only_unsigned_payload *bool 1013 1014 IsCoverageVariant bool `blueprint:"mutated"` 1015 1016 // Whether this APEX is considered updatable or not. When set to true, this will enforce additional 1017 // rules for making sure that the APEX is truly updatable. 1018 // - To be updatable, min_sdk_version should be set as well 1019 // This will also disable the size optimizations like symlinking to the system libs. 1020 // Default is false. 1021 Updatable *bool 1022 1023 // The minimum SDK version that this apex must be compatibile with. 1024 Min_sdk_version *string 1025 1026 // If set true, VNDK libs are considered as stable libs and are not included in this apex. 1027 // Should be only used in non-system apexes (e.g. vendor: true). 1028 // Default is false. 1029 Use_vndk_as_stable *bool 1030} 1031 1032type apexTargetBundleProperties struct { 1033 Target struct { 1034 // Multilib properties only for android. 1035 Android struct { 1036 Multilib apexMultilibProperties 1037 } 1038 1039 // Multilib properties only for host. 1040 Host struct { 1041 Multilib apexMultilibProperties 1042 } 1043 1044 // Multilib properties only for host linux_bionic. 1045 Linux_bionic struct { 1046 Multilib apexMultilibProperties 1047 } 1048 1049 // Multilib properties only for host linux_glibc. 1050 Linux_glibc struct { 1051 Multilib apexMultilibProperties 1052 } 1053 } 1054} 1055 1056type overridableProperties struct { 1057 // List of APKs to package inside APEX 1058 Apps []string 1059 1060 // List of runtime resource overlays (RROs) inside APEX 1061 Rros []string 1062 1063 // Names of modules to be overridden. Listed modules can only be other binaries 1064 // (in Make or Soong). 1065 // This does not completely prevent installation of the overridden binaries, but if both 1066 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed 1067 // from PRODUCT_PACKAGES. 1068 Overrides []string 1069 1070 // Logging Parent value 1071 Logging_parent string 1072 1073 // Apex Container Package Name. 1074 // Override value for attribute package:name in AndroidManifest.xml 1075 Package_name string 1076 1077 // A txt file containing list of files that are allowed to be included in this APEX. 1078 Allowed_files *string `android:"path"` 1079} 1080 1081type apexPackaging int 1082 1083const ( 1084 imageApex apexPackaging = iota 1085 zipApex 1086 flattenedApex 1087) 1088 1089// The suffix for the output "file", not the module 1090func (a apexPackaging) suffix() string { 1091 switch a { 1092 case imageApex: 1093 return imageApexSuffix 1094 case zipApex: 1095 return zipApexSuffix 1096 default: 1097 panic(fmt.Errorf("unknown APEX type %d", a)) 1098 } 1099} 1100 1101func (a apexPackaging) name() string { 1102 switch a { 1103 case imageApex: 1104 return imageApexType 1105 case zipApex: 1106 return zipApexType 1107 default: 1108 panic(fmt.Errorf("unknown APEX type %d", a)) 1109 } 1110} 1111 1112type apexFileClass int 1113 1114const ( 1115 etc apexFileClass = iota 1116 nativeSharedLib 1117 nativeExecutable 1118 shBinary 1119 pyBinary 1120 goBinary 1121 javaSharedLib 1122 nativeTest 1123 app 1124 appSet 1125) 1126 1127func (class apexFileClass) NameInMake() string { 1128 switch class { 1129 case etc: 1130 return "ETC" 1131 case nativeSharedLib: 1132 return "SHARED_LIBRARIES" 1133 case nativeExecutable, shBinary, pyBinary, goBinary: 1134 return "EXECUTABLES" 1135 case javaSharedLib: 1136 return "JAVA_LIBRARIES" 1137 case nativeTest: 1138 return "NATIVE_TESTS" 1139 case app, appSet: 1140 // b/142537672 Why isn't this APP? We want to have full control over 1141 // the paths and file names of the apk file under the flattend APEX. 1142 // If this is set to APP, then the paths and file names are modified 1143 // by the Make build system. For example, it is installed to 1144 // /system/apex/<apexname>/app/<Appname>/<apexname>.<Appname>/ instead of 1145 // /system/apex/<apexname>/app/<Appname> because the build system automatically 1146 // appends module name (which is <apexname>.<Appname> to the path. 1147 return "ETC" 1148 default: 1149 panic(fmt.Errorf("unknown class %d", class)) 1150 } 1151} 1152 1153// apexFile represents a file in an APEX bundle 1154type apexFile struct { 1155 builtFile android.Path 1156 stem string 1157 // Module name of `module` in AndroidMk. Note the generated AndroidMk module for 1158 // apexFile is named something like <AndroidMk module name>.<apex name>[<apex suffix>] 1159 androidMkModuleName string 1160 installDir string 1161 class apexFileClass 1162 module android.Module 1163 // list of symlinks that will be created in installDir that point to this apexFile 1164 symlinks []string 1165 dataPaths []android.DataPath 1166 transitiveDep bool 1167 moduleDir string 1168 1169 requiredModuleNames []string 1170 targetRequiredModuleNames []string 1171 hostRequiredModuleNames []string 1172 1173 jacocoReportClassesFile android.Path // only for javalibs and apps 1174 lintDepSets java.LintDepSets // only for javalibs and apps 1175 certificate java.Certificate // only for apps 1176 overriddenPackageName string // only for apps 1177 1178 isJniLib bool 1179} 1180 1181func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile { 1182 ret := apexFile{ 1183 builtFile: builtFile, 1184 androidMkModuleName: androidMkModuleName, 1185 installDir: installDir, 1186 class: class, 1187 module: module, 1188 } 1189 if module != nil { 1190 ret.moduleDir = ctx.OtherModuleDir(module) 1191 ret.requiredModuleNames = module.RequiredModuleNames() 1192 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames() 1193 ret.hostRequiredModuleNames = module.HostRequiredModuleNames() 1194 } 1195 return ret 1196} 1197 1198func (af *apexFile) Ok() bool { 1199 return af.builtFile != nil && af.builtFile.String() != "" 1200} 1201 1202func (af *apexFile) apexRelativePath(path string) string { 1203 return filepath.Join(af.installDir, path) 1204} 1205 1206// Path() returns path of this apex file relative to the APEX root 1207func (af *apexFile) Path() string { 1208 return af.apexRelativePath(af.Stem()) 1209} 1210 1211func (af *apexFile) Stem() string { 1212 if af.stem != "" { 1213 return af.stem 1214 } 1215 return af.builtFile.Base() 1216} 1217 1218// SymlinkPaths() returns paths of the symlinks (if any) relative to the APEX root 1219func (af *apexFile) SymlinkPaths() []string { 1220 var ret []string 1221 for _, symlink := range af.symlinks { 1222 ret = append(ret, af.apexRelativePath(symlink)) 1223 } 1224 return ret 1225} 1226 1227func (af *apexFile) AvailableToPlatform() bool { 1228 if af.module == nil { 1229 return false 1230 } 1231 if am, ok := af.module.(android.ApexModule); ok { 1232 return am.AvailableFor(android.AvailableToPlatform) 1233 } 1234 return false 1235} 1236 1237type apexBundle struct { 1238 android.ModuleBase 1239 android.DefaultableModuleBase 1240 android.OverridableModuleBase 1241 android.SdkBase 1242 1243 properties apexBundleProperties 1244 targetProperties apexTargetBundleProperties 1245 overridableProperties overridableProperties 1246 1247 // specific to apex_vndk modules 1248 vndkProperties apexVndkProperties 1249 1250 bundleModuleFile android.WritablePath 1251 outputFile android.WritablePath 1252 installDir android.InstallPath 1253 1254 prebuiltFileToDelete string 1255 1256 public_key_file android.Path 1257 private_key_file android.Path 1258 1259 container_certificate_file android.Path 1260 container_private_key_file android.Path 1261 1262 fileContexts android.WritablePath 1263 1264 // list of files to be included in this apex 1265 filesInfo []apexFile 1266 1267 // list of module names that should be installed along with this APEX 1268 requiredDeps []string 1269 1270 // list of module names that this APEX is including (to be shown via *-deps-info target) 1271 android.ApexBundleDepsInfo 1272 1273 testApex bool 1274 vndkApex bool 1275 artApex bool 1276 primaryApexType bool 1277 1278 manifestJsonOut android.WritablePath 1279 manifestPbOut android.WritablePath 1280 1281 // list of commands to create symlinks for backward compatibility. 1282 // these commands will be attached as LOCAL_POST_INSTALL_CMD to 1283 // apex package itself(for unflattened build) or apex_manifest(for flattened build) 1284 // so that compat symlinks are always installed regardless of TARGET_FLATTEN_APEX setting. 1285 compatSymlinks []string 1286 1287 // Suffix of module name in Android.mk 1288 // ".flattened", ".apex", ".zipapex", or "" 1289 suffix string 1290 1291 installedFilesFile android.WritablePath 1292 1293 // Whether to create symlink to the system file instead of having a file 1294 // inside the apex or not 1295 linkToSystemLib bool 1296 1297 // Struct holding the merged notice file paths in different formats 1298 mergedNotices android.NoticeOutputs 1299 1300 // Optional list of lint report zip files for apexes that contain java or app modules 1301 lintReports android.Paths 1302} 1303 1304func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, 1305 nativeModules ApexNativeDependencies, 1306 target android.Target, imageVariation string) { 1307 // Use *FarVariation* to be able to depend on modules having 1308 // conflicting variations with this module. This is required since 1309 // arch variant of an APEX bundle is 'common' but it is 'arm' or 'arm64' 1310 // for native shared libs. 1311 ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{ 1312 {Mutator: "image", Variation: imageVariation}, 1313 {Mutator: "link", Variation: "shared"}, 1314 {Mutator: "version", Variation: ""}, // "" is the non-stub variant 1315 }...), sharedLibTag, nativeModules.Native_shared_libs...) 1316 1317 ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{ 1318 {Mutator: "image", Variation: imageVariation}, 1319 {Mutator: "link", Variation: "shared"}, 1320 {Mutator: "version", Variation: ""}, // "" is the non-stub variant 1321 }...), jniLibTag, nativeModules.Jni_libs...) 1322 1323 ctx.AddFarVariationDependencies(append(target.Variations(), 1324 blueprint.Variation{Mutator: "image", Variation: imageVariation}), 1325 executableTag, nativeModules.Binaries...) 1326 1327 ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{ 1328 {Mutator: "image", Variation: imageVariation}, 1329 {Mutator: "test_per_src", Variation: ""}, // "" is the all-tests variant 1330 }...), testTag, nativeModules.Tests...) 1331} 1332 1333func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) { 1334 if ctx.Os().Class == android.Device { 1335 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil) 1336 } else { 1337 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil) 1338 if ctx.Os().Bionic() { 1339 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil) 1340 } else { 1341 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil) 1342 } 1343 } 1344} 1345 1346func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { 1347 if proptools.Bool(a.properties.Use_vendor) && !android.InList(a.Name(), useVendorAllowList(ctx.Config())) { 1348 ctx.PropertyErrorf("use_vendor", "not allowed to set use_vendor: true") 1349 } 1350 1351 targets := ctx.MultiTargets() 1352 config := ctx.DeviceConfig() 1353 imageVariation := a.getImageVariation(ctx) 1354 1355 a.combineProperties(ctx) 1356 1357 has32BitTarget := false 1358 for _, target := range targets { 1359 if target.Arch.ArchType.Multilib == "lib32" { 1360 has32BitTarget = true 1361 } 1362 } 1363 for i, target := range targets { 1364 // When multilib.* is omitted for native_shared_libs/jni_libs/tests, it implies 1365 // multilib.both 1366 addDependenciesForNativeModules(ctx, 1367 ApexNativeDependencies{ 1368 Native_shared_libs: a.properties.Native_shared_libs, 1369 Tests: a.properties.Tests, 1370 Jni_libs: a.properties.Jni_libs, 1371 Binaries: nil, 1372 }, 1373 target, imageVariation) 1374 1375 // Add native modules targetting both ABIs 1376 addDependenciesForNativeModules(ctx, 1377 a.properties.Multilib.Both, 1378 target, 1379 imageVariation) 1380 1381 isPrimaryAbi := i == 0 1382 if isPrimaryAbi { 1383 // When multilib.* is omitted for binaries, it implies 1384 // multilib.first 1385 addDependenciesForNativeModules(ctx, 1386 ApexNativeDependencies{ 1387 Native_shared_libs: nil, 1388 Tests: nil, 1389 Jni_libs: nil, 1390 Binaries: a.properties.Binaries, 1391 }, 1392 target, imageVariation) 1393 1394 // Add native modules targetting the first ABI 1395 addDependenciesForNativeModules(ctx, 1396 a.properties.Multilib.First, 1397 target, 1398 imageVariation) 1399 } 1400 1401 switch target.Arch.ArchType.Multilib { 1402 case "lib32": 1403 // Add native modules targetting 32-bit ABI 1404 addDependenciesForNativeModules(ctx, 1405 a.properties.Multilib.Lib32, 1406 target, 1407 imageVariation) 1408 1409 addDependenciesForNativeModules(ctx, 1410 a.properties.Multilib.Prefer32, 1411 target, 1412 imageVariation) 1413 case "lib64": 1414 // Add native modules targetting 64-bit ABI 1415 addDependenciesForNativeModules(ctx, 1416 a.properties.Multilib.Lib64, 1417 target, 1418 imageVariation) 1419 1420 if !has32BitTarget { 1421 addDependenciesForNativeModules(ctx, 1422 a.properties.Multilib.Prefer32, 1423 target, 1424 imageVariation) 1425 } 1426 } 1427 } 1428 1429 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 1430 // 32 on 32bit device) regardless of the TARGET_PREFER_* setting. 1431 // b/144532908 1432 archForPrebuiltEtc := config.Arches()[0] 1433 for _, arch := range config.Arches() { 1434 // Prefer 64-bit arch if there is any 1435 if arch.ArchType.Multilib == "lib64" { 1436 archForPrebuiltEtc = arch 1437 break 1438 } 1439 } 1440 ctx.AddFarVariationDependencies([]blueprint.Variation{ 1441 {Mutator: "os", Variation: ctx.Os().String()}, 1442 {Mutator: "arch", Variation: archForPrebuiltEtc.String()}, 1443 }, prebuiltTag, a.properties.Prebuilts...) 1444 1445 ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), 1446 javaLibTag, a.properties.Java_libs...) 1447 1448 // With EMMA_INSTRUMENT_FRAMEWORK=true the ART boot image includes jacoco library. 1449 if a.artApex && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { 1450 ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), 1451 javaLibTag, "jacocoagent") 1452 } 1453 1454 if String(a.properties.Key) == "" { 1455 ctx.ModuleErrorf("key is missing") 1456 return 1457 } 1458 ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key)) 1459 1460 cert := android.SrcIsModule(a.getCertString(ctx)) 1461 if cert != "" { 1462 ctx.AddDependency(ctx.Module(), certificateTag, cert) 1463 } 1464 1465 // TODO(jiyong): ensure that all apexes are with non-empty uses_sdks 1466 if len(a.properties.Uses_sdks) > 0 { 1467 sdkRefs := []android.SdkRef{} 1468 for _, str := range a.properties.Uses_sdks { 1469 parsed := android.ParseSdkRef(ctx, str, "uses_sdks") 1470 sdkRefs = append(sdkRefs, parsed) 1471 } 1472 a.BuildWithSdks(sdkRefs) 1473 } 1474} 1475 1476func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) { 1477 if a.overridableProperties.Allowed_files != nil { 1478 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files) 1479 } 1480 ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), 1481 androidAppTag, a.overridableProperties.Apps...) 1482 ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), 1483 rroTag, a.overridableProperties.Rros...) 1484} 1485 1486func (a *apexBundle) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 1487 // direct deps of an APEX bundle are all part of the APEX bundle 1488 return true 1489} 1490 1491func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string { 1492 moduleName := ctx.ModuleName() 1493 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the OVERRIDE_* list, 1494 // we check with the pseudo module name to see if its certificate is overridden. 1495 if a.vndkApex { 1496 moduleName = vndkApexName 1497 } 1498 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName) 1499 if overridden { 1500 return ":" + certificate 1501 } 1502 return String(a.properties.Certificate) 1503} 1504 1505func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) { 1506 switch tag { 1507 case "": 1508 return android.Paths{a.outputFile}, nil 1509 default: 1510 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 1511 } 1512} 1513 1514func (a *apexBundle) installable() bool { 1515 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable)) 1516} 1517 1518func (a *apexBundle) testOnlyShouldSkipHashtreeGeneration() bool { 1519 return proptools.Bool(a.properties.Test_only_no_hashtree) 1520} 1521 1522func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool { 1523 return proptools.Bool(a.properties.Test_only_unsigned_payload) 1524} 1525 1526func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string { 1527 deviceConfig := ctx.DeviceConfig() 1528 if a.vndkApex { 1529 return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig) 1530 } 1531 1532 var prefix string 1533 var vndkVersion string 1534 if deviceConfig.VndkVersion() != "" { 1535 if proptools.Bool(a.properties.Use_vendor) { 1536 prefix = cc.VendorVariationPrefix 1537 vndkVersion = deviceConfig.PlatformVndkVersion() 1538 } else if a.SocSpecific() || a.DeviceSpecific() { 1539 prefix = cc.VendorVariationPrefix 1540 vndkVersion = deviceConfig.VndkVersion() 1541 } else if a.ProductSpecific() { 1542 prefix = cc.ProductVariationPrefix 1543 vndkVersion = deviceConfig.ProductVndkVersion() 1544 } 1545 } 1546 if vndkVersion == "current" { 1547 vndkVersion = deviceConfig.PlatformVndkVersion() 1548 } 1549 if vndkVersion != "" { 1550 return prefix + vndkVersion 1551 } 1552 return android.CoreVariation 1553} 1554 1555func (a *apexBundle) EnableSanitizer(sanitizerName string) { 1556 if !android.InList(sanitizerName, a.properties.SanitizerNames) { 1557 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName) 1558 } 1559} 1560 1561func (a *apexBundle) IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool { 1562 if android.InList(sanitizerName, a.properties.SanitizerNames) { 1563 return true 1564 } 1565 1566 // Then follow the global setting 1567 globalSanitizerNames := []string{} 1568 if a.Host() { 1569 globalSanitizerNames = ctx.Config().SanitizeHost() 1570 } else { 1571 arches := ctx.Config().SanitizeDeviceArch() 1572 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) { 1573 globalSanitizerNames = ctx.Config().SanitizeDevice() 1574 } 1575 } 1576 return android.InList(sanitizerName, globalSanitizerNames) 1577} 1578 1579func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) { 1580 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") { 1581 for _, target := range ctx.MultiTargets() { 1582 if target.Arch.ArchType.Multilib == "lib64" { 1583 ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{ 1584 {Mutator: "image", Variation: a.getImageVariation(ctx)}, 1585 {Mutator: "link", Variation: "shared"}, 1586 {Mutator: "version", Variation: ""}, // "" is the non-stub variant 1587 }...), sharedLibTag, "libclang_rt.hwasan-aarch64-android") 1588 break 1589 } 1590 } 1591 } 1592} 1593 1594var _ cc.Coverage = (*apexBundle)(nil) 1595 1596func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { 1597 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled() 1598} 1599 1600func (a *apexBundle) PreventInstall() { 1601 a.properties.PreventInstall = true 1602} 1603 1604func (a *apexBundle) HideFromMake() { 1605 a.properties.HideFromMake = true 1606} 1607 1608func (a *apexBundle) MarkAsCoverageVariant(coverage bool) { 1609 a.properties.IsCoverageVariant = coverage 1610} 1611 1612func (a *apexBundle) EnableCoverageIfNeeded() {} 1613 1614// TODO(jiyong) move apexFileFor* close to the apexFile type definition 1615func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile { 1616 // Decide the APEX-local directory by the multilib of the library 1617 // In the future, we may query this to the module. 1618 var dirInApex string 1619 switch ccMod.Arch().ArchType.Multilib { 1620 case "lib32": 1621 dirInApex = "lib" 1622 case "lib64": 1623 dirInApex = "lib64" 1624 } 1625 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled { 1626 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath) 1627 } 1628 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath()) 1629 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) { 1630 // Special case for Bionic libs and other libs installed with them. This is 1631 // to prevent those libs from being included in the search path 1632 // /apex/com.android.runtime/${LIB}. This exclusion is required because 1633 // those libs in the Runtime APEX are available via the legacy paths in 1634 // /system/lib/. By the init process, the libs in the APEX are bind-mounted 1635 // to the legacy paths and thus will be loaded into the default linker 1636 // namespace (aka "platform" namespace). If the libs are directly in 1637 // /apex/com.android.runtime/${LIB} then the same libs will be loaded again 1638 // into the runtime linker namespace, which will result in double loading of 1639 // them, which isn't supported. 1640 dirInApex = filepath.Join(dirInApex, "bionic") 1641 } 1642 1643 fileToCopy := ccMod.OutputFile().Path() 1644 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName 1645 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod) 1646} 1647 1648func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile { 1649 dirInApex := "bin" 1650 if cc.Target().NativeBridge == android.NativeBridgeEnabled { 1651 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath) 1652 } 1653 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath()) 1654 fileToCopy := cc.OutputFile().Path() 1655 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName 1656 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc) 1657 af.symlinks = cc.Symlinks() 1658 af.dataPaths = cc.DataPaths() 1659 return af 1660} 1661 1662func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile { 1663 dirInApex := "bin" 1664 fileToCopy := py.HostToolPath().Path() 1665 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py) 1666} 1667func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile { 1668 dirInApex := "bin" 1669 s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath()) 1670 if err != nil { 1671 ctx.ModuleErrorf("Unable to use compiled binary at %s", gb.InstallPath()) 1672 return apexFile{} 1673 } 1674 fileToCopy := android.PathForOutput(ctx, s) 1675 // NB: Since go binaries are static we don't need the module for anything here, which is 1676 // good since the go tool is a blueprint.Module not an android.Module like we would 1677 // normally use. 1678 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil) 1679} 1680 1681func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile { 1682 dirInApex := filepath.Join("bin", sh.SubDir()) 1683 fileToCopy := sh.OutputFile() 1684 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh) 1685 af.symlinks = sh.Symlinks() 1686 return af 1687} 1688 1689type javaModule interface { 1690 android.Module 1691 BaseModuleName() string 1692 DexJarBuildPath() android.Path 1693 JacocoReportClassesFile() android.Path 1694 LintDepSets() java.LintDepSets 1695 1696 Stem() string 1697} 1698 1699var _ javaModule = (*java.Library)(nil) 1700var _ javaModule = (*java.SdkLibrary)(nil) 1701var _ javaModule = (*java.DexImport)(nil) 1702var _ javaModule = (*java.SdkLibraryImport)(nil) 1703 1704func apexFileForJavaLibrary(ctx android.BaseModuleContext, module javaModule) apexFile { 1705 dirInApex := "javalib" 1706 fileToCopy := module.DexJarBuildPath() 1707 af := newApexFile(ctx, fileToCopy, module.BaseModuleName(), dirInApex, javaSharedLib, module) 1708 af.jacocoReportClassesFile = module.JacocoReportClassesFile() 1709 af.lintDepSets = module.LintDepSets() 1710 af.stem = module.Stem() + ".jar" 1711 return af 1712} 1713 1714func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile { 1715 dirInApex := filepath.Join("etc", prebuilt.SubDir()) 1716 fileToCopy := prebuilt.OutputFile() 1717 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt) 1718} 1719 1720func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile { 1721 dirInApex := filepath.Join("etc", config.SubDir()) 1722 fileToCopy := config.CompatConfig() 1723 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config) 1724} 1725 1726func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp interface { 1727 android.Module 1728 Privileged() bool 1729 InstallApkName() string 1730 OutputFile() android.Path 1731 JacocoReportClassesFile() android.Path 1732 Certificate() java.Certificate 1733 BaseModuleName() string 1734}) apexFile { 1735 appDir := "app" 1736 if aapp.Privileged() { 1737 appDir = "priv-app" 1738 } 1739 dirInApex := filepath.Join(appDir, aapp.InstallApkName()) 1740 fileToCopy := aapp.OutputFile() 1741 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp) 1742 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile() 1743 af.certificate = aapp.Certificate() 1744 1745 if app, ok := aapp.(interface { 1746 OverriddenManifestPackageName() string 1747 }); ok { 1748 af.overriddenPackageName = app.OverriddenManifestPackageName() 1749 } 1750 return af 1751} 1752 1753func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile { 1754 rroDir := "overlay" 1755 dirInApex := filepath.Join(rroDir, rro.Theme()) 1756 fileToCopy := rro.OutputFile() 1757 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro) 1758 af.certificate = rro.Certificate() 1759 1760 if a, ok := rro.(interface { 1761 OverriddenManifestPackageName() string 1762 }); ok { 1763 af.overriddenPackageName = a.OverriddenManifestPackageName() 1764 } 1765 return af 1766} 1767 1768// Context "decorator", overriding the InstallBypassMake method to always reply `true`. 1769type flattenedApexContext struct { 1770 android.ModuleContext 1771} 1772 1773func (c *flattenedApexContext) InstallBypassMake() bool { 1774 return true 1775} 1776 1777// Visit dependencies that contributes to the payload of this APEX 1778func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) { 1779 ctx.WalkDeps(func(child, parent android.Module) bool { 1780 am, ok := child.(android.ApexModule) 1781 if !ok || !am.CanHaveApexVariants() { 1782 return false 1783 } 1784 1785 dt := ctx.OtherModuleDependencyTag(child) 1786 1787 if _, ok := dt.(android.ExcludeFromApexContentsTag); ok { 1788 return false 1789 } 1790 1791 // Check for the direct dependencies that contribute to the payload 1792 if adt, ok := dt.(dependencyTag); ok { 1793 if adt.payload { 1794 return do(ctx, parent, am, false /* externalDep */) 1795 } 1796 // As soon as the dependency graph crosses the APEX boundary, don't go further. 1797 return false 1798 } 1799 1800 // Check for the indirect dependencies if it is considered as part of the APEX 1801 if am.ApexName() != "" { 1802 return do(ctx, parent, am, false /* externalDep */) 1803 } 1804 1805 return do(ctx, parent, am, true /* externalDep */) 1806 }) 1807} 1808 1809func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) int { 1810 ver := proptools.String(a.properties.Min_sdk_version) 1811 if ver == "" { 1812 return android.FutureApiLevel 1813 } 1814 // Treat the current codenames as "current", which means future API version (10000) 1815 // Otherwise, ApiStrToNum converts codename(non-finalized) to a value from [9000...] 1816 // and would fail to build against "current". 1817 if android.InList(ver, ctx.Config().PlatformVersionActiveCodenames()) { 1818 return android.FutureApiLevel 1819 } 1820 // In "REL" branch, "current" is mapped to finalized sdk version 1821 if ctx.Config().PlatformSdkCodename() == "REL" && ver == "current" { 1822 return ctx.Config().PlatformSdkVersionInt() 1823 } 1824 // Finalized codenames are OKAY and will be converted to int 1825 intVer, err := android.ApiStrToNum(ctx, ver) 1826 if err != nil { 1827 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) 1828 } 1829 return intVer 1830} 1831 1832func (a *apexBundle) Updatable() bool { 1833 return proptools.Bool(a.properties.Updatable) 1834} 1835 1836var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil) 1837 1838// Ensures that the dependencies are marked as available for this APEX 1839func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { 1840 // Let's be practical. Availability for test, host, and the VNDK apex isn't important 1841 if ctx.Host() || a.testApex || a.vndkApex { 1842 return 1843 } 1844 1845 // Because APEXes targeting other than system/system_ext partitions 1846 // can't set apex_available, we skip checks for these APEXes 1847 if a.SocSpecific() || a.DeviceSpecific() || 1848 (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) { 1849 return 1850 } 1851 1852 // Coverage build adds additional dependencies for the coverage-only runtime libraries. 1853 // Requiring them and their transitive depencies with apex_available is not right 1854 // because they just add noise. 1855 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) { 1856 return 1857 } 1858 1859 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { 1860 if externalDep { 1861 // As soon as the dependency graph crosses the APEX boundary, don't go further. 1862 return false 1863 } 1864 1865 apexName := ctx.ModuleName() 1866 fromName := ctx.OtherModuleName(from) 1867 toName := ctx.OtherModuleName(to) 1868 1869 // If `to` is not actually in the same APEX as `from` then it does not need apex_available and neither 1870 // do any of its dependencies. 1871 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) { 1872 // As soon as the dependency graph crosses the APEX boundary, don't go further. 1873 return false 1874 } 1875 1876 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) { 1877 return true 1878 } 1879 ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, ctx.GetPathString(true)) 1880 // Visit this module's dependencies to check and report any issues with their availability. 1881 return true 1882 }) 1883} 1884 1885func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) { 1886 if a.Updatable() { 1887 if String(a.properties.Min_sdk_version) == "" { 1888 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well") 1889 } 1890 1891 a.checkJavaStableSdkVersion(ctx) 1892 } 1893} 1894 1895func (a *apexBundle) checkMinSdkVersion(ctx android.ModuleContext) { 1896 if a.testApex || a.vndkApex { 1897 return 1898 } 1899 // Meaningless to check min_sdk_version when building use_vendor modules against non-Trebleized targets 1900 if proptools.Bool(a.properties.Use_vendor) && ctx.DeviceConfig().VndkVersion() == "" { 1901 return 1902 } 1903 android.CheckMinSdkVersion(a, ctx, a.minSdkVersion(ctx)) 1904} 1905 1906// Ensures that a lib providing stub isn't statically linked 1907func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) { 1908 // Practically, we only care about regular APEXes on the device. 1909 if ctx.Host() || a.testApex || a.vndkApex { 1910 return 1911 } 1912 1913 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { 1914 if ccm, ok := to.(*cc.Module); ok { 1915 apexName := ctx.ModuleName() 1916 fromName := ctx.OtherModuleName(from) 1917 toName := ctx.OtherModuleName(to) 1918 1919 // If `to` is not actually in the same APEX as `from` then it does not need apex_available and neither 1920 // do any of its dependencies. 1921 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) { 1922 // As soon as the dependency graph crosses the APEX boundary, don't go further. 1923 return false 1924 } 1925 1926 // TODO(jiyong) remove this check when R is published to AOSP. Currently, libstatssocket 1927 // is capable of providing a stub variant, but is being statically linked from the bluetooth 1928 // APEX. 1929 if toName == "libstatssocket" { 1930 return false 1931 } 1932 1933 // The dynamic linker and crash_dump tool in the runtime APEX is the only exception to this rule. 1934 // It can't make the static dependencies dynamic because it can't 1935 // do the dynamic linking for itself. 1936 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump") { 1937 return false 1938 } 1939 1940 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !android.DirectlyInApex(apexName, toName) 1941 if isStubLibraryFromOtherApex && !externalDep { 1942 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+ 1943 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false)) 1944 } 1945 1946 } 1947 return true 1948 }) 1949} 1950 1951func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1952 buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuildApps() 1953 switch a.properties.ApexType { 1954 case imageApex: 1955 if buildFlattenedAsDefault { 1956 a.suffix = imageApexSuffix 1957 } else { 1958 a.suffix = "" 1959 a.primaryApexType = true 1960 1961 if ctx.Config().InstallExtraFlattenedApexes() { 1962 a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix) 1963 } 1964 } 1965 case zipApex: 1966 if proptools.String(a.properties.Payload_type) == "zip" { 1967 a.suffix = "" 1968 a.primaryApexType = true 1969 } else { 1970 a.suffix = zipApexSuffix 1971 } 1972 case flattenedApex: 1973 if buildFlattenedAsDefault { 1974 a.suffix = "" 1975 a.primaryApexType = true 1976 } else { 1977 a.suffix = flattenedSuffix 1978 } 1979 } 1980 1981 if len(a.properties.Tests) > 0 && !a.testApex { 1982 ctx.PropertyErrorf("tests", "property not allowed in apex module type") 1983 return 1984 } 1985 1986 a.checkApexAvailability(ctx) 1987 a.checkUpdatable(ctx) 1988 a.checkMinSdkVersion(ctx) 1989 a.checkStaticLinkingToStubLibraries(ctx) 1990 1991 handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case) 1992 1993 // native lib dependencies 1994 var provideNativeLibs []string 1995 var requireNativeLibs []string 1996 1997 // Check if "uses" requirements are met with dependent apexBundles 1998 var providedNativeSharedLibs []string 1999 useVendor := proptools.Bool(a.properties.Use_vendor) 2000 ctx.VisitDirectDepsBlueprint(func(m blueprint.Module) { 2001 if ctx.OtherModuleDependencyTag(m) != usesTag { 2002 return 2003 } 2004 otherName := ctx.OtherModuleName(m) 2005 other, ok := m.(*apexBundle) 2006 if !ok { 2007 ctx.PropertyErrorf("uses", "%q is not a provider", otherName) 2008 return 2009 } 2010 if proptools.Bool(other.properties.Use_vendor) != useVendor { 2011 ctx.PropertyErrorf("use_vendor", "%q has different value of use_vendor", otherName) 2012 return 2013 } 2014 if !proptools.Bool(other.properties.Provide_cpp_shared_libs) { 2015 ctx.PropertyErrorf("uses", "%q does not provide native_shared_libs", otherName) 2016 return 2017 } 2018 providedNativeSharedLibs = append(providedNativeSharedLibs, other.properties.Native_shared_libs...) 2019 }) 2020 2021 var filesInfo []apexFile 2022 // TODO(jiyong) do this using WalkPayloadDeps 2023 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { 2024 depTag := ctx.OtherModuleDependencyTag(child) 2025 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok { 2026 return false 2027 } 2028 depName := ctx.OtherModuleName(child) 2029 if _, isDirectDep := parent.(*apexBundle); isDirectDep { 2030 switch depTag { 2031 case sharedLibTag, jniLibTag: 2032 isJniLib := depTag == jniLibTag 2033 if c, ok := child.(*cc.Module); ok { 2034 fi := apexFileForNativeLibrary(ctx, c, handleSpecialLibs) 2035 fi.isJniLib = isJniLib 2036 filesInfo = append(filesInfo, fi) 2037 // Collect the list of stub-providing libs except: 2038 // - VNDK libs are only for vendors 2039 // - bootstrap bionic libs are treated as provided by system 2040 if c.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) { 2041 provideNativeLibs = append(provideNativeLibs, fi.Stem()) 2042 } 2043 return true // track transitive dependencies 2044 } else { 2045 propertyName := "native_shared_libs" 2046 if isJniLib { 2047 propertyName = "jni_libs" 2048 } 2049 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName) 2050 } 2051 case executableTag: 2052 if cc, ok := child.(*cc.Module); ok { 2053 filesInfo = append(filesInfo, apexFileForExecutable(ctx, cc)) 2054 return true // track transitive dependencies 2055 } else if sh, ok := child.(*sh.ShBinary); ok { 2056 filesInfo = append(filesInfo, apexFileForShBinary(ctx, sh)) 2057 } else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() { 2058 filesInfo = append(filesInfo, apexFileForPyBinary(ctx, py)) 2059 } else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() { 2060 filesInfo = append(filesInfo, apexFileForGoBinary(ctx, depName, gb)) 2061 } else { 2062 ctx.PropertyErrorf("binaries", "%q is neither cc_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName) 2063 } 2064 case javaLibTag: 2065 switch child.(type) { 2066 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport: 2067 af := apexFileForJavaLibrary(ctx, child.(javaModule)) 2068 if !af.Ok() { 2069 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName) 2070 return false 2071 } 2072 filesInfo = append(filesInfo, af) 2073 return true // track transitive dependencies 2074 default: 2075 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child)) 2076 } 2077 case androidAppTag: 2078 if ap, ok := child.(*java.AndroidApp); ok { 2079 filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap)) 2080 return true // track transitive dependencies 2081 } else if ap, ok := child.(*java.AndroidAppImport); ok { 2082 filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap)) 2083 } else if ap, ok := child.(*java.AndroidTestHelperApp); ok { 2084 filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap)) 2085 } else if ap, ok := child.(*java.AndroidAppSet); ok { 2086 appDir := "app" 2087 if ap.Privileged() { 2088 appDir = "priv-app" 2089 } 2090 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), 2091 filepath.Join(appDir, ap.BaseModuleName()), appSet, ap) 2092 af.certificate = java.PresignedCertificate 2093 filesInfo = append(filesInfo, af) 2094 } else { 2095 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName) 2096 } 2097 case rroTag: 2098 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok { 2099 filesInfo = append(filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro)) 2100 } else { 2101 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName) 2102 } 2103 case prebuiltTag: 2104 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { 2105 filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName)) 2106 } else if prebuilt, ok := child.(java.PlatformCompatConfigIntf); ok { 2107 filesInfo = append(filesInfo, apexFileForCompatConfig(ctx, prebuilt, depName)) 2108 } else { 2109 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc and not a platform_compat_config module", depName) 2110 } 2111 case testTag: 2112 if ccTest, ok := child.(*cc.Module); ok { 2113 if ccTest.IsTestPerSrcAllTestsVariation() { 2114 // Multiple-output test module (where `test_per_src: true`). 2115 // 2116 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module. 2117 // We do not add this variation to `filesInfo`, as it has no output; 2118 // however, we do add the other variations of this module as indirect 2119 // dependencies (see below). 2120 } else { 2121 // Single-output test module (where `test_per_src: false`). 2122 af := apexFileForExecutable(ctx, ccTest) 2123 af.class = nativeTest 2124 filesInfo = append(filesInfo, af) 2125 } 2126 return true // track transitive dependencies 2127 } else { 2128 ctx.PropertyErrorf("tests", "%q is not a cc module", depName) 2129 } 2130 case keyTag: 2131 if key, ok := child.(*apexKey); ok { 2132 a.private_key_file = key.private_key_file 2133 a.public_key_file = key.public_key_file 2134 } else { 2135 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName) 2136 } 2137 return false 2138 case certificateTag: 2139 if dep, ok := child.(*java.AndroidAppCertificate); ok { 2140 a.container_certificate_file = dep.Certificate.Pem 2141 a.container_private_key_file = dep.Certificate.Key 2142 } else { 2143 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName) 2144 } 2145 case android.PrebuiltDepTag: 2146 // If the prebuilt is force disabled, remember to delete the prebuilt file 2147 // that might have been installed in the previous builds 2148 if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() { 2149 a.prebuiltFileToDelete = prebuilt.InstallFilename() 2150 } 2151 } 2152 } else if !a.vndkApex { 2153 // indirect dependencies 2154 if am, ok := child.(android.ApexModule); ok { 2155 // We cannot use a switch statement on `depTag` here as the checked 2156 // tags used below are private (e.g. `cc.sharedDepTag`). 2157 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) { 2158 if cc, ok := child.(*cc.Module); ok { 2159 if android.InList(cc.Name(), providedNativeSharedLibs) { 2160 // If we're using a shared library which is provided from other APEX, 2161 // don't include it in this APEX 2162 return false 2163 } 2164 if cc.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && cc.IsVndk() { 2165 requireNativeLibs = append(requireNativeLibs, ":vndk") 2166 return false 2167 } 2168 af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs) 2169 af.transitiveDep = true 2170 if !a.Host() && !android.DirectlyInApex(ctx.ModuleName(), depName) && (cc.IsStubs() || cc.HasStubsVariants()) { 2171 // If the dependency is a stubs lib, don't include it in this APEX, 2172 // but make sure that the lib is installed on the device. 2173 // In case no APEX is having the lib, the lib is installed to the system 2174 // partition. 2175 // 2176 // Always include if we are a host-apex however since those won't have any 2177 // system libraries. 2178 if !android.DirectlyInAnyApex(ctx, depName) { 2179 // we need a module name for Make 2180 name := cc.BaseModuleName() + cc.Properties.SubName 2181 if proptools.Bool(a.properties.Use_vendor) { 2182 // we don't use subName(.vendor) for a "use_vendor: true" apex 2183 // which is supposed to be installed in /system 2184 name = cc.BaseModuleName() 2185 } 2186 if !android.InList(name, a.requiredDeps) { 2187 a.requiredDeps = append(a.requiredDeps, name) 2188 } 2189 } 2190 requireNativeLibs = append(requireNativeLibs, af.Stem()) 2191 // Don't track further 2192 return false 2193 } 2194 filesInfo = append(filesInfo, af) 2195 return true // track transitive dependencies 2196 } 2197 } else if cc.IsTestPerSrcDepTag(depTag) { 2198 if cc, ok := child.(*cc.Module); ok { 2199 af := apexFileForExecutable(ctx, cc) 2200 // Handle modules created as `test_per_src` variations of a single test module: 2201 // use the name of the generated test binary (`fileToCopy`) instead of the name 2202 // of the original test module (`depName`, shared by all `test_per_src` 2203 // variations of that module). 2204 af.androidMkModuleName = filepath.Base(af.builtFile.String()) 2205 // these are not considered transitive dep 2206 af.transitiveDep = false 2207 filesInfo = append(filesInfo, af) 2208 return true // track transitive dependencies 2209 } 2210 } else if java.IsJniDepTag(depTag) { 2211 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps 2212 return false 2213 } else if java.IsXmlPermissionsFileDepTag(depTag) { 2214 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { 2215 filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName)) 2216 } 2217 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() { 2218 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName) 2219 } 2220 } 2221 } 2222 return false 2223 }) 2224 2225 // Specific to the ART apex: dexpreopt artifacts for libcore Java libraries. 2226 // Build rules are generated by the dexpreopt singleton, and here we access build artifacts 2227 // via the global boot image config. 2228 if a.artApex { 2229 for arch, files := range java.DexpreoptedArtApexJars(ctx) { 2230 dirInApex := filepath.Join("javalib", arch.String()) 2231 for _, f := range files { 2232 localModule := "javalib_" + arch.String() + "_" + filepath.Base(f.String()) 2233 af := newApexFile(ctx, f, localModule, dirInApex, etc, nil) 2234 filesInfo = append(filesInfo, af) 2235 } 2236 } 2237 } 2238 2239 if a.private_key_file == nil { 2240 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.properties.Key)) 2241 return 2242 } 2243 2244 // remove duplicates in filesInfo 2245 removeDup := func(filesInfo []apexFile) []apexFile { 2246 encountered := make(map[string]apexFile) 2247 for _, f := range filesInfo { 2248 dest := filepath.Join(f.installDir, f.builtFile.Base()) 2249 if e, ok := encountered[dest]; !ok { 2250 encountered[dest] = f 2251 } else { 2252 // If a module is directly included and also transitively depended on 2253 // consider it as directly included. 2254 e.transitiveDep = e.transitiveDep && f.transitiveDep 2255 encountered[dest] = e 2256 } 2257 } 2258 var result []apexFile 2259 for _, v := range encountered { 2260 result = append(result, v) 2261 } 2262 return result 2263 } 2264 filesInfo = removeDup(filesInfo) 2265 2266 // to have consistent build rules 2267 sort.Slice(filesInfo, func(i, j int) bool { 2268 return filesInfo[i].builtFile.String() < filesInfo[j].builtFile.String() 2269 }) 2270 2271 a.installDir = android.PathForModuleInstall(ctx, "apex") 2272 a.filesInfo = filesInfo 2273 2274 // Optimization. If we are building bundled APEX, for the files that are gathered due to the 2275 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing 2276 // the same library in the system partition, thus effectively sharing the same libraries 2277 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed 2278 // in the APEX. 2279 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && 2280 a.installable() && 2281 !proptools.Bool(a.properties.Use_vendor) 2282 2283 // APEXes targeting other than system/system_ext partitions use vendor/product variants. 2284 // So we can't link them to /system/lib libs which are core variants. 2285 if a.SocSpecific() || a.DeviceSpecific() || 2286 (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) { 2287 a.linkToSystemLib = false 2288 } 2289 2290 // We don't need the optimization for updatable APEXes, as it might give false signal 2291 // to the system health when the APEXes are still bundled (b/149805758) 2292 if a.Updatable() && a.properties.ApexType == imageApex { 2293 a.linkToSystemLib = false 2294 } 2295 2296 // We also don't want the optimization for host APEXes, because it doesn't make sense. 2297 if ctx.Host() { 2298 a.linkToSystemLib = false 2299 } 2300 2301 // prepare apex_manifest.json 2302 a.buildManifest(ctx, provideNativeLibs, requireNativeLibs) 2303 2304 a.buildFileContexts(ctx) 2305 2306 a.setCertificateAndPrivateKey(ctx) 2307 if a.properties.ApexType == flattenedApex { 2308 a.buildFlattenedApex(ctx) 2309 } else { 2310 a.buildUnflattenedApex(ctx) 2311 } 2312 2313 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx) 2314 2315 a.buildApexDependencyInfo(ctx) 2316 2317 a.buildLintReports(ctx) 2318} 2319 2320// Enforce that Java deps of the apex are using stable SDKs to compile 2321func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) { 2322 // Visit direct deps only. As long as we guarantee top-level deps are using 2323 // stable SDKs, java's checkLinkType guarantees correct usage for transitive deps 2324 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) { 2325 tag := ctx.OtherModuleDependencyTag(module) 2326 switch tag { 2327 case javaLibTag, androidAppTag: 2328 if m, ok := module.(interface{ CheckStableSdkVersion() error }); ok { 2329 if err := m.CheckStableSdkVersion(); err != nil { 2330 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err) 2331 } 2332 } 2333 } 2334 }) 2335} 2336 2337func baselineApexAvailable(apex, moduleName string) bool { 2338 key := apex 2339 moduleName = normalizeModuleName(moduleName) 2340 2341 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) { 2342 return true 2343 } 2344 2345 key = android.AvailableToAnyApex 2346 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) { 2347 return true 2348 } 2349 2350 return false 2351} 2352 2353func normalizeModuleName(moduleName string) string { 2354 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build 2355 // system. Trim the prefix for the check since they are confusing 2356 moduleName = strings.TrimPrefix(moduleName, "prebuilt_") 2357 if strings.HasPrefix(moduleName, "libclang_rt.") { 2358 // This module has many arch variants that depend on the product being built. 2359 // We don't want to list them all 2360 moduleName = "libclang_rt" 2361 } 2362 if strings.HasPrefix(moduleName, "androidx.") { 2363 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries 2364 moduleName = "androidx" 2365 } 2366 return moduleName 2367} 2368 2369func newApexBundle() *apexBundle { 2370 module := &apexBundle{} 2371 module.AddProperties(&module.properties) 2372 module.AddProperties(&module.targetProperties) 2373 module.AddProperties(&module.overridableProperties) 2374 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon) 2375 android.InitDefaultableModule(module) 2376 android.InitSdkAwareModule(module) 2377 android.InitOverridableModule(module, &module.overridableProperties.Overrides) 2378 return module 2379} 2380 2381func ApexBundleFactory(testApex bool, artApex bool) android.Module { 2382 bundle := newApexBundle() 2383 bundle.testApex = testApex 2384 bundle.artApex = artApex 2385 return bundle 2386} 2387 2388// apex_test is an APEX for testing. The difference from the ordinary apex module type is that 2389// certain compatibility checks such as apex_available are not done for apex_test. 2390func testApexBundleFactory() android.Module { 2391 bundle := newApexBundle() 2392 bundle.testApex = true 2393 return bundle 2394} 2395 2396// apex packages other modules into an APEX file which is a packaging format for system-level 2397// components like binaries, shared libraries, etc. 2398func BundleFactory() android.Module { 2399 return newApexBundle() 2400} 2401 2402// 2403// Defaults 2404// 2405type Defaults struct { 2406 android.ModuleBase 2407 android.DefaultsModuleBase 2408} 2409 2410func defaultsFactory() android.Module { 2411 return DefaultsFactory() 2412} 2413 2414func DefaultsFactory(props ...interface{}) android.Module { 2415 module := &Defaults{} 2416 2417 module.AddProperties(props...) 2418 module.AddProperties( 2419 &apexBundleProperties{}, 2420 &apexTargetBundleProperties{}, 2421 &overridableProperties{}, 2422 ) 2423 2424 android.InitDefaultsModule(module) 2425 return module 2426} 2427 2428// 2429// OverrideApex 2430// 2431type OverrideApex struct { 2432 android.ModuleBase 2433 android.OverrideModuleBase 2434} 2435 2436func (o *OverrideApex) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2437 // All the overrides happen in the base module. 2438} 2439 2440// override_apex is used to create an apex module based on another apex module 2441// by overriding some of its properties. 2442func overrideApexFactory() android.Module { 2443 m := &OverrideApex{} 2444 m.AddProperties(&overridableProperties{}) 2445 2446 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) 2447 android.InitOverrideModule(m) 2448 return m 2449} 2450