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