1# Copyright (c) 2021-2024 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("//arkcompiler/runtime_core/static_core/ark_root.gni")
15import("//arkcompiler/runtime_core/static_vm_config.gni")
16
17if (ark_standalone_build) {
18  import("$build_root/ark.gni")
19} else {
20  import("//build/ohos.gni")
21}
22
23ark_subsystem_name = "arkcompiler"
24ark_part_name = "runtime_core"
25
26if (is_standard_system || ark_standalone_build) {
27  import("$ark_root/platforms/ohos/ark_config.gni")
28} else {
29  import("$ark_root/platforms/mobile/ark_config.gni")
30}
31
32declare_args() {
33  ark_enabled_plugins = default_ark_enabled_plugins
34  extras = []
35  if (!defined(is_ohos)) {
36    is_ohos = false
37  }
38  if (!defined(is_standard_system)) {
39    is_standard_system = true
40  }
41
42  if (!defined(is_llvmbackend)) {
43    is_llvmbackend = false
44  }
45
46  if (is_ohos && is_standard_system) {
47    ark_ets_interop_js = true
48  } else {
49    ark_ets_interop_js = false
50  }
51}
52
53declare_args() {
54  if (!defined(is_llvm_interpreter)) {
55    is_llvm_interpreter = is_llvmbackend
56  }
57  if (!defined(is_llvm_fastpath)) {
58    is_llvm_fastpath = is_llvmbackend && target_cpu == "arm64"
59  }
60  if (!defined(is_llvm_aot)) {
61    is_llvm_aot = is_llvmbackend
62  }
63}
64
65if (current_cpu == "arm") {
66  if (!defined(arm_float_abi) || arm_float_abi == "") {
67    arm_float_abi = "softfp"
68  }
69
70  assert(arm_float_abi == "soft" || arm_float_abi == "softfp" ||
71             arm_float_abi == "hard",
72         "arm_float_abi should be soft, softfp or hard")
73}
74
75ark_root_gen_dir = "$root_gen_dir/ark_sig"
76
77concat_gen_dir =
78    get_label_info("$ark_root:concat_plugins_yamls", "target_gen_dir")
79ark_plugin_options_yaml = "$concat_gen_dir/plugin_options.yaml"
80
81isa_gen_dir = get_label_info("$ark_root/isa:isa_combine", "target_gen_dir")
82ark_isa_yaml = "$isa_gen_dir/isa.yaml"
83
84enable_irtoc = true
85enable_codegen = true
86enable_libabckit = false
87if (ark_standalone_build || (!ark_static_standalone_build &&
88                             (target_cpu == "x64" || target_cpu == "x86_64"))) {
89  enable_irtoc = false
90  enable_codegen = false
91  is_llvmbackend = false
92  is_llvm_interpreter = false
93  is_llvm_fastpath = false
94  is_llvm_aot = false
95}
96if (target_cpu == "arm") {
97  is_llvmbackend = false
98  is_llvm_interpreter = false
99  is_llvm_fastpath = false
100  is_llvm_aot = false
101}
102
103if (!is_llvmbackend) {
104  assert(!is_llvm_interpreter,
105         "LLVM Irtoc Interpreter requires is_llvmbackend=true")
106  assert(!is_llvm_fastpath,
107         "LLVM Fastpath compilation feature requires is_llvmbackend=true")
108  assert(!is_llvm_aot,
109         "LLVM AOT compilation feature requires is_llvmbackend=true")
110} else {
111  assert(!is_llvm_fastpath || target_cpu == "arm64",
112         "LLVM Fastpath compilation available only for arm64 target")
113}
114
115ark_enable_global_register_variables = true
116enable_bytecode_optimizer = true
117enable_relayout_profile = false
118vixl_with_panda = true
119
120sdk_libc_secshared_dep = ""
121sdk_libc_secshared_ext_dep = ""
122sdk_libc_secshared_config = ""
123
124zlib_public_config = "$ark_third_party_root/zlib:zlib_public_config"
125zlib_dep = "zlib:libz"
126
127icui18n_dep = "icu:shared_icui18n"
128icuuc_dep = "icu:shared_icuuc"
129vixl_dep = "vixl:libvixl"
130
131if (ark_static_standalone_build) {
132  sdk_libc_secshared_dep = "$ark_third_party_root/securec:libc_secshared"
133  sdk_libc_secshared_ext_dep = "$ark_third_party_root/securec:libc_secshared"
134  sdk_libc_secshared_config =
135      "$ark_third_party_root/securec:libsec_public_config"
136  zlib_dep = "$ark_third_party_root/zlib:libz"
137  icui18n_dep = "$ark_third_party_root/icu/icu4c:shared_icui18n"
138  icuuc_dep = "$ark_third_party_root/icu/icu4c:shared_icuuc"
139  vixl_dep = "$ark_third_party_root/vixl:libvixl"
140
141  if (is_mingw || is_mac || is_linux) {
142    sdk_libc_secshared_dep = "$ark_third_party_root/securec:libc_secstatic"
143    sdk_libc_secshared_ext_dep = "$ark_third_party_root/securec:libc_secstatic"
144  }
145} else {
146  # For OpenHarmony build, always link with the static lib:
147  sdk_libc_secshared_dep = "bounds_checking_function:libsec_static"
148  sdk_libc_secshared_ext_dep = "bounds_checking_function:libsec_static"
149}
150
151is_mob = !is_ohos && !is_linux && !is_mingw && !is_mac &&
152         (current_cpu != "arm" || is_wearable_product)
153
154if (is_ohos && is_standard_system) {
155  hilog_root = "//base/hiviewdfx/hilog/interfaces/native/innerkits"
156}
157
158## TODO add other arch
159
160# Generate file for a template and YAML data provided.
161#
162# Mandatory arguments:
163# data -- a list of data sources, YAML files
164# template_file -- template full name
165# output_file -- output file full name
166# api -- a list of Ruby scripts that provide data-querying API for templates
167#   (Nth script from 'api' should parse Nth YAML file from 'data')
168#
169# Optional arguments:
170# extra_dependencies -- a list of files that should be considered as dependencies, must be lable
171# requires -- if defined, will require additional Ruby files for template generation, must be list
172
173template("ark_gen_file") {
174  assert(defined(invoker.data), "data is required!")
175  assert(defined(invoker.api), "api is required!")
176  assert(defined(invoker.template_file), "template_file is required!")
177  assert(defined(invoker.output_file), "output_file is required!")
178
179  extra_dependencies = []
180  if (defined(invoker.extra_dependencies)) {
181    extra_dependencies += invoker.extra_dependencies
182  }
183
184  positional_argv = []
185  if (defined(invoker.extra_argv)) {
186    positional_argv += invoker.extra_argv
187  }
188  keyword_argv = [
189    "--template",
190    rebase_path(invoker.template_file, root_build_dir),
191    "--data",
192    string_join(",", rebase_path(invoker.data, root_build_dir)),
193    "--api",
194    string_join(",", rebase_path(invoker.api, root_build_dir)),
195    "--output",
196    rebase_path(invoker.output_file),
197  ]
198  if (defined(invoker.requires)) {
199    keyword_argv += [
200      "--require",
201      string_join(",", rebase_path(invoker.requires, root_build_dir)),
202    ]
203  }
204
205  action("$target_name") {
206    script = "$ark_root/isa/gen.rb"
207
208    # rerun action when data file or template file update
209    inputs = [ invoker.template_file ] + invoker.data
210    outputs = [ invoker.output_file ]
211    args = positional_argv + keyword_argv
212    deps = extra_dependencies
213  }
214}
215
216template("concat_yamls") {
217  assert(defined(invoker.output_file), "output_file is required!")
218  assert(defined(invoker.default_file), "default_file is required!")
219
220  extra_dependencies = []
221  if (defined(invoker.extra_dependencies)) {
222    extra_dependencies += invoker.extra_dependencies
223  }
224
225  outputs = [ invoker.output_file ]
226
227  action("$target_name") {
228    script = "$ark_root/templates/concat_yamls.sh"
229
230    # rerun action when data file or template file update
231    inputs = [ invoker.default_file ]
232
233    args = [
234      rebase_path(invoker.output_file, root_build_dir),
235      rebase_path(invoker.default_file, root_build_dir),
236    ]
237
238    foreach(yaml, invoker.add_yamls) {
239      args += [ rebase_path(yaml, root_build_dir) ]
240    }
241
242    deps = extra_dependencies
243  }
244}
245
246template("merge_yamls") {
247  assert(defined(invoker.output_file), "output_file is required!")
248  assert(defined(invoker.add_yamls), "add_yamls is required!")
249
250  extra_dependencies = []
251  if (defined(invoker.extra_dependencies)) {
252    extra_dependencies += invoker.extra_dependencies
253  }
254
255  outputs = [ invoker.output_file ]
256
257  action("$target_name") {
258    script = "$ark_root/templates/merge.rb"
259
260    data = []
261    foreach(yaml, invoker.add_yamls) {
262      data += [ rebase_path(yaml, root_build_dir) ]
263    }
264    args = [
265      "-d",
266      string_join(",", data),
267      "-o",
268      rebase_path(invoker.output_file, root_build_dir),
269    ]
270
271    deps = extra_dependencies
272  }
273}
274
275# Generate files based on templates and YAML data provided.
276# Adds targets for every template. Also adds a target for the whole function invocation
277# with name ${data_name}_gen_${PROJECT_NAME} for ease of declaring dependencies on generated files.
278#
279# Mandatory arguments:
280# * data -- a list of data sources, YAML files
281# * template_files -- a list of templates to generate files
282# * api -- a list of Ruby scripts that provide data-querying API for templates
283#   (Nth script from 'api' should parse Nth YAML file from 'data')
284#
285# Optional arguments:
286# * sources -- a directory with templates, default is ${PROJECT_SOURCE_DIR}/templates
287# * destination -- a directory for output files, default is ${PANDA_BINARY_ROOT}
288# * extra_dependencies -- a list of files that should be considered as dependencies
289# * requires -- if defined, will require additional Ruby files for template generation, must be list
290# * extra_argv -- a list of positional arguments that could be accessed in '.erb' files via ARGV[]
291template("ark_gen") {
292  assert(defined(invoker.data), "data files were not passed to ark_gen")
293  assert(defined(invoker.api), "ruby api files were not passed to ark_gen")
294  assert(defined(invoker.template_files),
295         "template_files were not passed to ark_gen")
296
297  if (defined(invoker.sources)) {
298    dir = invoker.sources
299  } else {
300    dir = "templates"
301  }
302
303  if (defined(invoker.destination)) {
304    destination = invoker.destination
305  } else {
306    destination = target_out_dir
307  }
308
309  foreach(t, invoker.template_files) {
310    name = string_replace(t, ".erb", "")
311    output = "${destination}/${name}"
312    name = string_replace(name, ".", "_")
313    name = string_replace(name, "/", "_")
314    target = "${target_name}_${name}"
315
316    ark_gen_file(target) {
317      data = invoker.data
318      template_file = "${dir}/${t}"
319      output_file = output
320      api = invoker.api
321      if (defined(invoker.requires)) {
322        requires = invoker.requires
323      }
324      if (defined(invoker.extra_dependencies)) {
325        extra_dependencies = invoker.extra_dependencies
326      }
327      if (defined(invoker.extra_argv)) {
328        extra_argv = invoker.extra_argv
329      }
330    }
331  }
332}
333
334# Calls `ark_gen` for ISA YAML.
335# Adds targets for every template. Also adds a target for the whole function invocation
336# with name isa_gen_${PROJECT_NAME} for ease of declaring dependencies on generated files.
337#
338# Mandatory arguments:
339# * template_files -- a list of templates to generate files
340#
341# Optional arguments:
342# * sources -- a directory with templates, default is ${PROJECT_SOURCE_DIR}/templates
343# * destination -- a directory for output files, default is ${target_out_dir}
344# * requires -- if defined, will require additional Ruby files for template generation, must be list
345# * extra_dependencies -- a list of files that should be considered as dependencies lable, must be list, not used
346template("ark_isa_gen") {
347  isa_api = [ "$ark_root/isa/isapi.rb" ]
348  dependencies = [ "$ark_root/isa:isa_combine" ]
349  if (defined(invoker.extra_dependencies)) {
350    dependencies += invoker.extra_dependencies
351  }
352
353  ark_gen("$target_name") {
354    data = [ ark_isa_yaml ]
355    template_files = invoker.template_files
356    sources = invoker.sources
357    destination = invoker.destination
358    api = isa_api
359    if (defined(invoker.requires)) {
360      requires = invoker.requires
361    }
362    extra_dependencies = dependencies
363  }
364}
365
366# Run ark_asm
367#
368# Arguments:
369# * input_file -- Path to the source assembly code
370# * output_file -- Path to the generated binary code
371template("ark_asm_gen") {
372  action(target_name) {
373    ark_asm_root_out =
374        get_label_info("$ark_root/assembler:arkts_asm(${host_toolchain})",
375                       "root_out_dir")
376    script = ark_asm_root_out + "/$ark_subsystem_name/$ark_part_name/ark_asm"
377
378    inputs = [ invoker.input_file ]
379    outputs = [ invoker.output_file ]
380    args = [
381      rebase_path(invoker.input_file, root_build_dir),
382      rebase_path(invoker.output_file, root_build_dir),
383    ]
384
385    deps = [ "$ark_root/assembler:arkts_asm(${host_toolchain})" ]
386  }
387}
388
389# Run es2panda
390#
391# Arguments:
392# The same you would pass to action except script and deps.
393template("es2panda_gen") {
394  action(target_name) {
395    es2panda_root_out =
396        get_label_info("$ark_es2panda_root/aot:ets2panda(${host_toolchain})",
397                       "root_out_dir")
398    if (ark_static_standalone_build || ark_standalone_build) {
399      deps = [ "$ark_es2panda_root/aot:ets2panda" ]
400      es2panda_bin = "/bin/es2panda"
401    } else {
402      external_deps = [ "ets_frontend:ets2panda(${host_toolchain})" ]
403      es2panda_bin = "/arkcompiler/ets_frontend/es2panda"
404    }
405
406    script = es2panda_root_out + es2panda_bin
407
408    inputs = invoker.inputs
409    outputs = invoker.outputs
410    args = invoker.args
411  }
412}
413