blob: 622423ebf3d2eb16a1129467f3a2ef881f8890b4 [file] [edit]
# 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
_is_memory64 = defined(invoker.is_memory64) && invoker.is_memory64
if (is_wasm) {
# Defaults: worker-only, no Emscripten FS. Callers opt in via
# enable_web_environment / enable_filesystem.
_enable_web = defined(invoker.enable_web_environment) &&
invoker.enable_web_environment
_enable_fs = defined(invoker.enable_filesystem) && invoker.enable_filesystem
if (_enable_web) {
_environment = "web,worker"
} else {
_environment = "worker"
}
if (_enable_fs) {
_exports = "['ccall', 'callMain', 'addFunction', 'FS', 'HEAPU8']"
} else {
_exports = "['ccall', 'callMain', 'addFunction', 'HEAPU8']"
}
_target_ldflags = [
"-s",
"WASM=1",
"-s",
"ENVIRONMENT=${_environment}",
"-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",
"STACK_SIZE=2MB",
"-s",
# Required for the Module.instantiateWasm hook used by
# wasm_engine_proxy.ts to share a precompiled Module across workers.
"WASM_ASYNC_COMPILATION=1",
"-s",
"EXPORTED_RUNTIME_METHODS=" + _exports,
# 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}",
]
if (_enable_fs) {
_target_ldflags += [
# Forces MEMFS to use typed arrays — traceconv needs this for
# pseudo-files >128 MB.
"-s",
"MEMFS_APPEND_TO_TYPED_ARRAYS=1",
"-lworkerfs.js", # For FS.filesystems.WORKERFS
]
} else {
_target_ldflags += [
"-s",
"FILESYSTEM=0",
]
}
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",
# Closure-compile the JS glue. Will silently rename any dynamic
# Module.* lookups, so any JS-side caller must only use exported
# methods.
"--closure",
"1",
]
}
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)
if (_is_memory64) {
ldflags = _target_ldflags + [
"-s",
"MEMORY64=1",
"-s",
"MAXIMUM_MEMORY=16GB",
"-mwasm64",
]
} else {
ldflags = _target_ldflags + [
"-s",
"MAXIMUM_MEMORY=4GB",
]
}
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) {
if (_is_memory64) {
_wasm_32_or_64_toolchain = wasm_memory64_toolchain
} else {
_wasm_32_or_64_toolchain = wasm_toolchain
}
deps = [
":${_lib_name}.d.ts($_wasm_32_or_64_toolchain)",
":${_lib_name}.js($_wasm_32_or_64_toolchain)",
":${_lib_name}.wasm($_wasm_32_or_64_toolchain)",
]
}
} # template