1# Copyright (C) 2022 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 15load("@bazel_skylib//lib:paths.bzl", "paths") 16load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") 17load("//build/bazel/rules/cc:cc_binary.bzl", "cc_binary") 18load("//build/bazel/rules/cc:cc_library_headers.bzl", "cc_library_headers") 19load("//build/bazel/rules/cc:cc_library_shared.bzl", "cc_library_shared") 20load("//build/bazel/rules/cc:cc_library_static.bzl", "cc_library_static") 21load("//build/bazel/rules/cc:cc_prebuilt_library_static.bzl", "cc_prebuilt_library_static") 22load( 23 "//build/bazel/rules/test_common:flags.bzl", 24 "action_flags_absent_for_mnemonic_test", 25 "action_flags_present_only_for_mnemonic_test", 26) 27load("//build/bazel/rules/test_common:paths.bzl", "get_output_and_package_dir_based_path", "get_package_dir_based_path") 28load("//build/bazel/rules/test_common:rules.bzl", "expect_failure_test") 29load(":cc_library_common_test.bzl", "target_provides_androidmk_info_test") 30 31def _cc_library_static_propagating_compilation_context_test_impl(ctx): 32 env = analysistest.begin(ctx) 33 target = analysistest.target_under_test(env) 34 cc_info = target[CcInfo] 35 compilation_context = cc_info.compilation_context 36 37 header_paths = [f.path for f in compilation_context.headers.to_list()] 38 for hdr in ctx.files.expected_hdrs: 39 asserts.true( 40 env, 41 hdr.path in header_paths, 42 "Did not find {hdr} in includes: {hdrs}.".format(hdr = hdr, hdrs = compilation_context.headers), 43 ) 44 45 for hdr in ctx.files.expected_absent_hdrs: 46 asserts.true( 47 env, 48 hdr not in header_paths, 49 "Found {hdr} in includes: {hdrs}, should not be present.".format(hdr = hdr, hdrs = compilation_context.headers), 50 ) 51 52 for include in ctx.attr.expected_includes: 53 absolute_include = get_package_dir_based_path(env, include) 54 asserts.true( 55 env, 56 absolute_include in compilation_context.includes.to_list(), 57 "Did not find {include} in includes: {includes}.".format(include = include, includes = compilation_context.includes), 58 ) 59 60 for include in ctx.attr.expected_absent_includes: 61 absolute_include = get_package_dir_based_path(env, include) 62 asserts.true( 63 env, 64 absolute_include not in compilation_context.includes.to_list(), 65 "Found {include} in includes: {includes}, was expected to be absent".format(include = include, includes = compilation_context.includes), 66 ) 67 68 for include in ctx.attr.expected_system_includes: 69 absolute_include = get_package_dir_based_path(env, include) 70 asserts.true( 71 env, 72 absolute_include in compilation_context.system_includes.to_list(), 73 "Did not find {include} in system includes: {includes}.".format(include = include, includes = compilation_context.system_includes), 74 ) 75 76 for include in ctx.attr.expected_absent_system_includes: 77 absolute_include = get_package_dir_based_path(env, include) 78 asserts.true( 79 env, 80 absolute_include not in compilation_context.system_includes.to_list(), 81 "Found {include} in system includes: {includes}, was expected to be absent".format(include = include, includes = compilation_context.system_includes), 82 ) 83 84 return analysistest.end(env) 85 86_cc_library_static_propagating_compilation_context_test = analysistest.make( 87 _cc_library_static_propagating_compilation_context_test_impl, 88 attrs = { 89 "expected_hdrs": attr.label_list(), 90 "expected_absent_hdrs": attr.label_list(), 91 "expected_includes": attr.string_list(), 92 "expected_absent_includes": attr.string_list(), 93 "expected_system_includes": attr.string_list(), 94 "expected_absent_system_includes": attr.string_list(), 95 }, 96) 97 98def _cc_library_static_propagates_deps(): 99 name = "_cc_library_static_propagates_deps" 100 dep_name = name + "_dep" 101 test_name = name + "_test" 102 103 cc_library_static( 104 name = dep_name, 105 hdrs = [":hdr"], 106 export_includes = ["a/b/c"], 107 export_system_includes = ["d/e/f"], 108 tags = ["manual"], 109 ) 110 111 cc_library_static( 112 name = name, 113 deps = [dep_name], 114 tags = ["manual"], 115 ) 116 117 _cc_library_static_propagating_compilation_context_test( 118 name = test_name, 119 target_under_test = name, 120 expected_hdrs = [":hdr"], 121 expected_includes = ["a/b/c"], 122 expected_system_includes = ["d/e/f"], 123 ) 124 125 return test_name 126 127def _cc_library_static_propagates_whole_archive_deps(): 128 name = "_cc_library_static_propagates_whole_archive_deps" 129 dep_name = name + "_dep" 130 test_name = name + "_test" 131 132 cc_library_static( 133 name = dep_name, 134 hdrs = [":hdr"], 135 export_includes = ["a/b/c"], 136 export_system_includes = ["d/e/f"], 137 tags = ["manual"], 138 ) 139 140 cc_library_static( 141 name = name, 142 whole_archive_deps = [dep_name], 143 tags = ["manual"], 144 ) 145 146 _cc_library_static_propagating_compilation_context_test( 147 name = test_name, 148 target_under_test = name, 149 expected_hdrs = [":hdr"], 150 expected_includes = ["a/b/c"], 151 expected_system_includes = ["d/e/f"], 152 ) 153 154 return test_name 155 156def _cc_library_static_propagates_dynamic_deps(): 157 name = "_cc_library_static_propagates_dynamic_deps" 158 dep_name = name + "_dep" 159 test_name = name + "_test" 160 161 cc_library_shared( 162 name = dep_name, 163 hdrs = [":hdr"], 164 export_includes = ["a/b/c"], 165 export_system_includes = ["d/e/f"], 166 tags = ["manual"], 167 ) 168 169 cc_library_static( 170 name = name, 171 dynamic_deps = [dep_name], 172 tags = ["manual"], 173 ) 174 175 _cc_library_static_propagating_compilation_context_test( 176 name = test_name, 177 target_under_test = name, 178 expected_hdrs = [":hdr"], 179 expected_includes = ["a/b/c"], 180 expected_system_includes = ["d/e/f"], 181 ) 182 183 return test_name 184 185def _cc_library_static_does_not_propagate_implementation_deps(): 186 name = "_cc_library_static_does_not_propagate_implementation_deps" 187 dep_name = name + "_dep" 188 test_name = name + "_test" 189 190 cc_library_static( 191 name = dep_name, 192 hdrs = [":hdr"], 193 export_includes = ["a/b/c"], 194 export_system_includes = ["d/e/f"], 195 tags = ["manual"], 196 ) 197 198 cc_library_static( 199 name = name, 200 implementation_deps = [dep_name], 201 tags = ["manual"], 202 ) 203 204 _cc_library_static_propagating_compilation_context_test( 205 name = test_name, 206 target_under_test = name, 207 expected_absent_hdrs = [":hdr"], 208 expected_absent_includes = ["a/b/c"], 209 expected_absent_system_includes = ["d/e/f"], 210 ) 211 212 return test_name 213 214def _cc_library_static_does_not_propagate_implementation_whole_archive_deps(): 215 name = "_cc_library_static_does_not_propagate_implementation_whole_archive_deps" 216 dep_name = name + "_dep" 217 test_name = name + "_test" 218 219 cc_library_static( 220 name = dep_name, 221 hdrs = [":hdr"], 222 export_includes = ["a/b/c"], 223 export_system_includes = ["d/e/f"], 224 tags = ["manual"], 225 ) 226 227 cc_library_static( 228 name = name, 229 implementation_whole_archive_deps = [dep_name], 230 tags = ["manual"], 231 ) 232 233 _cc_library_static_propagating_compilation_context_test( 234 name = test_name, 235 target_under_test = name, 236 expected_absent_hdrs = [":hdr"], 237 expected_absent_includes = ["a/b/c"], 238 expected_absent_system_includes = ["d/e/f"], 239 ) 240 241 return test_name 242 243def _cc_library_static_does_not_propagate_implementation_dynamic_deps(): 244 name = "_cc_library_static_does_not_propagate_implementation_dynamic_deps" 245 dep_name = name + "_dep" 246 test_name = name + "_test" 247 248 cc_library_shared( 249 name = dep_name, 250 hdrs = [":hdr"], 251 export_includes = ["a/b/c"], 252 export_system_includes = ["d/e/f"], 253 tags = ["manual"], 254 ) 255 256 cc_library_static( 257 name = name, 258 implementation_dynamic_deps = [dep_name], 259 tags = ["manual"], 260 ) 261 262 _cc_library_static_propagating_compilation_context_test( 263 name = test_name, 264 target_under_test = name, 265 expected_absent_hdrs = [":hdr"], 266 expected_absent_includes = ["a/b/c"], 267 expected_absent_system_includes = ["d/e/f"], 268 ) 269 270 return test_name 271 272def _cc_rules_do_not_allow_absolute_includes(): 273 name = "cc_rules_do_not_allow_absolute_includes" 274 test_names = [] 275 276 DISALLOWED_INCLUDE_DIRS = [ 277 "art", 278 "art/libnativebridge", 279 "art/libnativeloader", 280 "libcore", 281 "libnativehelper", 282 "external/apache-harmony", 283 "external/apache-xml", 284 "external/boringssl", 285 "external/bouncycastle", 286 "external/conscrypt", 287 "external/icu", 288 "external/okhttp", 289 "external/vixl", 290 "external/wycheproof", 291 ] 292 293 for include_dir in DISALLOWED_INCLUDE_DIRS: 294 binary_name = name + "_binary" + "_" + include_dir 295 library_headers_name = name + "_library_headers" + "_" + include_dir 296 library_shared_name = name + "_library_shared" + "_" + include_dir 297 library_static_name = name + "_library_static" + "_" + include_dir 298 299 cc_binary( 300 name = binary_name, 301 absolute_includes = [include_dir], 302 tags = ["manual"], 303 ) 304 cc_library_headers( 305 name = library_headers_name, 306 absolute_includes = [include_dir], 307 tags = ["manual"], 308 ) 309 cc_library_shared( 310 name = library_shared_name, 311 absolute_includes = [include_dir], 312 tags = ["manual"], 313 ) 314 cc_library_static( 315 name = library_static_name, 316 absolute_includes = [include_dir], 317 tags = ["manual"], 318 ) 319 320 for target in [ 321 binary_name, 322 library_headers_name, 323 library_static_name, 324 library_shared_name, 325 ]: 326 test_name = target + "_" + include_dir + "_test" 327 test_names.append(test_name) 328 expect_failure_test( 329 name = test_name, 330 target_under_test = target, 331 ) 332 333 return test_names 334 335def _cc_library_static_links_against_prebuilt_library_test_impl(ctx): 336 env = analysistest.begin(ctx) 337 actions = analysistest.target_actions(env) 338 339 asserts.equals(env, 2, len(actions), "Expected actions, got %s" % actions) 340 341 argv = actions[0].argv 342 expected_output_action1 = get_output_and_package_dir_based_path(env, "libcc_library_static_links_against_prebuilt_library_objs_only.a") 343 asserts.equals(env, 5, len(argv)) 344 asserts.equals(env, "crsPD", argv[1]) 345 asserts.equals(env, expected_output_action1, argv[2]) 346 asserts.equals(env, get_output_and_package_dir_based_path(env, paths.join("_objs", "cc_library_static_links_against_prebuilt_library_cpp", "bar.o")), argv[3]) 347 asserts.equals(env, "--format=gnu", argv[4]) 348 349 argv = actions[1].argv 350 asserts.equals(env, 6, len(argv)) 351 asserts.equals(env, "cqsL", argv[1]) 352 asserts.equals(env, get_output_and_package_dir_based_path(env, "libcc_library_static_links_against_prebuilt_library.a"), argv[2]) 353 asserts.equals(env, "--format=gnu", argv[3]) 354 asserts.equals(env, expected_output_action1, argv[4]) 355 asserts.equals(env, get_package_dir_based_path(env, "foo.a"), argv[5]) 356 357 return analysistest.end(env) 358 359_cc_library_static_links_against_prebuilt_library_test = analysistest.make(_cc_library_static_links_against_prebuilt_library_test_impl) 360 361def _cc_library_static_links_against_prebuilt_library(): 362 name = "cc_library_static_links_against_prebuilt_library" 363 test_name = name + "_test" 364 dep_name = name + "_dep" 365 366 cc_prebuilt_library_static( 367 name = dep_name, 368 static_library = "foo.a", 369 tags = ["manual"], 370 ) 371 372 cc_library_static( 373 name = name, 374 srcs = ["bar.c"], 375 whole_archive_deps = [dep_name], 376 tags = ["manual"], 377 ) 378 379 _cc_library_static_links_against_prebuilt_library_test( 380 name = test_name, 381 target_under_test = name, 382 ) 383 384 return test_name 385 386def _cc_library_static_linking_object_ordering_test_impl(ctx): 387 env = analysistest.begin(ctx) 388 actions = analysistest.target_actions(env) 389 390 asserts.equals(env, 1, len(actions), "Expected actions, got %s" % actions) 391 392 outputs = actions[0].outputs.to_list() 393 argv = actions[0].argv 394 asserts.equals(env, 4 + len(ctx.attr.expected_objects_in_order), len(argv)) 395 asserts.equals(env, "crsPD", argv[1]) 396 asserts.equals(env, outputs[0].path, argv[2]) 397 398 for i in range(len(ctx.attr.expected_objects_in_order)): 399 obj = ctx.attr.expected_objects_in_order[i] 400 asserts.equals(env, obj, paths.basename(argv[3 + i])) 401 402 asserts.equals(env, "--format=gnu", argv[-1]) 403 404 return analysistest.end(env) 405 406_cc_library_static_linking_object_ordering_test = analysistest.make( 407 _cc_library_static_linking_object_ordering_test_impl, 408 attrs = { 409 "expected_objects_in_order": attr.string_list(), 410 }, 411) 412 413def _cc_library_static_whole_archive_deps_objects_precede_target_objects(): 414 name = "_cc_library_static_whole_archive_deps_objects_precede_target_objects" 415 dep_name = name + "_dep" 416 test_name = name + "_test" 417 418 cc_library_static( 419 name = dep_name, 420 srcs = ["first.c"], 421 tags = ["manual"], 422 ) 423 424 cc_library_static( 425 name = name, 426 srcs = ["second.c"], 427 whole_archive_deps = [dep_name], 428 tags = ["manual"], 429 ) 430 431 _cc_library_static_linking_object_ordering_test( 432 name = test_name, 433 target_under_test = name, 434 expected_objects_in_order = [ 435 "first.o", 436 "second.o", 437 ], 438 ) 439 440 return test_name 441 442def _cc_library_static_provides_androidmk_info(): 443 name = "cc_library_static_provides_androidmk_info" 444 dep_name = name + "_static_dep" 445 whole_archive_dep_name = name + "_whole_archive_dep" 446 dynamic_dep_name = name + "_dynamic_dep" 447 test_name = name + "_test" 448 449 cc_library_static( 450 name = dep_name, 451 srcs = ["foo.c"], 452 tags = ["manual"], 453 ) 454 cc_library_static( 455 name = whole_archive_dep_name, 456 srcs = ["foo.c"], 457 tags = ["manual"], 458 ) 459 cc_library_shared( 460 name = dynamic_dep_name, 461 srcs = ["foo.c"], 462 tags = ["manual"], 463 ) 464 cc_library_static( 465 name = name, 466 srcs = ["foo.cc"], 467 deps = [dep_name], 468 whole_archive_deps = [whole_archive_dep_name], 469 dynamic_deps = [dynamic_dep_name], 470 tags = ["manual"], 471 ) 472 android_test_name = test_name + "_android" 473 linux_test_name = test_name + "_linux" 474 target_provides_androidmk_info_test( 475 name = android_test_name, 476 target_under_test = name, 477 expected_static_libs = [dep_name, "libc++_static", "libc++demangle"], 478 expected_whole_static_libs = [whole_archive_dep_name], 479 expected_shared_libs = [dynamic_dep_name, "libc", "libdl", "libm"], 480 target_compatible_with = ["//build/bazel/platforms/os:android"], 481 ) 482 target_provides_androidmk_info_test( 483 name = linux_test_name, 484 target_under_test = name, 485 expected_static_libs = [dep_name, "libc++_static"], 486 expected_whole_static_libs = [whole_archive_dep_name], 487 expected_shared_libs = [dynamic_dep_name], 488 target_compatible_with = ["//build/bazel/platforms/os:linux"], 489 ) 490 return [ 491 android_test_name, 492 linux_test_name, 493 ] 494 495def _cc_library_static_link_action_should_not_have_arch_cflags(): 496 name = "cc_library_static_link_action_should_not_have_cflags" 497 cpp_compile_test_name = name + "_CppCompile_test" 498 cpp_link_test_name = name + "_CppLink_test" 499 500 # https://cs.android.com/android/platform/build/soong/+/master:cc/config/arm_device.go;l=57-59;drc=de7c7847e7e028d46fdff8268689f30163c4c231 501 arm_armv7_a_cflags = ["-march=armv7-a", "-mfloat-abi=softfp"] 502 503 cc_library_static( 504 name = name, 505 srcs = ["foo.cpp"], 506 tags = ["manual"], 507 ) 508 509 action_flags_present_only_for_mnemonic_test( 510 name = cpp_compile_test_name, 511 target_under_test = name + "_cpp", 512 mnemonics = ["CppCompile"], 513 expected_flags = arm_armv7_a_cflags, 514 target_compatible_with = [ 515 "//build/bazel/platforms/os:android", 516 "//build/bazel/platforms/arch/variants:armv7-a-neon", 517 ], 518 ) 519 520 action_flags_absent_for_mnemonic_test( 521 name = cpp_link_test_name, 522 target_under_test = name, 523 mnemonics = ["CppLink"], 524 expected_absent_flags = arm_armv7_a_cflags, 525 target_compatible_with = [ 526 "//build/bazel/platforms/os:android", 527 "//build/bazel/platforms/arch/variants:armv7-a-neon", 528 ], 529 ) 530 531 return [ 532 cpp_compile_test_name, 533 cpp_link_test_name, 534 ] 535 536def _cc_library_static_defines_do_not_check_manual_binder_interfaces(): 537 name = "_cc_library_static_defines_do_not_check_manual_binder_interfaces" 538 cpp_lib_name = name + "_cpp" 539 cpp_test_name = cpp_lib_name + "_test" 540 c_lib_name = name + "_c" 541 c_test_name = c_lib_name + "_test" 542 543 cc_library_static( 544 name = name, 545 srcs = ["a.cpp"], 546 srcs_c = ["b.c"], 547 tags = ["manual"], 548 ) 549 action_flags_present_only_for_mnemonic_test( 550 name = cpp_test_name, 551 target_under_test = cpp_lib_name, 552 mnemonics = ["CppCompile"], 553 expected_flags = [ 554 "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES", 555 ], 556 ) 557 action_flags_present_only_for_mnemonic_test( 558 name = c_test_name, 559 target_under_test = c_lib_name, 560 mnemonics = ["CppCompile"], 561 expected_flags = [ 562 "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES", 563 ], 564 ) 565 566 non_allowlisted_package_cpp_name = name + "_non_allowlisted_package_cpp" 567 action_flags_absent_for_mnemonic_test( 568 name = non_allowlisted_package_cpp_name, 569 target_under_test = "//build/bazel/examples/cc:foo_static_cpp", 570 mnemonics = ["CppCompile"], 571 expected_absent_flags = [ 572 "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES", 573 ], 574 ) 575 576 return [ 577 cpp_test_name, 578 c_test_name, 579 non_allowlisted_package_cpp_name, 580 ] 581 582def cc_library_static_test_suite(name): 583 native.genrule(name = "hdr", cmd = "null", outs = ["f.h"], tags = ["manual"]) 584 585 native.test_suite( 586 name = name, 587 tests = [ 588 _cc_library_static_propagates_deps(), 589 _cc_library_static_propagates_whole_archive_deps(), 590 _cc_library_static_propagates_dynamic_deps(), 591 _cc_library_static_does_not_propagate_implementation_deps(), 592 _cc_library_static_does_not_propagate_implementation_whole_archive_deps(), 593 _cc_library_static_does_not_propagate_implementation_dynamic_deps(), 594 _cc_library_static_links_against_prebuilt_library(), 595 _cc_library_static_whole_archive_deps_objects_precede_target_objects(), 596 ] + ( 597 _cc_rules_do_not_allow_absolute_includes() + 598 _cc_library_static_provides_androidmk_info() + 599 _cc_library_static_link_action_should_not_have_arch_cflags() + 600 _cc_library_static_defines_do_not_check_manual_binder_interfaces() 601 ), 602 ) 603