Skip to content

obazl/obazl_llvm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

obazl_llvm

llvm bazel module(s)

Warning
Experimental. Not stable. Only tested on MacOS.

overview

  • 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 and demos/llvm/c/hello. To build them cd to the subdir containing the MODULE.bazel file and run bazel build demo2 and bazel build hello respectively. Or try bazel run (you’ll have to read the code to see how they work).

@llvm

This submodule configures an llvm installation for use by the SDK submodules described below. It also contains an optional llvm/clang toolchain.

MODULE.bazel
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)
  1. llvm_root label of file containing path to llvm installation

  2. Optional. You can use the SDKs this module provides with your local CC toolchain; using the llvm/clang toolchain is opt-in.

.config/llvm/root
/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.

Toolchain

Brand new, may be flaky, but seems to work for the demos

SDKs

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_c_sdk

MODULE.bazel
llvm.llvm_c_sdk()
use_repo(llvm, "llvm_c_sdk")
demos/llvm/c/hello/BUILD.bazel
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)
)
  1. The demos use a utility tool that defines make variables for module names; in this case, "$(@llvm_c_sdk)" expands to external/obazl_llvm~override~llvm~llvm_c_sdk. See repo_paths below for more information.

@llvm_c++_sdk

Not yet implemented

@clang_c_sdk

Integrates libclang.

@clang_c++_sdk

Not yet implemented.

other sdks

There’s no reason all the other sdks supported by llvm could not be accomodated by this modular design.

repo_paths

To enable module name make variables (like "$(@llvm_c_sdk)") you can use cc_config as follows:

MODULE.bazel
bazel_dep(name = "cc_config",    version = "1.0.0")

Then in any build file add the following:

BUILD.bazel
load("@cc_config//:MACROS.bzl", "repo_paths")
repo_paths(
    name = "repo_paths",
    repos = ["@llvm_c_sdk//version"])    (1)
  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"]

building llvm

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 produce lib/libLLVM.dylib (or .so).

  • Do not use -BUILD_SHARED_LIBS

Releases

No releases published

Packages

No packages published