xref: /aosp_15_r20/external/perfetto/gn/standalone/wasm.gni (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1# Copyright (C) 2018 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
15import("../wasm_vars.gni")
16
17# Used by //gn/standalone/toolchain/BUILD.gn .
18em_config = rebase_path(".emscripten", "")
19if (is_mac_host) {
20  emsdk_dir = rebase_path("//buildtools/mac/emsdk", "")
21} else {
22  emsdk_dir = rebase_path("//buildtools/linux64/emsdk", "")
23}
24
25# Defines a WASM library target.
26# Args:
27#  generate_js: when true generates a .wasm file and a .js file that wraps it
28#      and provides the boilerplate to initialize the module.
29#  generate_html: when true generates also an example .html file which contains
30#      a minimal console to interact with the module (useful for testing).
31template("wasm_lib") {
32  assert(defined(invoker.name))
33
34  # If the name is foo the target_name must be foo_wasm.
35  assert(invoker.name + "_wasm" == target_name)
36  _lib_name = invoker.name
37  if (is_wasm) {
38    _exports = "['ccall', 'callMain', 'addFunction', 'FS']"
39    _target_ldflags = [
40      "-s",
41      "WASM=1",
42      "-s",
43      "ENVIRONMENT=web,worker",
44      "-s",
45      "DISABLE_EXCEPTION_CATCHING=1",
46      "-s",
47      "NO_DYNAMIC_EXECUTION=1",
48      "-s",
49      "INITIAL_MEMORY=33554432",
50      "-s",
51      "MAXIMUM_MEMORY=4GB",
52      "-s",
53      "ALLOW_MEMORY_GROWTH=1",
54      "-s",
55      "ALLOW_TABLE_GROWTH=1",
56      "-s",
57      "WASM_ASYNC_COMPILATION=0",
58      "-s",
59      "EXTRA_EXPORTED_RUNTIME_METHODS=" + _exports,
60
61      # This forces the MEMFS filesystem library to always use typed arrays
62      # instead of building strings/arrays when appending to a file. This allows
63      # to deal with pseudo-files larger than 128 MB when calling traceconv.
64      "-s",
65      "MEMFS_APPEND_TO_TYPED_ARRAYS=1",
66
67      # Reduces global namespace pollution.
68      "-s",
69      "MODULARIZE=1",
70
71      # This is to prevent that two different wasm modules end up generating
72      # JS that overrides the same global variable (var Module = ...)
73      "-s",
74      "EXPORT_NAME=${target_name}",
75
76      "-lworkerfs.js",  # For FS.filesystems.WORKERFS
77    ]
78    if (is_debug) {
79      _target_ldflags += [
80        "-s",
81        "ASSERTIONS=2",
82        "-s",
83        "SAFE_HEAP=1",
84        "-s",
85        "STACK_OVERFLOW_CHECK=1",
86        "-g4",
87        "-O0",
88      ]
89    } else {
90      _target_ldflags += [
91        "-s",
92        "ASSERTIONS=1",
93        "-g2",  # Required for getting C++ symbol names.
94        "-O3",
95      ]
96    }
97
98    if (defined(invoker.js_library)) {
99      _target_ldflags += [
100        "--js-library",
101        invoker.js_library,
102      ]
103    }
104
105    _vars_to_forward = [
106      "cflags",
107      "defines",
108      "deps",
109      "includes",
110      "sources",
111      "include_dirs",
112      "public_configs",
113      "testonly",
114      "visibility",
115    ]
116
117    executable("${_lib_name}.js") {
118      forward_variables_from(invoker, _vars_to_forward)
119      ldflags = _target_ldflags
120      output_extension = ""
121    }
122
123    # This is just a workaround to deal with the fact that GN doesn't allow
124    # spcifying extra outputs for an executable() target. In reality the .wasm
125    # file here is generated by the executable() target above, together with the
126    # .js file. This dummy target is here to tell GN "there is a target that
127    # outputs also the .wasm file", so we can depend on that in copy() targets.
128    action("${_lib_name}.wasm") {
129      inputs = []
130      deps = [ ":${_lib_name}.js" ]
131      outputs = [ "$root_out_dir/$_lib_name.wasm" ]
132      if (is_debug) {
133        outputs += [ "$root_out_dir/$_lib_name.wasm.map" ]
134      }
135      args = [ "--noop" ]
136      script = "//gn/standalone/build_tool_wrapper.py"
137    }
138
139    copy("${_lib_name}.d.ts") {
140      sources = [ "//gn/standalone/wasm_typescript_declaration.d.ts" ]
141      outputs = [ "$root_out_dir/$_lib_name.d.ts" ]
142    }
143  } else {  # is_wasm
144    not_needed(invoker, "*")
145  }
146
147  group(target_name) {
148    deps = [
149      ":${_lib_name}.d.ts($wasm_toolchain)",
150      ":${_lib_name}.js($wasm_toolchain)",
151      ":${_lib_name}.wasm($wasm_toolchain)",
152    ]
153  }
154}  # template
155