llvm bazel module(s)
Warning
|
Experimental. Not stable. Only tested on MacOS. |
-
the sole purpose of the primary module (
@obazl_llvm
) is to host the extension that generates the subrepos that do the work:@llvm
,@llvm_c_sdk
,llvm_ocaml_sdk
, etc. -
toolchain and sdks are independent. You can use an sdk with whatever toolchain you want; you don’t have to use the llvm/clang toolchain.
-
two very rudimentary Proof of Concept demos,
demos/clang/c/demo2
anddemos/llvm/c/hello
. To build themcd
to the subdir containing theMODULE.bazel
file and runbazel build demo2
andbazel build hello
respectively. Or trybazel run
(you’ll have to read the code to see how they work).
This submodule configures an llvm installation for use by the SDK submodules described below. It also contains an optional llvm/clang toolchain.
bazel_dep(name = "obazl_llvm", version = "x.y.z") llvm = use_extension("@obazl_llvm//extensions:llvm.bzl", "llvm") llvm.config(llvm_root = "@@//.config/llvm:root") (1) use_repo(llvm, "llvm") register_toolchains("@llvm//toolchain:all") (2)
-
llvm_root
label of file containing path to llvm installation -
Optional. You can use the SDKs this module provides with your local CC toolchain; using the llvm/clang toolchain is opt-in.
/path/to/llvm-installation # only the first line of this file is read # example: an unpacked binary distro: /Users/<uid>/llvm/clang+llvm-17.0.1-arm64-apple-darwin22.0 # example: built from llvm-project clone: /Users/<uid>/llvm/llvm-project/build
Here llvm-installation
can be a binary distribution or a source
distribution that you have built.
The function of llvm.config(llvm_root = …)
is analogous to the
function of try-import
in a bazelrc file: it reads the file if it
exists, and ignores it if not. This allows you to integrate a prebuilt
llvm installation.
Caution
|
The intended (but not yet implemented) default is to download
a distribution if llvm_root is omitted, or the file does not exist.
Currently you can only use this module with a local llvm installation.
|
Note
|
Currently the SDKs are implemented as separate Bazel modules
that use symlinks to piggy-back on the configuration set up by
@llvm . Another option would be to put everything in the @llvm
namespace, so we would have something like @llvm//sdk/llvm/c instead
of @llvm_c_sdk , @llvm//sdk/clang/c instead of @clang_c_sdk , etc.
|
llvm.llvm_c_sdk() use_repo(llvm, "llvm_c_sdk")
cc_binary( name = "hello", srcs = ["hello.c"], deps = [ "@llvm_c_sdk//include", "@llvm_c_sdk//lib:LLVMBinaryFormat", "@llvm_c_sdk//lib:LLVMBitstreamReader", "@llvm_c_sdk//lib:LLVMCore", "@llvm_c_sdk//lib:LLVMDemangle", "@llvm_c_sdk//lib:LLVMRemarks", "@llvm_c_sdk//lib:LLVMSupport", "@llvm_c_sdk//lib:LLVMTargetParser", # OR: "@llvm_c_sdk//lib:all-libs", ], copts = [ "-I$(@llvm_c_sdk)/include", (1) ... ], ... toolchains = ["//:repo_paths"] (1) )
-
The demos use a utility tool that defines make variables for module names; in this case,
"$(@llvm_c_sdk)"
expands toexternal/obazl_llvm~override~llvm~llvm_c_sdk
. Seerepo_paths
below for more information.
There’s no reason all the other sdks supported by llvm could not be accomodated by this modular design.
-
@mlir_c_sdk
(mlir c api) -
etc.
To enable module name make variables (like "$(@llvm_c_sdk)"
) you can
use cc_config as follows:
bazel_dep(name = "cc_config", version = "1.0.0")
Then in any build file add the following:
load("@cc_config//:MACROS.bzl", "repo_paths") repo_paths( name = "repo_paths", repos = ["@llvm_c_sdk//version"]) (1)
-
Items in the
repos
list may be any build target. The tool just uses it to obtain the expansion of the module name.
Then to use the make variables in a cc_*
target:
toolchains = ["//:repo_paths"]
examples:
cmake -S llvm -B .build.16.0.6 -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=polly -DLLVM_ENABLE_BINDINGS=0 -DLLVM_BUILD_LLVM_DYLIB=ON
-
-B
controls the build output directory. Makes it easy to build multiple versions of the compiler. -
-DLLVM_ENABLE_PROJECTS=polly
- needed for the ocaml sdk? -
-DLLVM_ENABLE_BINDINGS=0
- we’re going to build the bindings so we do not want ninja to do it
"LLVM does not support generating component dylibs and shared libs. It supports generating libLLVM, a single dylib containing all of the LLVM components rolled together. libunwind, libcxx, libcxxabi, are runtime libraries that are designed to allow static linkage, and they don’t link LLVM." (https://reviews.llvm.org/D61804)
So you can link to libLLVM.[so,dylib], or you can statically link to the individual libs like libLLVMBitreader.a, etc. The shared lib is not built by default. To build it:
-
-DLLVM_BUILD_LLVM_DYLIB=ON
- tells the build to producelib/libLLVM.dylib
(or.so
). -
Do not use
-BUILD_SHARED_LIBS