1# Copyright (c) 2021 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14import("//build/config/python.gni") 15import("//build/templates/common/collect_target.gni") 16import("//build/templates/metadata/module_info.gni") 17 18declare_args() { 19 native_stub = "native-stub" 20 stub_version_script_suffix = ".map.txt" 21 native_stub_signature_save_dir = "//interface/native-stub" 22} 23 24stub_signature_out_dir = "$root_out_dir/${native_stub}/signature" 25 26# Generate native stub library from native stub description file for system components. 27# 28# Variables: 29# stub_description_file: stub description file, json format with stub function names 30# install_enable: default is false, if you want install, assign with true 31# 32# Example: 33# ohos_native_stub_library("libtest_stub") { 34# output_extension = "so" 35# stub_description_file = "./libtest.stub.json" 36# } 37# It will generate libtest_stub.so with symbols defined in libtest.stub.json. 38# The stub library will not be installed by default. 39# 40# 41template("ohos_native_stub_library") { 42 forward_variables_from(invoker, [ "testonly" ]) 43 assert(defined(invoker.stub_description_file), 44 "stub description file is necessary ") 45 46 _stub_description_file = invoker.stub_description_file 47 48 _system_capability = "" 49 if (defined(invoker.system_capability)) { 50 _system_capability = invoker.system_capability 51 } 52 53 _deps = [] 54 if (defined(invoker.deps)) { 55 _deps += invoker.deps 56 } 57 58 _output_name = target_name 59 if (defined(invoker.output_name)) { 60 _output_name = invoker.output_name 61 } 62 63 _output_extension = "z.so" 64 if (defined(invoker.output_extension)) { 65 _output_extension = invoker.output_extension 66 } 67 68 _native_stub_target = "${target_name}__native_stub" 69 _generated_native_stub_file = 70 target_gen_dir + "/${target_name}.stub/" + 71 get_path_info(_stub_description_file, "name") + ".c" 72 73 _current_label = get_label_info(":${target_name}", "label_with_toolchain") 74 action_with_pydeps(_native_stub_target) { 75 deps = _deps 76 script = "//build/ohos/ndk/generate_ndk_stub_file.py" 77 depfile = "${target_gen_dir}/${target_name}.d" 78 args = [ 79 "--output", 80 rebase_path(_generated_native_stub_file, root_build_dir), 81 "--ndk-description-file", 82 rebase_path(_stub_description_file, root_build_dir), 83 "--depfile", 84 rebase_path(depfile, root_build_dir), 85 ] 86 inputs = [ _stub_description_file ] 87 outputs = [ _generated_native_stub_file ] 88 89 _stub_config_info = { 90 label = _current_label 91 lib_name = _output_name 92 system_capability = _system_capability 93 } 94 metadata = { 95 ndk_config = [ _stub_config_info ] 96 } 97 } 98 99 _stub_shlib_target = "${target_name}" 100 101 target_label = get_label_info(":${target_name}", "label_with_toolchain") 102 if (defined(invoker.subsystem_name) && defined(invoker.part_name)) { 103 subsystem_name = invoker.subsystem_name 104 part_name = invoker.part_name 105 } else if (defined(invoker.part_name)) { 106 part_name = invoker.part_name 107 _part_subsystem_info_file = 108 "$root_build_dir/build_configs/parts_info/part_subsystem.json" 109 _arguments = [ 110 "--part-name", 111 part_name, 112 "--part-subsystem-info-file", 113 rebase_path(_part_subsystem_info_file, root_build_dir), 114 ] 115 get_subsystem_script = "//build/templates/common/get_subsystem_name.py" 116 subsystem_name = 117 exec_script(get_subsystem_script, _arguments, "trim string") 118 } else if (defined(invoker.subsystem_name)) { 119 subsystem_name = invoker.subsystem_name 120 part_name = subsystem_name 121 } else { 122 subsystem_name = "build" 123 part_name = "build_framework" 124 } 125 126 module_label = get_label_info(":${target_name}", "label_with_toolchain") 127 _collect_target = "${target_name}__collect" 128 collect_module_target(_collect_target) { 129 forward_variables_from(invoker, [ "install_images" ]) 130 } 131 132 ohos_module_name = target_name 133 _module_info_target = "${target_name}_info" 134 generate_module_info(_module_info_target) { 135 module_name = ohos_module_name 136 module_type = "lib" 137 module_source_dir = target_out_dir 138 139 module_install_name = ohos_module_name 140 if (defined(invoker.output_name)) { 141 module_install_name = invoker.output_name 142 } 143 144 module_install_images = [ "system" ] 145 if (defined(invoker.install_images)) { 146 module_install_images = [] 147 module_install_images += invoker.install_images 148 } 149 150 module_output_extension = shlib_extension 151 if (defined(invoker.output_extension)) { 152 module_output_extension = "." + invoker.output_extension 153 } 154 155 install_enable = false 156 if (defined(invoker.install_enable)) { 157 install_enable = invoker.install_enable 158 } 159 160 if (defined(invoker.module_install_dir)) { 161 module_install_dir = invoker.module_install_dir 162 } 163 164 if (defined(invoker.relative_install_dir)) { 165 relative_install_dir = invoker.relative_install_dir 166 } 167 168 if (defined(invoker.symlink_target_name)) { 169 symlink_target_name = invoker.symlink_target_name 170 } 171 172 if (defined(invoker.output_prefix_override)) { 173 output_prefix_override = invoker.output_prefix_override 174 } 175 notice = "$target_out_dir/$ohos_module_name.notice.txt" 176 } 177 178 shared_library(_stub_shlib_target) { 179 forward_variables_from(invoker, 180 [ 181 "cflags", 182 "ldflags", 183 "configs", 184 "public_configs", 185 "libs", 186 "include_dirs", 187 "external_deps", 188 ]) 189 deps = [ 190 ":$_native_stub_target", 191 ":${_collect_target}", 192 ] 193 if (!skip_gen_module_info) { 194 deps += [ ":$_module_info_target" ] 195 } 196 sources = [ _generated_native_stub_file ] 197 output_dir = target_out_dir 198 output_name = _output_name 199 output_extension = _output_extension 200 201 if (defined(visibility) && visibility != []) { 202 visibility += [ "//build/*" ] 203 if (defined(build_ext_path)) { 204 visibility += [ "${build_ext_path}/*" ] 205 } 206 } 207 208 install_module_info = { 209 module_def = target_label 210 module_info_file = 211 rebase_path(get_label_info(module_def, "target_out_dir"), 212 root_build_dir) + "/${target_name}_module_info.json" 213 subsystem_name = subsystem_name 214 part_name = part_name 215 toolchain = current_toolchain 216 toolchain_out_dir = rebase_path(root_out_dir, root_build_dir) 217 } 218 metadata = { 219 install_modules = [ install_module_info ] 220 } 221 } 222} 223 224# Generate native stub library version script from native stub description file for system components. 225# 226# Variables: 227# stub_description_file: stub description file, json format with stub function names 228# 229# Example: 230# ohos_native_stub_versionscript("libtest_stub_versionscript") { 231# stub_description_file = "./libtest.stub.json" 232# } 233# It will generate version script with symbols defined in libtest.stub.json. 234# The generated version script location is: 235# get_label_info(":libtest_stub_versionscript", "target_gen_dir") + "/" + 236# get_label_info(":libtest_stub_versionscript", "name") + stub_version_script_suffix 237# 238# ohos_executable() or ohos_shared_library() can use version scripit as follow: 239# ohos_shared_library("libtest") { 240# ... 241# deps += [ ":libtest_stub_versionscript"] 242# version_script = get_label_info(":libtest_stub_versionscript", "target_gen_dir") + "/" + 243# get_label_info(":libtest_stub_versionscript", "name") + stub_version_script_suffix 244# ... 245# } 246# In this way, libtest.z.so will only export symbols specified in libtest.stub.json. 247# 248# 249template("ohos_native_stub_versionscript") { 250 assert(defined(invoker.stub_description_file), 251 "stub description file is necessary ") 252 253 _stub_description_file = invoker.stub_description_file 254 255 _deps = [] 256 if (defined(invoker.deps)) { 257 _deps += invoker.deps 258 } 259 260 _output_name = target_name 261 if (defined(invoker.output_name)) { 262 _output_name = invoker.output_name 263 } 264 265 _ndk_version_script_target = target_name 266 _generated_version_script = 267 target_gen_dir + "/$target_name" + stub_version_script_suffix 268 action_with_pydeps(_ndk_version_script_target) { 269 deps = _deps 270 script = "//build/ohos/ndk/generate_version_script.py" 271 depfile = "${target_gen_dir}/${target_name}.d" 272 args = [ 273 "--output", 274 rebase_path(_generated_version_script, root_build_dir), 275 "--ndk-description-file", 276 rebase_path(_stub_description_file, root_build_dir), 277 "--shlib-name", 278 _output_name, 279 "--depfile", 280 rebase_path(depfile, root_build_dir), 281 ] 282 outputs = [ _generated_version_script ] 283 } 284} 285 286# Specify native-stub header files 287# 288# Input variables: 289# sources: List of files. 290# 291template("ohos_native_stub_headers") { 292 assert(defined(invoker.sources), "sources are necessary ") 293 294 _stub_header_signature_target = "${target_name}__stub_signature_check" 295 _target_name = target_name 296 action_with_pydeps(_stub_header_signature_target) { 297 if (defined(invoker.deps)) { 298 deps = invoker.deps 299 } 300 301 script = "//build/ohos/ndk/check_ndk_header_signature.py" 302 depfile = "${target_gen_dir}/${target_name}.d" 303 304 inputs = [] 305 foreach(src, invoker.sources) { 306 _all_files = [] 307 _all_files = exec_script("//build/scripts/find.py", 308 [ rebase_path(src) ], 309 "list lines") 310 311 inputs += _all_files 312 } 313 314 _output = "$target_gen_dir/$target_name.stamp" 315 316 args = [ 317 "--depfile", 318 rebase_path(depfile, root_build_dir), 319 "--generated-signature", 320 rebase_path("$stub_signature_out_dir/$_target_name/signature.txt", 321 root_build_dir), 322 "--saved-signature", 323 rebase_path("$native_stub_signature_save_dir/$_target_name/signature.txt", 324 root_build_dir), 325 "--output", 326 rebase_path(_output, root_build_dir), 327 ] 328 foreach(f, inputs) { 329 args += [ 330 "--headers", 331 rebase_path(f, root_build_dir), 332 "--root-build-dir", 333 rebase_path("//", root_build_dir), 334 ] 335 } 336 337 outputs = [ _output ] 338 } 339} 340