diff --git a/bazel/external/fmt.BUILD b/bazel/external/fmt.BUILD new file mode 100644 index 000000000..5ffb299a2 --- /dev/null +++ b/bazel/external/fmt.BUILD @@ -0,0 +1,29 @@ +# Copyright 2025 Google LLC +# +# 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. + +licenses(["notice"]) # MIT + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "fmt", + srcs = [ + "src/format.cc", + "src/os.cc", + ], + hdrs = glob([ + "include/fmt/*.h", + ]), + includes = ["include"], +) diff --git a/bazel/external/spdlog.BUILD b/bazel/external/spdlog.BUILD new file mode 100644 index 000000000..d9a913fd0 --- /dev/null +++ b/bazel/external/spdlog.BUILD @@ -0,0 +1,43 @@ +# Copyright 2025 Google LLC +# +# 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. + +licenses(["notice"]) # MIT + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "spdlog", + srcs = glob( + [ + "src/*.cpp", + ], + exclude = [ + "src/bundled*", + ], + ), + hdrs = glob( + [ + "include/**/*.h", + ], + exclude = [ + "include/spdlog/fmt/bundled/**", + ], + ), + defines = [ + "SPDLOG_FMT_EXTERNAL", + "SPDLOG_COMPILED_LIB", + ], + includes = ["include"], + deps = ["@fmt"], +) diff --git a/bazel/external/wasmedge.BUILD b/bazel/external/wasmedge.BUILD index e8fba783e..b4eea299f 100644 --- a/bazel/external/wasmedge.BUILD +++ b/bazel/external/wasmedge.BUILD @@ -26,7 +26,7 @@ filegroup( cmake( name = "wasmedge_lib", cache_entries = { - "WASMEDGE_BUILD_AOT_RUNTIME": "Off", + "WASMEDGE_USE_LLVM": "Off", "WASMEDGE_BUILD_SHARED_LIB": "Off", "WASMEDGE_BUILD_STATIC_LIB": "On", "WASMEDGE_BUILD_TOOLS": "Off", @@ -38,4 +38,8 @@ cmake( generate_args = ["-GNinja"], lib_source = ":srcs", out_static_libs = ["libwasmedge.a"], + deps = [ + "@fmt", + "@spdlog", + ], ) diff --git a/bazel/external/wasmedge.patch b/bazel/external/wasmedge.patch new file mode 100644 index 000000000..396971645 --- /dev/null +++ b/bazel/external/wasmedge.patch @@ -0,0 +1,33 @@ +diff -urN WasmEdge-0.16.1/cmake/Helper.cmake WasmEdge-0.16.1-patched/cmake/Helper.cmake +--- WasmEdge-0.16.1/cmake/Helper.cmake 2026-01-05 22:09:55.000000000 +0000 ++++ WasmEdge-0.16.1-patched/cmake/Helper.cmake 2026-01-15 07:37:20.896411038 +0000 +@@ -362,6 +362,12 @@ + endfunction() + + function(wasmedge_setup_spdlog) ++ # When building under Bazel with external dependencies, skip setup ++ # Bazel handles fmt and spdlog separately through its dependency system ++ if(DEFINED ENV{EXT_BUILD_DEPS}) ++ message(STATUS "Using fmt and spdlog from Bazel dependencies - skipping setup") ++ return() ++ endif() + if(TARGET spdlog::spdlog) + return() + endif() +diff -urN WasmEdge-0.16.1/lib/api/CMakeLists.txt WasmEdge-0.16.1-patched/lib/api/CMakeLists.txt +--- WasmEdge-0.16.1/lib/api/CMakeLists.txt 2026-01-05 22:09:55.000000000 +0000 ++++ WasmEdge-0.16.1-patched/lib/api/CMakeLists.txt 2026-01-15 07:37:20.896411038 +0000 +@@ -151,8 +151,11 @@ + endif() + + if(WASMEDGE_BUILD_STATIC_LIB) +- wasmedge_add_static_lib_component_command(fmt::fmt) +- wasmedge_add_static_lib_component_command(spdlog::spdlog) ++ # Skip fmt and spdlog when building under Bazel - they're provided separately ++ if(NOT DEFINED ENV{EXT_BUILD_DEPS}) ++ wasmedge_add_static_lib_component_command(fmt::fmt) ++ wasmedge_add_static_lib_component_command(spdlog::spdlog) ++ endif() + wasmedge_add_static_lib_component_command(wasmedgeSystem) + wasmedge_add_static_lib_component_command(wasmedgeCommon) + wasmedge_add_static_lib_component_command(wasmedgePO) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index eeb7a4688..5101b5c44 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -344,13 +344,35 @@ def proxy_wasm_cpp_host_repositories(): # WasmEdge with dependencies. + # fmt library required by WasmEdge + maybe( + http_archive, + name = "fmt", + build_file = "@proxy_wasm_cpp_host//bazel/external:fmt.BUILD", + sha256 = "40fc58bebcf38c759e11a7bd8fdc163507d2423ef5058bba7f26280c5b9c5465", + strip_prefix = "fmt-11.0.2", + url = "https://github.com/fmtlib/fmt/releases/download/11.0.2/fmt-11.0.2.zip", + ) + + # spdlog library required by WasmEdge + maybe( + http_archive, + name = "spdlog", + build_file = "@proxy_wasm_cpp_host//bazel/external:spdlog.BUILD", + sha256 = "534f2ee1a4dcbeb22249856edfb2be76a1cf4f708a20b0ac2ed090ee24cfdbc9", + strip_prefix = "spdlog-1.13.0", + url = "https://github.com/gabime/spdlog/archive/refs/tags/v1.13.0.tar.gz", + ) + maybe( http_archive, name = "com_github_wasmedge_wasmedge", build_file = "@proxy_wasm_cpp_host//bazel/external:wasmedge.BUILD", - sha256 = "7ab8a0df37c8d282ecff72d0f0bff8db63fd92df1645d5a014a9dbed4b7f9025", - strip_prefix = "WasmEdge-proxy-wasm-0.13.1", - url = "https://github.com/WasmEdge/WasmEdge/archive/refs/tags/proxy-wasm/0.13.1.tar.gz", + sha256 = "2354d90a67e3eb396179663bdc0b457abbbc70dca967ec4528f211599a49f62a", + strip_prefix = "WasmEdge-0.16.1", + url = "https://github.com/WasmEdge/WasmEdge/archive/refs/tags/0.16.1.tar.gz", + patches = ["@proxy_wasm_cpp_host//bazel/external:wasmedge.patch"], + patch_args = ["-p1"], ) # Wasmtime with dependencies. diff --git a/src/wasmedge/wasmedge.cc b/src/wasmedge/wasmedge.cc index 30fe78f5e..81481ad95 100644 --- a/src/wasmedge/wasmedge.cc +++ b/src/wasmedge/wasmedge.cc @@ -52,16 +52,15 @@ template <> WasmEdge_Value makeVal(double t) { return WasmEdge_ValueGenF64(t); } // Helper function to print values. std::string printValue(const WasmEdge_Value &value) { - switch (value.Type) { - case WasmEdge_ValType_I32: + if (WasmEdge_ValTypeIsI32(value.Type)) { return std::to_string(WasmEdge_ValueGetI32(value)); - case WasmEdge_ValType_I64: + } else if (WasmEdge_ValTypeIsI64(value.Type)) { return std::to_string(WasmEdge_ValueGetI64(value)); - case WasmEdge_ValType_F32: + } else if (WasmEdge_ValTypeIsF32(value.Type)) { return std::to_string(WasmEdge_ValueGetF32(value)); - case WasmEdge_ValType_F64: + } else if (WasmEdge_ValTypeIsF64(value.Type)) { return std::to_string(WasmEdge_ValueGetF64(value)); - default: + } else { return "unknown"; } } @@ -83,20 +82,19 @@ std::string printValues(const WasmEdge_Value *values, size_t size) { // Helper function to print valtype. const char *printValType(WasmEdge_ValType kind) { - switch (kind) { - case WasmEdge_ValType_I32: + if (WasmEdge_ValTypeIsI32(kind)) { return "i32"; - case WasmEdge_ValType_I64: + } else if (WasmEdge_ValTypeIsI64(kind)) { return "i64"; - case WasmEdge_ValType_F32: + } else if (WasmEdge_ValTypeIsF32(kind)) { return "f32"; - case WasmEdge_ValType_F64: + } else if (WasmEdge_ValTypeIsF64(kind)) { return "f64"; - case WasmEdge_ValType_ExternRef: + } else if (WasmEdge_ValTypeIsExternRef(kind)) { return "anyref"; - case WasmEdge_ValType_FuncRef: + } else if (WasmEdge_ValTypeIsFuncRef(kind)) { return "funcref"; - default: + } else { return "unknown"; } } @@ -118,6 +116,20 @@ std::string printValTypes(const WasmEdge_ValType *types, size_t size) { return s; } +// Helper function to compare vectors of WasmEdge_ValType. +bool compareValTypeVectors(const std::vector &a, + const std::vector &b) { + if (a.size() != b.size()) { + return false; + } + for (size_t i = 0; i < a.size(); i++) { + if (!WasmEdge_ValTypeIsEqual(a[i], b[i])) { + return false; + } + } + return true; +} + template struct ConvertWordType { using type = T; // NOLINT(readability-identifier-naming) }; @@ -126,12 +138,12 @@ template <> struct ConvertWordType { }; // Helper templates to convert arg to valtype. -template enum WasmEdge_ValType convArgToValType(); -template <> enum WasmEdge_ValType convArgToValType() { return WasmEdge_ValType_I32; } -template <> enum WasmEdge_ValType convArgToValType() { return WasmEdge_ValType_I32; } -template <> enum WasmEdge_ValType convArgToValType() { return WasmEdge_ValType_I64; } -template <> enum WasmEdge_ValType convArgToValType() { return WasmEdge_ValType_I64; } -template <> enum WasmEdge_ValType convArgToValType() { return WasmEdge_ValType_F64; } +template WasmEdge_ValType convArgToValType(); +template <> WasmEdge_ValType convArgToValType() { return WasmEdge_ValTypeGenI32(); } +template <> WasmEdge_ValType convArgToValType() { return WasmEdge_ValTypeGenI32(); } +template <> WasmEdge_ValType convArgToValType() { return WasmEdge_ValTypeGenI64(); } +template <> WasmEdge_ValType convArgToValType() { return WasmEdge_ValTypeGenI64(); } +template <> WasmEdge_ValType convArgToValType() { return WasmEdge_ValTypeGenF64(); } // Helper templates to convert valtype to arg. template T convValTypeToArg(WasmEdge_Value val); @@ -164,11 +176,11 @@ constexpr T convValTypesToArgsTuple(const WasmEdge_Value *arr) { // Helper templates to convert args tuple to valtypes. template -uint32_t convArgsTupleToValTypesImpl(std::vector &types, +uint32_t convArgsTupleToValTypesImpl(std::vector &types, std::index_sequence /*comptime*/) { auto size = std::tuple_size::value; if (size > 0) { - auto ps = std::array::value>{ + auto ps = std::array::value>{ convArgToValType::type>()...}; types.resize(size); std::copy_n(ps.data(), size, types.data()); @@ -177,14 +189,14 @@ uint32_t convArgsTupleToValTypesImpl(std::vector &types, } template ::value>> -uint32_t convArgsTupleToValTypes(std::vector &types) { +uint32_t convArgsTupleToValTypes(std::vector &types) { return convArgsTupleToValTypesImpl(types, Is()); } // Helper templates to create WasmEdge_FunctionTypeContext. template WasmEdge_FunctionTypeContext *newWasmEdgeFuncType() { - std::vector params; - std::vector returns; + std::vector params; + std::vector returns; uint32_t param_nums = convArgsTupleToValTypes(params); uint32_t return_nums = convArgsTupleToValTypes>(returns); auto *ftype = WasmEdge_FunctionTypeCreate(params.data(), param_nums, returns.data(), return_nums); @@ -192,7 +204,7 @@ template WasmEdge_FunctionTypeContext *newWasmEdgeFuncT } template WasmEdge_FunctionTypeContext *newWasmEdgeFuncType() { - std::vector params; + std::vector params; uint32_t param_nums = convArgsTupleToValTypes(params); auto *ftype = WasmEdge_FunctionTypeCreate(params.data(), param_nums, nullptr, 0); return ftype; @@ -521,19 +533,18 @@ void WasmEdge::getModuleFunctionImpl(std::string_view function_name, return; } - std::vector exp_args; - std::vector exp_returns; + std::vector exp_args; + std::vector exp_returns; convArgsTupleToValTypes>(exp_args); convArgsTupleToValTypes>(exp_returns); const auto *functype_cxt = WasmEdge_FunctionInstanceGetFunctionType(func_cxt); - std::vector act_args( - WasmEdge_FunctionTypeGetParametersLength(functype_cxt)); - std::vector act_returns( - WasmEdge_FunctionTypeGetReturnsLength(functype_cxt)); + std::vector act_args(WasmEdge_FunctionTypeGetParametersLength(functype_cxt)); + std::vector act_returns(WasmEdge_FunctionTypeGetReturnsLength(functype_cxt)); WasmEdge_FunctionTypeGetParameters(functype_cxt, act_args.data(), act_args.size()); WasmEdge_FunctionTypeGetReturns(functype_cxt, act_returns.data(), act_returns.size()); - if (exp_args != act_args || exp_returns != act_returns) { + if (!compareValTypeVectors(exp_args, act_args) || + !compareValTypeVectors(exp_returns, act_returns)) { fail(FailState::UnableToInitializeCode, "Bad function signature for: " + std::string(function_name) + ", want: " + printValTypes(exp_args.data(), exp_args.size()) + " -> " + @@ -574,19 +585,18 @@ void WasmEdge::getModuleFunctionImpl(std::string_view function_name, return; } - std::vector exp_args; - std::vector exp_returns; + std::vector exp_args; + std::vector exp_returns; convArgsTupleToValTypes>(exp_args); convArgsTupleToValTypes>(exp_returns); const auto *functype_cxt = WasmEdge_FunctionInstanceGetFunctionType(func_cxt); - std::vector act_args( - WasmEdge_FunctionTypeGetParametersLength(functype_cxt)); - std::vector act_returns( - WasmEdge_FunctionTypeGetReturnsLength(functype_cxt)); + std::vector act_args(WasmEdge_FunctionTypeGetParametersLength(functype_cxt)); + std::vector act_returns(WasmEdge_FunctionTypeGetReturnsLength(functype_cxt)); WasmEdge_FunctionTypeGetParameters(functype_cxt, act_args.data(), act_args.size()); WasmEdge_FunctionTypeGetReturns(functype_cxt, act_returns.data(), act_returns.size()); - if (exp_args != act_args || exp_returns != act_returns) { + if (!compareValTypeVectors(exp_args, act_args) || + !compareValTypeVectors(exp_returns, act_returns)) { fail(FailState::UnableToInitializeCode, "Bad function signature for: " + std::string(function_name) + ", want: " + printValTypes(exp_args.data(), exp_args.size()) + " -> " +