1""" 2This file assembles a toolchain for Linux using the Clang Compiler and musl. 3 4It currently makes use of musl and not glibc because the pre-compiled libraries from the latter 5have absolute paths baked in and this makes linking difficult. The pre-compiled musl library 6does not have this restriction and is much easier to statically link in as a result. 7 8As inputs, it takes external URLs from which to download the clang binaries/libraries/includes 9as well as the musl headers and pre-compiled binaries. Those files are downloaded and put 10into one folder, with a little bit of re-arrangement so clang can find files (like the C runtime). 11""" 12 13def _download_and_extract_deb(ctx, deb, sha256, prefix, output = ""): 14 """Downloads a debian file and extracts the data into the provided output directory""" 15 16 # https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#download 17 download_info = ctx.download( 18 url = deb, 19 output = "deb.ar", 20 sha256 = sha256, 21 ) 22 23 # https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#execute 24 # This uses the extracted llvm-ar that comes with clang. 25 ctx.execute(["bin/llvm-ar", "x", "deb.ar"]) 26 27 # https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#extract 28 extract_info = ctx.extract( 29 archive = "data.tar.xz", 30 output = output, 31 stripPrefix = prefix, 32 ) 33 34 # Clean up 35 ctx.delete("deb.ar") 36 ctx.delete("data.tar.xz") 37 ctx.delete("control.tar.xz") 38 39def _build_cpp_toolchain_impl(ctx): 40 # Download the clang toolchain (the extraction can take a while) 41 # https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#download 42 download_info = ctx.download_and_extract( 43 url = ctx.attr.clang_url, 44 output = "", 45 stripPrefix = ctx.attr.clang_prefix, 46 sha256 = ctx.attr.clang_sha256, 47 ) 48 49 # This puts the musl include files in ${PWD}/usr/include/x86_64-linux-musl 50 # and the runtime files and lib.a files in ${PWD}/usr/lib/x86_64-linux-musl 51 _download_and_extract_deb( 52 ctx, 53 ctx.attr.musl_dev_url, 54 ctx.attr.musl_dev_sha256, 55 ".", 56 ) 57 58 # kjlubick@ cannot figure out how to get clang to look in ${PWD}/usr/lib/x86_64-linux-musl 59 # for the crt1.o files, so we'll move them to ${PWD}/usr/lib/ where clang *is* looking. 60 for file in ["crt1.o", "crtn.o", "Scrt1.o", "crti.o", "rcrt1.o"]: 61 ctx.execute(["cp", "usr/lib/x86_64-linux-musl/" + file, "usr/lib/"]) 62 63 # Create a BUILD.bazel file that makes all the files in this subfolder 64 # available for use in rules, i.e. in the toolchain declaration. 65 # https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#file 66 ctx.file( 67 "BUILD.bazel", 68 content = """ 69filegroup( 70 name = "all_files", 71 srcs = glob([ 72 "**", 73 ]), 74 visibility = ["//visibility:public"] 75) 76""", 77 executable = False, 78 ) 79 80build_cpp_toolchain = repository_rule( 81 implementation = _build_cpp_toolchain_impl, 82 attrs = { 83 "clang_url": attr.string(mandatory = True), 84 "clang_sha256": attr.string(mandatory = True), 85 "clang_prefix": attr.string(mandatory = True), 86 "musl_dev_url": attr.string(mandatory = True), 87 "musl_dev_sha256": attr.string(mandatory = True), 88 }, 89 doc = "", 90) 91