Skip to content

Commit df7271a

Browse files
committed
add wasmedge-llvm engine
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
1 parent 45475c9 commit df7271a

10 files changed

Lines changed: 410 additions & 116 deletions

File tree

.github/workflows/test.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,22 @@ jobs:
214214
arch: x86_64
215215
action: test
216216
flags: --config=hermetic-llvm
217+
- name: 'WasmEdge llvm on Linux/x86_64'
218+
engine: 'wasmedge-llvm'
219+
repo: 'com_github_wasmedge_wasmedge'
220+
os: ubuntu-24.04-16core
221+
arch: x86_64
222+
action: test
223+
flags: --config=hermetic-llvm
224+
cache: true
225+
- name: 'WasmEdge llvm on macOS/x86_64'
226+
engine: 'wasmedge-llvm'
227+
repo: 'com_github_wasmedge_wasmedge'
228+
os: macos-15
229+
arch: x86_64
230+
action: test
231+
flags: --config=hermetic-llvm
232+
cache: true
217233
- name: 'Wasmtime on Linux/x86_64'
218234
engine: 'wasmtime'
219235
repo: 'com_github_bytecodealliance_wasmtime'
@@ -339,4 +355,3 @@ jobs:
339355
${{ matrix.flags }}
340356
--per_file_copt=src/signature_util.cc,test/signature_util_test.cc@-DPROXY_WASM_VERIFY_WITH_ED25519_PUBKEY=\"$(xxd -p -c 256 test/test_data/signature_key1.pub | cut -c3- | tr -d '\n')\"
341357
//test:signature_util_test
342-

bazel/BUILD

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ config_setting(
4242
values = {"define": "engine=wasmedge"},
4343
)
4444

45+
config_setting(
46+
name = "engine_wasmedge_llvm",
47+
values = {"define": "engine=wasmedge-llvm"},
48+
)
49+
4550
config_setting(
4651
name = "engine_wasmtime",
4752
values = {"define": "engine=wasmtime"},

bazel/external/llvm.BUILD

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Copyright 2025 Google LLC
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+
load("@rules_cc//cc:defs.bzl", "cc_library")
16+
17+
licenses(["notice"]) # Apache 2
18+
19+
package(default_visibility = ["//visibility:public"])
20+
21+
# LLVM libraries for JIT/AOT compilation - built with native Bazel.
22+
# This replaces the foreign_cc cmake build of LLVM with native Bazel builds.
23+
# These libraries are linked into the final binary for WAMR JIT and WasmEdge AOT.
24+
# Shared by both WAMR and WasmEdge for consistency.
25+
# Uses select() for CPU-specific libraries only.
26+
cc_library(
27+
name = "llvm_lib",
28+
deps = [
29+
"@llvm-project//llvm:Analysis",
30+
"@llvm-project//llvm:BitReader",
31+
"@llvm-project//llvm:BitWriter",
32+
"@llvm-project//llvm:CodeGen",
33+
"@llvm-project//llvm:Core",
34+
"@llvm-project//llvm:ExecutionEngine",
35+
"@llvm-project//llvm:IPO",
36+
"@llvm-project//llvm:IRReader",
37+
"@llvm-project//llvm:InstCombine",
38+
"@llvm-project//llvm:Instrumentation",
39+
"@llvm-project//llvm:JITLink",
40+
"@llvm-project//llvm:Linker",
41+
"@llvm-project//llvm:MC",
42+
"@llvm-project//llvm:MCJIT",
43+
"@llvm-project//llvm:Object",
44+
"@llvm-project//llvm:OrcJIT",
45+
"@llvm-project//llvm:Passes",
46+
"@llvm-project//llvm:Scalar",
47+
"@llvm-project//llvm:Support",
48+
"@llvm-project//llvm:Target",
49+
"@llvm-project//llvm:TransformUtils",
50+
"@llvm-project//llvm:Vectorize",
51+
# LLD libraries required by WasmEdge AOT codegen
52+
"@llvm-project//lld:Common",
53+
"@llvm-project//lld:ELF",
54+
] + select({
55+
"@platforms//cpu:x86_64": [
56+
"@llvm-project//llvm:X86AsmParser",
57+
"@llvm-project//llvm:X86CodeGen",
58+
"@llvm-project//llvm:X86Disassembler",
59+
],
60+
"@platforms//cpu:aarch64": [
61+
"@llvm-project//llvm:AArch64AsmParser",
62+
"@llvm-project//llvm:AArch64CodeGen",
63+
"@llvm-project//llvm:AArch64Disassembler",
64+
],
65+
"//conditions:default": [
66+
"@llvm-project//llvm:X86AsmParser",
67+
"@llvm-project//llvm:X86CodeGen",
68+
"@llvm-project//llvm:X86Disassembler",
69+
],
70+
}),
71+
)
72+
73+
# Create a tarball with LLVM headers preserving directory structure
74+
# This is a robust, bzlmod-compatible solution for providing headers to rules_foreign_cc
75+
genrule(
76+
name = "package_llvm_headers",
77+
srcs = ["@llvm_toolchain_llvm//:all_includes"],
78+
outs = ["llvm_headers.tar.gz"],
79+
cmd = """
80+
# Create temporary directory for building the archive
81+
TMPDIR=$$(mktemp -d)
82+
83+
# Copy all headers preserving directory structure
84+
# The all_includes filegroup contains files like include/llvm/Config/llvm-config.h
85+
for src in $(SRCS); do
86+
# Extract the path relative to the workspace
87+
# Files are like external/llvm_toolchain_llvm/include/llvm/...
88+
rel_path=$$(echo $$src | sed 's|.*/llvm_toolchain_llvm/||')
89+
dest_path=$$TMPDIR/$$rel_path
90+
mkdir -p $$(dirname $$dest_path)
91+
cp $$src $$dest_path
92+
done
93+
94+
# Create tarball from the temp directory
95+
tar -czf $(location llvm_headers.tar.gz) -C $$TMPDIR .
96+
rm -rf $$TMPDIR
97+
""",
98+
)
99+
100+
filegroup(
101+
name = "llvm_headers",
102+
srcs = [":package_llvm_headers"],
103+
)
104+
105+
# Create LLVM CMake config files for rules_foreign_cc
106+
# WasmEdge's CMake build needs find_package(LLVM) to work
107+
# This genrule creates a tarball with CMake config files preserving directory structure
108+
# The tarball approach ensures rules_foreign_cc extracts files to EXT_BUILD_DEPS with correct paths
109+
genrule(
110+
name = "generate_llvm_cmake_config",
111+
outs = ["llvm_cmake.tar.gz"],
112+
cmd = """
113+
# Create temporary directory for building the archive
114+
TMPDIR=$$(mktemp -d) || exit 1
115+
116+
# Ensure cleanup on exit
117+
trap 'rm -rf $$TMPDIR' EXIT
118+
119+
# Create directory structure
120+
mkdir -p $$TMPDIR/llvm_cmake/lib/cmake/llvm
121+
122+
# Determine native architecture for LLVM_NATIVE_ARCH
123+
# This is used as a placeholder - actual architecture is determined by Bazel build
124+
NATIVE_ARCH="X86"
125+
if [ "$$(uname -m)" = "aarch64" ] || [ "$$(uname -m)" = "arm64" ]; then
126+
NATIVE_ARCH="AArch64"
127+
fi
128+
129+
# Create LLVMConfig.cmake with necessary variables
130+
# Note: Version numbers are hardcoded to match llvm-project-19.1.0.src in repositories.bzl
131+
# When upgrading LLVM, update both repositories.bzl and this version string
132+
cat > $$TMPDIR/llvm_cmake/lib/cmake/llvm/LLVMConfig.cmake << EOF
133+
# Minimal LLVMConfig.cmake for Bazel builds
134+
# Generated by bazel/external/llvm.BUILD
135+
136+
set(LLVM_VERSION_MAJOR 19)
137+
set(LLVM_VERSION_MINOR 1)
138+
set(LLVM_VERSION_PATCH 0)
139+
set(LLVM_VERSION_SUFFIX "")
140+
set(LLVM_VERSION_STRING "19.1.0")
141+
142+
# Set library and include directories
143+
# These are relative to where WasmEdge's CMake will be running
144+
# In rules_foreign_cc sandbox, LLVM headers are available via EXT_BUILD_ROOT
145+
get_filename_component(LLVM_INSTALL_PREFIX "\\$${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE)
146+
set(LLVM_LIBRARY_DIR "\\$${LLVM_INSTALL_PREFIX}/lib")
147+
set(LLVM_CMAKE_DIR "\\$${CMAKE_CURRENT_LIST_DIR}")
148+
set(LLVM_INCLUDE_DIRS "\\$${LLVM_INSTALL_PREFIX}/include")
149+
set(LLVM_DEFINITIONS "")
150+
set(LLVM_ENABLE_ASSERTIONS OFF)
151+
set(LLVM_ENABLE_EH OFF)
152+
set(LLVM_ENABLE_RTTI OFF)
153+
set(LLVM_BUILD_TYPE "Release")
154+
155+
# Target information
156+
set(LLVM_TARGETS_TO_BUILD "X86;AArch64")
157+
set(LLVM_NATIVE_ARCH $$NATIVE_ARCH)
158+
159+
# Components (minimal set for WasmEdge)
160+
set(LLVM_AVAILABLE_LIBS "")
161+
162+
# Mark as found
163+
set(LLVM_FOUND TRUE)
164+
165+
# Include LLVMExports if it exists (it will be empty but needs to exist)
166+
include("\\$${CMAKE_CURRENT_LIST_DIR}/LLVMExports.cmake" OPTIONAL)
167+
168+
message(STATUS "Found LLVM \\$${LLVM_VERSION_STRING} (Bazel-generated config)")
169+
message(STATUS "LLVM_CMAKE_DIR: \\$${LLVM_CMAKE_DIR}")
170+
message(STATUS "LLVM_LIBRARY_DIR: \\$${LLVM_LIBRARY_DIR}")
171+
message(STATUS "LLVM_INCLUDE_DIRS: \\$${LLVM_INCLUDE_DIRS}")
172+
EOF
173+
174+
# Create LLVMConfigVersion.cmake
175+
# Note: Version number must match LLVM_VERSION_STRING above
176+
cat > $$TMPDIR/llvm_cmake/lib/cmake/llvm/LLVMConfigVersion.cmake << 'EOF'
177+
# LLVMConfigVersion.cmake for Bazel builds
178+
set(PACKAGE_VERSION "19.1.0")
179+
set(PACKAGE_VERSION_EXACT FALSE)
180+
set(PACKAGE_VERSION_COMPATIBLE TRUE)
181+
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
182+
set(PACKAGE_VERSION_COMPATIBLE FALSE)
183+
endif()
184+
if(PACKAGE_FIND_VERSION_MAJOR STREQUAL "19" AND
185+
PACKAGE_FIND_VERSION_MINOR STREQUAL "1")
186+
set(PACKAGE_VERSION_EXACT TRUE)
187+
endif()
188+
EOF
189+
190+
# Create empty LLVMExports.cmake
191+
cat > $$TMPDIR/llvm_cmake/lib/cmake/llvm/LLVMExports.cmake << 'EOF'
192+
# LLVMExports.cmake for Bazel builds
193+
# In Bazel builds, LLVM libraries are linked via cc_library deps,
194+
# not via CMake targets, so this file is intentionally minimal.
195+
EOF
196+
197+
# Create tarball from the temp directory
198+
tar -czf $(location llvm_cmake.tar.gz) -C $$TMPDIR llvm_cmake
199+
""",
200+
)
201+
202+
filegroup(
203+
name = "llvm_cmake_config",
204+
srcs = [":generate_llvm_cmake_config"],
205+
)

bazel/external/wamr.BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ cc_library(
107107
}),
108108
deps = [":wamr_lib_cmake"] + select({
109109
"@proxy_wasm_cpp_host//bazel:engine_wamr_jit": [
110-
"@llvm-raw//:llvm_wamr_lib",
110+
"@llvm-raw//:llvm_lib",
111111
],
112112
"//conditions:default": [],
113113
}),

bazel/external/wamr_llvm.BUILD

Lines changed: 0 additions & 100 deletions
This file was deleted.

0 commit comments

Comments
 (0)