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