# Copyright (C) 2018 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import("../wasm_vars.gni") # Used by //gn/standalone/toolchain/BUILD.gn . em_config = rebase_path(".emscripten", "") if (is_mac_host) { emsdk_dir = rebase_path("//buildtools/mac/emsdk", "") } else { emsdk_dir = rebase_path("//buildtools/linux64/emsdk", "") } # Defines a WASM library target. # Args: # generate_js: when true generates a .wasm file and a .js file that wraps it # and provides the boilerplate to initialize the module. # generate_html: when true generates also an example .html file which contains # a minimal console to interact with the module (useful for testing). template("wasm_lib") { assert(defined(invoker.name)) # If the name is foo the target_name must be foo_wasm. assert(invoker.name + "_wasm" == target_name) _lib_name = invoker.name if (is_wasm) { _exports = "['ccall', 'callMain', 'addFunction', 'FS']" _target_ldflags = [ "-s", "WASM=1", "-s", "ENVIRONMENT=web,worker", "-s", "DISABLE_EXCEPTION_CATCHING=1", "-s", "NO_DYNAMIC_EXECUTION=1", "-s", "INITIAL_MEMORY=33554432", "-s", "ALLOW_MEMORY_GROWTH=1", "-s", "ALLOW_TABLE_GROWTH=1", "-s", "WASM_ASYNC_COMPILATION=0", "-s", "EXTRA_EXPORTED_RUNTIME_METHODS=" + _exports, # This forces the MEMFS filesystem library to always use typed arrays # instead of building strings/arrays when appending to a file. This allows # to deal with pseudo-files larger than 128 MB when calling traceconv. "-s", "MEMFS_APPEND_TO_TYPED_ARRAYS=1", # Reduces global namespace pollution. "-s", "MODULARIZE=1", # This is to prevent that two different wasm modules end up generating # JS that overrides the same global variable (var Module = ...) "-s", "EXPORT_NAME=${target_name}", "-lworkerfs.js", # For FS.filesystems.WORKERFS ] if (is_debug) { _target_ldflags += [ "-s", "ASSERTIONS=2", "-s", "SAFE_HEAP=1", "-s", "STACK_OVERFLOW_CHECK=1", "-g4", "-O0", ] } else { _target_ldflags += [ "-s", "ASSERTIONS=1", "-g2", # Required for getting C++ symbol names. "-O3", ] } if (defined(invoker.js_library)) { _target_ldflags += [ "--js-library", invoker.js_library, ] } _vars_to_forward = [ "cflags", "defines", "deps", "includes", "sources", "include_dirs", "public_configs", "testonly", "visibility", ] executable("${_lib_name}.js") { forward_variables_from(invoker, _vars_to_forward) ldflags = _target_ldflags output_extension = "" } # This is just a workaround to deal with the fact that GN doesn't allow # spcifying extra outputs for an executable() target. In reality the .wasm # file here is generated by the executable() target above, together with the # .js file. This dummy target is here to tell GN "there is a target that # outputs also the .wasm file", so we can depend on that in copy() targets. action("${_lib_name}.wasm") { inputs = [] deps = [ ":${_lib_name}.js" ] outputs = [ "$root_out_dir/$_lib_name.wasm" ] if (is_debug) { outputs += [ "$root_out_dir/$_lib_name.wasm.map" ] } args = [ "--noop" ] script = "//gn/standalone/build_tool_wrapper.py" } copy("${_lib_name}.d.ts") { sources = [ "//gn/standalone/wasm_typescript_declaration.d.ts" ] outputs = [ "$root_out_dir/$_lib_name.d.ts" ] } } else { # is_wasm not_needed(invoker, "*") } group(target_name) { deps = [ ":${_lib_name}.d.ts($wasm_toolchain)", ":${_lib_name}.js($wasm_toolchain)", ":${_lib_name}.wasm($wasm_toolchain)", ] } } # template