1""" 2Copyright (C) 2023 The Android Open Source Project 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15""" 16 17load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") 18load("//build/bazel/rules/cc:cc_prebuilt_library_static.bzl", "cc_prebuilt_library_static") 19load("//build/bazel/rules/test_common:paths.bzl", "get_output_and_package_dir_based_path") 20 21_fake_expected_lib = "{[()]}" 22 23def _cc_prebuilt_library_static_alwayslink_test_impl(ctx): 24 env = analysistest.begin(ctx) 25 target = analysistest.target_under_test(env) 26 expected_lib = ctx.attr.expected_lib 27 alwayslink = ctx.attr.alwayslink 28 cc_info = target[CcInfo] 29 linker_inputs = cc_info.linking_context.linker_inputs.to_list() 30 libs_to_link = [] 31 for l in linker_inputs: 32 libs_to_link += l.libraries 33 34 has_lib = False 35 has_alwayslink = False 36 libs = {} 37 for lib_to_link in libs_to_link: 38 lib = lib_to_link.static_library.basename 39 libs[lib_to_link.static_library] = lib_to_link.alwayslink 40 if lib == expected_lib: 41 has_lib = True 42 has_alwayslink = lib_to_link.alwayslink 43 if has_alwayslink: 44 break 45 asserts.true( 46 env, 47 has_lib, 48 "\nExpected to find the static library `%s` in the linker_input:\n\t%s" % (expected_lib, str(libs)), 49 ) 50 asserts.equals( 51 env, 52 has_alwayslink, 53 alwayslink, 54 "\nExpected to find the static library `%s` unconditionally in the linker_input, with alwayslink set to %s:\n\t%s" % (expected_lib, alwayslink, str(libs)), 55 ) 56 57 return analysistest.end(env) 58 59_cc_prebuilt_library_static_alwayslink_test = analysistest.make( 60 _cc_prebuilt_library_static_alwayslink_test_impl, 61 attrs = { 62 "expected_lib": attr.string(), 63 "alwayslink": attr.bool(), 64 }, 65) 66 67def _cc_prebuilt_library_static_alwayslink_lib(alwayslink): 68 name = "_cc_prebuilt_library_static_alwayslink_lib_" + str(alwayslink) 69 test_name = name + "_test" 70 lib = "libfoo.a" 71 72 cc_prebuilt_library_static( 73 name = name, 74 static_library = lib, 75 alwayslink = alwayslink, 76 tags = ["manual"], 77 ) 78 _cc_prebuilt_library_static_alwayslink_test( 79 name = test_name, 80 target_under_test = name, 81 expected_lib = lib, 82 alwayslink = alwayslink, 83 ) 84 85 return test_name 86 87def _cc_prebuilt_library_static_test_impl(ctx): 88 env = analysistest.begin(ctx) 89 target = analysistest.target_under_test(env) 90 expected_lib = ctx.attr.expected_lib 91 cc_info = target[CcInfo] 92 compilation_context = cc_info.compilation_context 93 linker_inputs = cc_info.linking_context.linker_inputs.to_list() 94 libs_to_link = [] 95 for lib in linker_inputs: 96 libs_to_link += lib.libraries 97 98 if expected_lib == _fake_expected_lib: 99 asserts.true( 100 env, 101 len(libs_to_link) == 0, 102 "\nExpected the static library to be empty, but instead got:\n\t%s\n" % str(libs_to_link), 103 ) 104 else: 105 asserts.true( 106 env, 107 expected_lib in [lib.static_library.basename for lib in libs_to_link], 108 "\nExpected the target to include the static library %s; but instead got:\n\t%s\n" % (expected_lib, libs_to_link), 109 ) 110 111 # Checking for the expected {,system_}includes 112 assert_template = "\nExpected the %s for " + expected_lib + " to be:\n\t%s\n, but instead got:\n\t%s\n" 113 expand_paths = lambda paths: [get_output_and_package_dir_based_path(env, p) for p in paths] 114 expected_includes = expand_paths(ctx.attr.expected_includes) 115 expected_system_includes = expand_paths(ctx.attr.expected_system_includes) 116 117 includes = compilation_context.includes.to_list() 118 for include in expected_includes: 119 asserts.true(env, include in includes, assert_template % ("includes", expected_includes, includes)) 120 121 system_includes = compilation_context.system_includes.to_list() 122 for include in expected_system_includes: 123 asserts.true(env, include in system_includes, assert_template % ("system_includes", expected_system_includes, system_includes)) 124 125 return analysistest.end(env) 126 127_cc_prebuilt_library_static_test = analysistest.make( 128 _cc_prebuilt_library_static_test_impl, 129 attrs = dict( 130 expected_lib = attr.string(default = _fake_expected_lib), 131 expected_includes = attr.string_list(), 132 expected_system_includes = attr.string_list(), 133 ), 134) 135 136def _cc_prebuilt_library_static_simple(): 137 name = "_cc_prebuilt_library_static_simple" 138 test_name = name + "_test" 139 lib = "libfoo.a" 140 141 cc_prebuilt_library_static( 142 name = name, 143 static_library = lib, 144 tags = ["manual"], 145 ) 146 _cc_prebuilt_library_static_test( 147 name = test_name, 148 target_under_test = name, 149 expected_lib = lib, 150 ) 151 152 return test_name 153 154def _cc_prebuilt_library_static_None(): 155 name = "_cc_prebuilt_library_static_None" 156 test_name = name + "_test" 157 lib = None 158 159 cc_prebuilt_library_static( 160 name = name, 161 static_library = lib, 162 tags = ["manual"], 163 ) 164 _cc_prebuilt_library_static_test( 165 name = test_name, 166 target_under_test = name, 167 expected_lib = lib, # We expect the default of _fake_expected_lib 168 ) 169 170 return test_name 171 172def _cc_prebuilt_library_static_has_all_includes(): 173 name = "_cc_prebuilt_library_static_has_all_includes" 174 test_name = name + "_test" 175 lib = "libfoo.a" 176 includes = ["includes"] 177 system_includes = ["system_includes"] 178 179 cc_prebuilt_library_static( 180 name = name, 181 static_library = lib, 182 export_includes = includes, 183 export_system_includes = system_includes, 184 tags = ["manual"], 185 ) 186 _cc_prebuilt_library_static_test( 187 name = test_name, 188 target_under_test = name, 189 expected_lib = lib, 190 expected_includes = includes, 191 expected_system_includes = system_includes, 192 ) 193 194 return test_name 195 196# TODO: Test that is alwayslink = alse 197 198def cc_prebuilt_library_static_test_suite(name): 199 native.test_suite( 200 name = name, 201 tests = [ 202 _cc_prebuilt_library_static_simple(), 203 _cc_prebuilt_library_static_None(), 204 _cc_prebuilt_library_static_alwayslink_lib(True), 205 _cc_prebuilt_library_static_alwayslink_lib(False), 206 _cc_prebuilt_library_static_has_all_includes(), 207 ], 208 ) 209