Home | History | Annotate | Download | only in standalone
      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 
     15 wasm_toolchain = "//gn/standalone/toolchain:wasm"
     16 is_wasm = current_toolchain == wasm_toolchain
     17 emsdk_dir = rebase_path("//buildtools/emsdk", "")
     18 nodejs_dir = rebase_path("//buildtools/nodejs", "")
     19 
     20 # This variable is used by the //gn/standalone/toolchain/BUILD.gn.
     21 em_config = "EMSCRIPTEN_ROOT='$emsdk_dir/emscripten';"
     22 em_config += "LLVM_ROOT='$emsdk_dir/llvm';"
     23 em_config += "BINARYEN_ROOT='$emsdk_dir/llvm/binaryen';"
     24 em_config += "EMSCRIPTEN_NATIVE_OPTIMIZER='$emsdk_dir/llvm/optimizer';"
     25 em_config += "NODE_JS='$nodejs_dir/bin/node';"
     26 em_config += "COMPILER_ENGINE=NODE_JS;"
     27 em_config += "JS_ENGINES=[NODE_JS];"
     28 em_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).
     36 template("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