1"""Unittests for the --experimental_use_cc_common_link build setting.""" 2 3load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") 4load("@rules_cc//cc:defs.bzl", "cc_library") 5load( 6 "@rules_rust//rust:defs.bzl", 7 "rust_binary", 8 "rust_shared_library", 9 "rust_test", 10) 11 12DepActionsInfo = provider( 13 "Contains information about dependencies actions.", 14 fields = {"actions": "List[Action]"}, 15) 16 17def _collect_dep_actions_aspect_impl(target, _ctx): 18 return [DepActionsInfo(actions = target.actions)] 19 20collect_dep_actions_aspect = aspect( 21 implementation = _collect_dep_actions_aspect_impl, 22) 23 24def _use_cc_common_link_transition_impl(_settings, _attr): 25 return {"@rules_rust//rust/settings:experimental_use_cc_common_link": True} 26 27use_cc_common_link_transition = transition( 28 inputs = [], 29 outputs = ["@rules_rust//rust/settings:experimental_use_cc_common_link"], 30 implementation = _use_cc_common_link_transition_impl, 31) 32 33def _use_cc_common_link_on_target_impl(ctx): 34 return [ctx.attr.target[0][DepActionsInfo]] 35 36use_cc_common_link_on_target = rule( 37 implementation = _use_cc_common_link_on_target_impl, 38 attrs = { 39 "target": attr.label( 40 cfg = use_cc_common_link_transition, 41 aspects = [collect_dep_actions_aspect], 42 ), 43 "_allowlist_function_transition": attr.label( 44 default = Label("@bazel_tools//tools/allowlists/function_transition_allowlist"), 45 ), 46 }, 47) 48 49def _outputs_object_file(action): 50 object_files = [output for output in action.outputs.to_list() if output.extension in ("o", "obj")] 51 return len(object_files) > 0 52 53def _use_cc_common_link_test(ctx): 54 env = analysistest.begin(ctx) 55 tut = analysistest.target_under_test(env) 56 registered_actions = tut[DepActionsInfo].actions 57 58 # When --experimental_use_cc_common_link is enabled the compile+link Rustc action produces a 59 # .o/.obj file. 60 rustc_action = [action for action in registered_actions if action.mnemonic == "Rustc"][0] 61 asserts.true(env, _outputs_object_file(rustc_action), "Rustc action did not output an object file") 62 63 has_cpp_link_action = len([action for action in registered_actions if action.mnemonic == "CppLink"]) > 0 64 asserts.true(env, has_cpp_link_action, "Expected that the target registers a CppLink action") 65 66 return analysistest.end(env) 67 68use_cc_common_link_test = analysistest.make(_use_cc_common_link_test) 69 70def _custom_malloc_test(ctx): 71 env = analysistest.begin(ctx) 72 tut = analysistest.target_under_test(env) 73 registered_actions = tut[DepActionsInfo].actions 74 links = [action for action in registered_actions if action.mnemonic == "CppLink"] 75 cmdline = " ".join(links[0].argv) 76 asserts.true(env, "this_library_is_not_really_an_allocator" in cmdline, "expected to find custom malloc in linker invocation") 77 return analysistest.end(env) 78 79custom_malloc_test = analysistest.make( 80 _custom_malloc_test, 81 config_settings = { 82 "//command_line_option:custom_malloc": "@//unit:this_library_is_not_really_an_allocator", 83 }, 84) 85 86def _cc_common_link_test_targets(): 87 """Generate targets and tests.""" 88 89 cc_library( 90 name = "this_library_is_not_really_an_allocator", 91 srcs = ["this_library_is_not_really_an_allocator.c"], 92 ) 93 94 rust_binary( 95 name = "bin", 96 srcs = ["bin.rs"], 97 edition = "2018", 98 ) 99 100 use_cc_common_link_on_target( 101 name = "bin_with_cc_common_link", 102 target = ":bin", 103 ) 104 105 rust_shared_library( 106 name = "cdylib", 107 srcs = ["lib.rs"], 108 edition = "2018", 109 ) 110 111 use_cc_common_link_on_target( 112 name = "cdylib_with_cc_common_link", 113 target = ":cdylib", 114 ) 115 116 rust_test( 117 name = "test_with_srcs", 118 srcs = ["lib.rs"], 119 edition = "2018", 120 ) 121 122 use_cc_common_link_on_target( 123 name = "test_with_cc_common_link", 124 target = ":test_with_srcs", 125 testonly = True, 126 ) 127 128 rust_test( 129 name = "test-with-crate", 130 crate = "cdylib", 131 edition = "2018", 132 ) 133 134 use_cc_common_link_on_target( 135 name = "crate_test_with_cc_common_link", 136 target = ":test-with-crate", 137 testonly = True, 138 ) 139 140 use_cc_common_link_test( 141 name = "use_cc_common_link_on_binary", 142 target_under_test = ":bin_with_cc_common_link", 143 ) 144 145 use_cc_common_link_test( 146 name = "use_cc_common_link_on_test", 147 target_under_test = ":test_with_cc_common_link", 148 ) 149 150 use_cc_common_link_test( 151 name = "use_cc_common_link_on_crate_test", 152 target_under_test = ":crate_test_with_cc_common_link", 153 ) 154 155 use_cc_common_link_test( 156 name = "use_cc_common_link_on_cdylib", 157 target_under_test = ":cdylib_with_cc_common_link", 158 ) 159 160 custom_malloc_test( 161 name = "custom_malloc_on_binary_test", 162 target_under_test = ":bin_with_cc_common_link", 163 ) 164 165def cc_common_link_test_suite(name): 166 """Entry-point macro called from the BUILD file. 167 168 Args: 169 name: Name of the macro. 170 """ 171 _cc_common_link_test_targets() 172 173 native.test_suite( 174 name = name, 175 tests = [ 176 "use_cc_common_link_on_binary", 177 "use_cc_common_link_on_test", 178 "use_cc_common_link_on_crate_test", 179 "use_cc_common_link_on_cdylib", 180 "custom_malloc_on_binary_test", 181 ], 182 ) 183