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