| # Copyright 2025 The Dawn & Tint Authors | |
| # | |
| # Redistribution and use in source and binary forms, with or without | |
| # modification, are permitted provided that the following conditions are met: | |
| # | |
| # 1. Redistributions of source code must retain the above copyright notice, this | |
| # list of conditions and the following disclaimer. | |
| # | |
| # 2. Redistributions in binary form must reproduce the above copyright notice, | |
| # this list of conditions and the following disclaimer in the documentation | |
| # and/or other materials provided with the distribution. | |
| # | |
| # 3. Neither the name of the copyright holder nor the names of its | |
| # contributors may be used to endorse or promote products derived from | |
| # this software without specific prior written permission. | |
| # | |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
| # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
| # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
| # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| import("../../../scripts/dawn_overrides_with_defaults.gni") | |
| if (host_os == "win") { | |
| _exe = ".exe" | |
| } else { | |
| _exe = "" | |
| } | |
| # Directory in which to find node-addon-api | |
| dawn_node_addon_api_dir = "$dawn_root/third_party/node-addon-api" | |
| # Directory in which to find node-api-headers | |
| dawn_node_api_headers_dir = "$dawn_root/third_party/node-api-headers" | |
| # Path to the webgpu.idl definition file | |
| dawn_webgpu_idl_path = "$dawn_root/third_party/gpuweb/webgpu.idl" | |
| # Golang executable for running the IDL generator | |
| _cipd_os = "" | |
| _cipd_arch = "" | |
| if (host_os == "linux") { | |
| _cipd_os = "linux" | |
| } else if (host_os == "mac") { | |
| _cipd_os = "mac" | |
| } else if (host_os == "win") { | |
| _cipd_os = "windows" | |
| } | |
| if (host_cpu == "x64") { | |
| _cipd_arch = "amd64" | |
| } else if (host_cpu == "arm64") { | |
| _cipd_arch = "arm64" | |
| } | |
| dawn_go_executable = | |
| "$dawn_root/tools/golang/${_cipd_os}-${_cipd_arch}/bin/go${_exe}" | |
| # TODO(amaiorano): Figure out why path_exists doesn't work | |
| #assert( | |
| # path_exists(dawn_node_addon_api_dir) && | |
| # path_exists(dawn_node_api_headers_dir) && | |
| # path_exists(dawn_webgpu_idl_path), | |
| # "dawn_build_node_bindings missing dependencies. Please follow the 'Fetch dependencies' instructions at: ./src/dawn/node/README.md") | |
| dawn_node_gen_dir = target_gen_dir | |
| interop_gen_dir = "$dawn_node_gen_dir/src/dawn/node/interop" | |
| # TODO(amaiorano): Move run_built_binary.py to a common dir | |
| run_built_binary_script = "${dawn_dxc_gn_dir}/build/run_built_binary.py" | |
| config("common_config") { | |
| # Add include paths for Node API headers. | |
| include_dirs = [ | |
| "${dawn_node_addon_api_dir}", | |
| "${dawn_node_api_headers_dir}/include", | |
| ] | |
| } | |
| template("idlgen") { | |
| assert(defined(invoker.template), "must set 'template'") | |
| assert(defined(invoker.output), "must set 'output'") | |
| assert(defined(invoker.idls), "must set 'idls'") | |
| action(target_name) { | |
| assert( | |
| _cipd_os != "", | |
| "Tried to build on an unsupported OS. Allowlist may need to be updated") | |
| assert( | |
| _cipd_arch != "", | |
| "Tried to build on an unsupported architecture. Allowlist may need to be updated") | |
| idlgen_tool_dir = "$dawn_root/tools/src/cmd/idlgen" | |
| inputs = [ | |
| "$idlgen_tool_dir/main.go", | |
| invoker.template, | |
| ] + invoker.idls | |
| if (defined(invoker.depends)) { | |
| inputs += invoker.depends | |
| } | |
| outputs = [ invoker.output ] | |
| idls = [] | |
| foreach(i, invoker.idls) { | |
| idls += [ rebase_path(i, root_build_dir) ] | |
| } | |
| script = run_built_binary_script | |
| args = [ | |
| "", | |
| rebase_path(dawn_go_executable, root_build_dir), | |
| "run", | |
| rebase_path("$idlgen_tool_dir/main.go", root_build_dir), | |
| "--template", | |
| rebase_path(invoker.template, root_build_dir), | |
| "--output", | |
| rebase_path(invoker.output, root_build_dir), | |
| ] + idls | |
| } | |
| } | |
| idlgen("idlgen_webgpu_h") { | |
| template = "interop/WebGPU.h.tmpl" | |
| idls = [ | |
| "interop/Browser.idl", | |
| dawn_webgpu_idl_path, | |
| "interop/DawnExtensions.idl", | |
| ] | |
| depends = [ "interop/WebGPUCommon.tmpl" ] | |
| output = "$interop_gen_dir/WebGPU.h" | |
| } | |
| idlgen("idlgen_webgpu_cpp") { | |
| template = "interop/WebGPU.cpp.tmpl" | |
| idls = [ | |
| "interop/Browser.idl", | |
| dawn_webgpu_idl_path, | |
| "interop/DawnExtensions.idl", | |
| ] | |
| depends = [ "interop/WebGPUCommon.tmpl" ] | |
| output = "$interop_gen_dir/WebGPU.cpp" | |
| } | |
| static_library("dawn_node_interop") { | |
| public_configs = [ ":common_config" ] | |
| sources = [ | |
| "$interop_gen_dir/WebGPU.cpp", | |
| "$interop_gen_dir/WebGPU.h", | |
| "interop/Core.cpp", | |
| "interop/Core.h", | |
| "interop/NodeAPI.h", | |
| ] | |
| include_dirs = [ "${dawn_node_gen_dir}" ] | |
| deps = [ | |
| ":idlgen_webgpu_cpp", | |
| ":idlgen_webgpu_h", | |
| "$dawn_root/include/dawn:cpp_headers", | |
| "$dawn_root/src/utils", | |
| ] | |
| } | |
| static_library("dawn_node_binding") { | |
| public_configs = [ ":common_config" ] | |
| if (is_win) { | |
| # Use multibyte character set so that Win32 functions map the ANSI ones, not | |
| # the UNICODE ones. | |
| configs -= [ "//build/config/win:unicode" ] | |
| } | |
| sources = [ | |
| "binding/AsyncRunner.cpp", | |
| "binding/AsyncRunner.h", | |
| "binding/Converter.cpp", | |
| "binding/Converter.h", | |
| "binding/Errors.cpp", | |
| "binding/Errors.h", | |
| "binding/EventTarget.cpp", | |
| "binding/EventTarget.h", | |
| "binding/Flags.cpp", | |
| "binding/Flags.h", | |
| "binding/GPU.cpp", | |
| "binding/GPU.h", | |
| "binding/GPUAdapter.cpp", | |
| "binding/GPUAdapter.h", | |
| "binding/GPUAdapterInfo.cpp", | |
| "binding/GPUAdapterInfo.h", | |
| "binding/GPUBindGroup.cpp", | |
| "binding/GPUBindGroup.h", | |
| "binding/GPUBindGroupLayout.cpp", | |
| "binding/GPUBindGroupLayout.h", | |
| "binding/GPUBuffer.cpp", | |
| "binding/GPUBuffer.h", | |
| "binding/GPUCommandBuffer.cpp", | |
| "binding/GPUCommandBuffer.h", | |
| "binding/GPUCommandEncoder.cpp", | |
| "binding/GPUCommandEncoder.h", | |
| "binding/GPUComputePassEncoder.cpp", | |
| "binding/GPUComputePassEncoder.h", | |
| "binding/GPUComputePipeline.cpp", | |
| "binding/GPUComputePipeline.h", | |
| "binding/GPUDevice.cpp", | |
| "binding/GPUDevice.h", | |
| "binding/GPUPipelineLayout.cpp", | |
| "binding/GPUPipelineLayout.h", | |
| "binding/GPUQuerySet.cpp", | |
| "binding/GPUQuerySet.h", | |
| "binding/GPUQueue.cpp", | |
| "binding/GPUQueue.h", | |
| "binding/GPURenderBundle.cpp", | |
| "binding/GPURenderBundle.h", | |
| "binding/GPURenderBundleEncoder.cpp", | |
| "binding/GPURenderBundleEncoder.h", | |
| "binding/GPURenderPassEncoder.cpp", | |
| "binding/GPURenderPassEncoder.h", | |
| "binding/GPURenderPipeline.cpp", | |
| "binding/GPURenderPipeline.h", | |
| "binding/GPUResourceTable.cpp", | |
| "binding/GPUResourceTable.h", | |
| "binding/GPUSampler.cpp", | |
| "binding/GPUSampler.h", | |
| "binding/GPUShaderModule.cpp", | |
| "binding/GPUShaderModule.h", | |
| "binding/GPUSupportedFeatures.cpp", | |
| "binding/GPUSupportedFeatures.h", | |
| "binding/GPUSupportedLimits.cpp", | |
| "binding/GPUSupportedLimits.h", | |
| "binding/GPUTexture.cpp", | |
| "binding/GPUTexture.h", | |
| "binding/GPUTextureView.cpp", | |
| "binding/GPUTextureView.h", | |
| "binding/IteratorHelper.h", | |
| "binding/Split.cpp", | |
| "binding/Split.h", | |
| "binding/TogglesLoader.cpp", | |
| "binding/TogglesLoader.h", | |
| ] | |
| include_dirs = [ "${dawn_node_gen_dir}" ] | |
| public_deps = [ ":dawn_node_interop" ] | |
| deps = [ | |
| "$dawn_root/src/dawn/native", | |
| "$dawn_root/src/dawn/utils:wgpu_utils", | |
| ] | |
| } | |
| action("gen_napi_symbols") { | |
| script = "gen_napi_symbols.py" | |
| args = [ rebase_path("$dawn_root/third_party/node-api-headers/symbols.js", | |
| root_build_dir) ] | |
| if (is_win) { | |
| args += | |
| [ rebase_path("$dawn_node_gen_dir/NapiSymbols.def", root_build_dir) ] | |
| outputs = [ "$dawn_node_gen_dir/NapiSymbols.def" ] | |
| } else { | |
| args += [ rebase_path("$dawn_node_gen_dir/NapiSymbols.h", root_build_dir) ] | |
| outputs = [ "$dawn_node_gen_dir/NapiSymbols.h" ] | |
| } | |
| } | |
| if (is_win) { | |
| import("//build/config/clang/clang.gni") | |
| action("napi_symbols_lib") { | |
| inputs = [ "$dawn_node_gen_dir/NapiSymbols.def" ] | |
| outputs = [ "$dawn_node_gen_dir/NapiSymbols.lib" ] | |
| script = run_built_binary_script | |
| linker = rebase_path("$clang_base_path/bin/lld-link${_exe}", root_build_dir) | |
| args = [ | |
| "", | |
| linker, | |
| "/DEF:" + rebase_path(inputs[0], root_build_dir), | |
| "/OUT:" + rebase_path(outputs[0], root_build_dir), | |
| ] | |
| if (current_cpu == "x64") { | |
| args += [ "/machine:x64" ] | |
| } else if (current_cpu == "x86") { | |
| args += [ "/machine:x86" ] | |
| } else if (current_cpu == "arm64") { | |
| args += [ "/machine:arm64" ] | |
| } | |
| deps = [ ":gen_napi_symbols" ] | |
| } | |
| } | |
| copy("copy_index_js") { | |
| sources = [ "$dawn_root/src/dawn/node/index.js" ] | |
| outputs = [ "$root_build_dir/index.js" ] | |
| } | |
| copy("copy_cts_js") { | |
| sources = [ "$dawn_root/src/dawn/node/cts.cjs" ] | |
| outputs = [ "$root_build_dir/cts.cjs" ] | |
| } | |
| shared_library("dawn_node") { | |
| output_name = "dawn" | |
| output_extension = "node" | |
| output_prefix_override = true # dawn.node, not libdawn.node | |
| public_configs = [ ":common_config" ] | |
| sources = [ | |
| "ManualConstructors.cpp", | |
| "ManualConstructors.h", | |
| "Module.cpp", | |
| ] | |
| deps = [ | |
| ":dawn_node_binding", | |
| ":gen_napi_symbols", | |
| "$dawn_root/src/dawn:proc", | |
| ] | |
| data_deps = [ | |
| ":copy_cts_js", | |
| ":copy_index_js", | |
| ] | |
| if (is_win) { | |
| deps += [ ":napi_symbols_lib" ] | |
| ldflags = | |
| [ rebase_path("$dawn_node_gen_dir/NapiSymbols.lib", root_build_dir) ] | |
| if (current_cpu == "x64") { | |
| ldflags += [ "/machine:x64" ] | |
| } else if (current_cpu == "x86") { | |
| ldflags += [ "/machine:x86" ] | |
| } else if (current_cpu == "arm64") { | |
| ldflags += [ "/machine:arm64" ] | |
| } | |
| } else { | |
| # Don't pass '-z,defs' linker arg when compiling weak symbols | |
| configs -= [ "//build/config/compiler:no_unresolved_symbols" ] | |
| # TODO(crbug.com/404499678): GN build doesn't like when weak functions have | |
| # a definition | |
| defines = [ "NAPI_SYMBOL_WEAK_DECL_ONLY" ] | |
| if (is_mac) { | |
| # On mac, make undefined weak functions dynamic to bind with node | |
| # functions at runtime | |
| ldflags = [ "-Wl,-undefined,dynamic_lookup" ] | |
| } | |
| sources += [ "NapiSymbols.cpp" ] | |
| } | |
| include_dirs = [ "${dawn_node_gen_dir}" ] | |
| } |