|
| 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 minimal LLVMConfig.cmake that provides the necessary variables |
| 108 | +genrule( |
| 109 | + name = "generate_llvm_cmake_config", |
| 110 | + outs = [ |
| 111 | + "llvm_cmake/lib/cmake/llvm/LLVMConfig.cmake", |
| 112 | + "llvm_cmake/lib/cmake/llvm/LLVMConfigVersion.cmake", |
| 113 | + "llvm_cmake/lib/cmake/llvm/LLVMExports.cmake", |
| 114 | + ], |
| 115 | + cmd = """ |
| 116 | + # Create directory structure |
| 117 | + mkdir -p $$(dirname $(location llvm_cmake/lib/cmake/llvm/LLVMConfig.cmake)) |
| 118 | + |
| 119 | + # Determine native architecture for LLVM_NATIVE_ARCH |
| 120 | + # This is used as a placeholder - actual architecture is determined by Bazel build |
| 121 | + NATIVE_ARCH="X86" |
| 122 | + if [ "$$(uname -m)" = "aarch64" ] || [ "$$(uname -m)" = "arm64" ]; then |
| 123 | + NATIVE_ARCH="AArch64" |
| 124 | + fi |
| 125 | + |
| 126 | + # Create LLVMConfig.cmake with necessary variables |
| 127 | + # Note: Version numbers are hardcoded to match llvm-project-19.1.0.src in repositories.bzl |
| 128 | + # When upgrading LLVM, update both repositories.bzl and this version string |
| 129 | + cat > $(location llvm_cmake/lib/cmake/llvm/LLVMConfig.cmake) << EOF |
| 130 | +# Minimal LLVMConfig.cmake for Bazel builds |
| 131 | +# Generated by bazel/external/llvm.BUILD |
| 132 | + |
| 133 | +set(LLVM_VERSION_MAJOR 19) |
| 134 | +set(LLVM_VERSION_MINOR 1) |
| 135 | +set(LLVM_VERSION_PATCH 0) |
| 136 | +set(LLVM_VERSION_SUFFIX "") |
| 137 | +set(LLVM_VERSION_STRING "19.1.0") |
| 138 | + |
| 139 | +# Set library and include directories |
| 140 | +# These are relative to where WasmEdge's CMake will be running |
| 141 | +# In rules_foreign_cc sandbox, LLVM headers are available via EXT_BUILD_ROOT |
| 142 | +get_filename_component(LLVM_INSTALL_PREFIX "\\$${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE) |
| 143 | +set(LLVM_LIBRARY_DIR "\\$${LLVM_INSTALL_PREFIX}/lib") |
| 144 | +set(LLVM_CMAKE_DIR "\\$${CMAKE_CURRENT_LIST_DIR}") |
| 145 | +set(LLVM_INCLUDE_DIRS "\\$${LLVM_INSTALL_PREFIX}/include") |
| 146 | +set(LLVM_DEFINITIONS "") |
| 147 | +set(LLVM_ENABLE_ASSERTIONS OFF) |
| 148 | +set(LLVM_ENABLE_EH OFF) |
| 149 | +set(LLVM_ENABLE_RTTI OFF) |
| 150 | +set(LLVM_BUILD_TYPE "Release") |
| 151 | + |
| 152 | +# Target information |
| 153 | +set(LLVM_TARGETS_TO_BUILD "X86;AArch64") |
| 154 | +set(LLVM_NATIVE_ARCH $$NATIVE_ARCH) |
| 155 | + |
| 156 | +# Components (minimal set for WasmEdge) |
| 157 | +set(LLVM_AVAILABLE_LIBS "") |
| 158 | + |
| 159 | +# Mark as found |
| 160 | +set(LLVM_FOUND TRUE) |
| 161 | + |
| 162 | +# Include LLVMExports if it exists (it will be empty but needs to exist) |
| 163 | +include("\\$${CMAKE_CURRENT_LIST_DIR}/LLVMExports.cmake" OPTIONAL) |
| 164 | + |
| 165 | +message(STATUS "Found LLVM \\$${LLVM_VERSION_STRING} (Bazel-generated config)") |
| 166 | +message(STATUS "LLVM_CMAKE_DIR: \\$${LLVM_CMAKE_DIR}") |
| 167 | +message(STATUS "LLVM_LIBRARY_DIR: \\$${LLVM_LIBRARY_DIR}") |
| 168 | +message(STATUS "LLVM_INCLUDE_DIRS: \\$${LLVM_INCLUDE_DIRS}") |
| 169 | +EOF |
| 170 | + |
| 171 | + # Create LLVMConfigVersion.cmake |
| 172 | + # Note: Version number must match LLVM_VERSION_STRING above |
| 173 | + cat > $(location llvm_cmake/lib/cmake/llvm/LLVMConfigVersion.cmake) << 'EOF' |
| 174 | +# LLVMConfigVersion.cmake for Bazel builds |
| 175 | +set(PACKAGE_VERSION "19.1.0") |
| 176 | +set(PACKAGE_VERSION_EXACT FALSE) |
| 177 | +set(PACKAGE_VERSION_COMPATIBLE TRUE) |
| 178 | +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) |
| 179 | + set(PACKAGE_VERSION_COMPATIBLE FALSE) |
| 180 | +endif() |
| 181 | +if(PACKAGE_FIND_VERSION_MAJOR STREQUAL "19" AND |
| 182 | + PACKAGE_FIND_VERSION_MINOR STREQUAL "1") |
| 183 | + set(PACKAGE_VERSION_EXACT TRUE) |
| 184 | +endif() |
| 185 | +EOF |
| 186 | + |
| 187 | + # Create empty LLVMExports.cmake |
| 188 | + cat > $(location llvm_cmake/lib/cmake/llvm/LLVMExports.cmake) << 'EOF' |
| 189 | +# LLVMExports.cmake for Bazel builds |
| 190 | +# In Bazel builds, LLVM libraries are linked via cc_library deps, |
| 191 | +# not via CMake targets, so this file is intentionally minimal. |
| 192 | +EOF |
| 193 | + """, |
| 194 | +) |
| 195 | + |
| 196 | +filegroup( |
| 197 | + name = "llvm_cmake_config", |
| 198 | + srcs = [":generate_llvm_cmake_config"], |
| 199 | +) |
0 commit comments