""" This file assembles a toolchain for Linux using the Clang Compiler and musl. It currently makes use of musl and not glibc because the pre-compiled libraries from the latter have absolute paths baked in and this makes linking difficult. The pre-compiled musl library does not have this restriction and is much easier to statically link in as a result. As inputs, it takes external URLs from which to download the clang binaries/libraries/includes as well as the musl headers and pre-compiled binaries. Those files are downloaded and put into one folder, with a little bit of re-arrangement so clang can find files (like the C runtime). """ def _download_and_extract_deb(ctx, deb, sha256, prefix, output = ""): """Downloads a debian file and extracts the data into the provided output directory""" # https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#download download_info = ctx.download( url = deb, output = "deb.ar", sha256 = sha256, ) # https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#execute # This uses the extracted llvm-ar that comes with clang. ctx.execute(["bin/llvm-ar", "x", "deb.ar"]) # https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#extract extract_info = ctx.extract( archive = "data.tar.xz", output = output, stripPrefix = prefix, ) # Clean up ctx.delete("deb.ar") ctx.delete("data.tar.xz") ctx.delete("control.tar.xz") def _build_cpp_toolchain_impl(ctx): # Download the clang toolchain (the extraction can take a while) # https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#download download_info = ctx.download_and_extract( url = ctx.attr.clang_url, output = "", stripPrefix = ctx.attr.clang_prefix, sha256 = ctx.attr.clang_sha256, ) # This puts the musl include files in ${PWD}/usr/include/x86_64-linux-musl # and the runtime files and lib.a files in ${PWD}/usr/lib/x86_64-linux-musl _download_and_extract_deb( ctx, ctx.attr.musl_dev_url, ctx.attr.musl_dev_sha256, ".", ) # kjlubick@ cannot figure out how to get clang to look in ${PWD}/usr/lib/x86_64-linux-musl # for the crt1.o files, so we'll move them to ${PWD}/usr/lib/ where clang *is* looking. for file in ["crt1.o", "crtn.o", "Scrt1.o", "crti.o", "rcrt1.o"]: ctx.execute(["cp", "usr/lib/x86_64-linux-musl/" + file, "usr/lib/"]) # Create a BUILD.bazel file that makes all the files in this subfolder # available for use in rules, i.e. in the toolchain declaration. # https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#file ctx.file( "BUILD.bazel", content = """ filegroup( name = "all_files", srcs = glob([ "**", ]), visibility = ["//visibility:public"] ) """, executable = False, ) build_cpp_toolchain = repository_rule( implementation = _build_cpp_toolchain_impl, attrs = { "clang_url": attr.string(mandatory = True), "clang_sha256": attr.string(mandatory = True), "clang_prefix": attr.string(mandatory = True), "musl_dev_url": attr.string(mandatory = True), "musl_dev_sha256": attr.string(mandatory = True), }, doc = "", )