| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- # Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- # Exceptions. See /LICENSE for license information.
- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- """Starlark rules to bootstrap Clang (and LLVM).
- These rules are loaded as part of the `WORKSPACE`, and used by
- `clang_configuration.bzl`. The llvm-project submodule is used for the build.
- """
- def _run(
- repository_ctx,
- cmd,
- timeout = 10,
- environment = {},
- quiet = True):
- """Runs the provided `cmd`, checks for failure, and returns the result."""
- exec_result = repository_ctx.execute(
- cmd,
- timeout = timeout,
- environment = environment,
- quiet = quiet,
- )
- if exec_result.return_code != 0:
- fail("Unable to run command successfully: %s" % str(cmd))
- return exec_result
- def _detect_system_clang(repository_ctx):
- """Detects whether a system-provided clang can be used.
- Returns a tuple of (is_clang, environment).
- """
- # If the user provides an explicit `CC` environment variable, use that as
- # the compiler.
- cc = repository_ctx.os.environ.get("CC")
- cxx = repository_ctx.os.environ.get("CXX")
- if cc or cxx:
- version_output = _run(repository_ctx, [cc, "--version"]).stdout
- return "clang" in version_output, {}
- # If we can build our Clang toolchain using a system-installed Clang, try
- # to do so.
- system_clang = repository_ctx.which("clang")
- if system_clang:
- return True, {
- "CC": str(system_clang),
- "CXX": str(system_clang) + "++",
- }
- return False, {}
- def _get_cmake_defines(repository_ctx, is_clang):
- """Returns a long list of cmake defines for the bootstrap."""
- modules_setting = "OFF"
- if is_clang:
- modules_setting = "ON"
- static_link_cxx = "ON"
- unstable_libcxx_abi = "ON"
- if repository_ctx.os.name.lower().startswith("mac os"):
- # macOS doesn't support the static C++ standard library linking. Turn
- # it off here, and disable the unstable libc++ ABI as we will also be
- # unable to use it later on.
- static_link_cxx = "OFF"
- unstable_libcxx_abi = "OFF"
- return [
- "-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra;lld;libcxx;libcxxabi;compiler-rt;libunwind",
- "-DCMAKE_BUILD_TYPE=Release",
- "-DLLVM_ENABLE_ASSERTIONS=OFF",
- "-DLLVM_ENABLE_MODULES=" + modules_setting,
- "-DLLVM_STATIC_LINK_CXX_STDLIB=" + static_link_cxx,
- "-DLLVM_TARGETS_TO_BUILD=AArch64;X86",
- "-DLIBCXX_ABI_UNSTABLE=" + unstable_libcxx_abi,
- "-DLIBCXX_ENABLE_ASSERTIONS=OFF",
- "-DLIBCXXABI_ENABLE_ASSERTIONS=OFF",
- # Disable components of the build that we don't use while building Carbon.
- "-DCLANG_ENABLE_ARCMT=OFF",
- "-DCLANG_INCLUDE_TESTS=OFF",
- "-DCLANG_TOOL_APINOTES_TEST_BUILD=OFF",
- "-DCLANG_TOOL_ARCMT_TEST_BUILD=OFF",
- "-DCLANG_TOOL_CLANG_CHECK_BUILD=OFF",
- "-DCLANG_TOOL_CLANG_DIFF_BUILD=OFF",
- "-DCLANG_TOOL_CLANG_EXTDEF_MAPPING_BUILD=OFF",
- "-DCLANG_TOOL_CLANG_FUZZER_BUILD=OFF",
- "-DCLANG_TOOL_CLANG_IMPORT_TEST_BUILD=OFF",
- "-DCLANG_TOOL_CLANG_OFFLOAD_BUNDLER_BUILD=OFF",
- "-DCLANG_TOOL_CLANG_OFFLOAD_WRAPPER_BUILD=OFF",
- "-DCLANG_TOOL_CLANG_SCAN_DEPS_BUILD=OFF",
- "-DCLANG_TOOL_CLANG_SHLIB_BUILD=OFF",
- "-DCLANG_TOOL_C_ARCMT_TEST_BUILD=OFF",
- "-DCLANG_TOOL_C_INDEX_TEST_BUILD=OFF",
- "-DCLANG_TOOL_DIAGTOOL_BUILD=OFF",
- "-DCLANG_TOOL_LIBCLANG_BUILD=OFF",
- "-DCLANG_TOOL_SCAN_BUILD_BUILD=OFF",
- "-DCLANG_TOOL_SCAN_VIEW_BUILD=OFF",
- "-DLLVM_BUILD_UTILS=OFF",
- "-DLLVM_ENABLE_BINDINGS=OFF",
- "-DLLVM_ENABLE_LIBXML2=OFF",
- "-DLLVM_ENABLE_OCAMLDOC=OFF",
- "-DLLVM_INCLUDE_BENCHMARKS=OFF",
- "-DLLVM_INCLUDE_DOCS=OFF",
- "-DLLVM_INCLUDE_EXAMPLES=OFF",
- "-DLLVM_INCLUDE_GO_TESTS=OFF",
- "-DLLVM_INCLUDE_TESTS=OFF",
- "-DLLVM_INCLUDE_UTILS=OFF",
- "-DLLVM_TOOL_BUGPOINT_BUILD=OFF",
- "-DLLVM_TOOL_BUGPOINT_PASSES_BUILD=OFF",
- "-DLLVM_TOOL_DSYMUTIL_BUILD=OFF",
- "-DLLVM_TOOL_GOLD_BUILD=OFF",
- "-DLLVM_TOOL_LLC_BUILD=OFF",
- "-DLLVM_TOOL_LLI_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_AS_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_BCANALYZER_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_CAT_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_CFI_VERIFY_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_CONFIG_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_CVTRES_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_CXXDUMP_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_CXXFILT_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_CXXMAP_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_C_TEST_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_DIFF_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_DWARFDUMP_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_ELFABI_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_EXEGESIS_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_EXTRACT_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_GO_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_GSYMUTIL_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_IFS_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_ISEL_FUZZER_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_ITANIUM_DEMANGLE_FUZZER_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_JITLINK_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_JITLISTENER_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_LIBTOOL_DARWIN_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_LINK_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_LIPO_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_LTO2_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_LTO_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_MCA_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_MC_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_ML_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_MICROSOFT_DEMANGLE_FUZZER_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_MT_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_OPT_FUZZER_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_PDBUTIL_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_PROFDATA_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_PROFGEN_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_RC_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_READOBJ_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_REDUCE_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_RTDYLD_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_SHLIB_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_SIZE_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_SPECIAL_CASE_LIST_FUZZER_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_SPLIT_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_STRESS_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_STRINGS_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_XRAY_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_YAML_NUMERIC_PARSER_FUZZER_BUILD=OFF",
- "-DLLVM_TOOL_LLVM_YAML_PARSER_FUZZER_BUILD=OFF",
- "-DLLVM_TOOL_LTO_BUILD=OFF",
- "-DLLVM_TOOL_OBJ2YAML_BUILD=OFF",
- "-DLLVM_TOOL_OPT_BUILD=OFF",
- "-DLLVM_TOOL_OPT_VIEWER_BUILD=OFF",
- "-DLLVM_TOOL_REMARKS_SHLIB_BUILD=OFF",
- "-DLLVM_TOOL_SPLIT_FILE_BUILD=OFF",
- "-DLLVM_TOOL_VERIFY_USELISTORDER_BUILD=OFF",
- "-DLLVM_TOOL_YAML2OBJ_BUILD=OFF",
- ]
- def _bootstrap_clang_toolchain_impl(repository_ctx):
- """Returns the path a bootstrapped Clang executable.
- This bootstraps Clang and the rest of the LLVM toolchain from the LLVM
- submodule.
- """
- repository_ctx.report_progress("Configuring Clang toolchain bootstrap...")
- is_clang, environment = _detect_system_clang(repository_ctx)
- cmake = repository_ctx.which("cmake")
- if not cmake:
- fail("`cmake` not found: is it installed?")
- ninja = repository_ctx.which("ninja")
- if not ninja:
- fail("`ninja` not found: is it installed?")
- workspace_dir = repository_ctx.path(repository_ctx.attr._workspace).dirname
- llvm_dir = repository_ctx.path("%s/third_party/llvm-project/llvm" %
- workspace_dir)
- repository_ctx.report_progress(
- "Running CMake for the Clang toolchain build...",
- )
- cmake_args = [cmake, "-G", "Ninja", str(llvm_dir)]
- cmake_args += _get_cmake_defines(repository_ctx, is_clang)
- _run(
- repository_ctx,
- cmake_args,
- timeout = 600,
- environment = environment,
- # This is very slow, so print output as a form of progress.
- quiet = False,
- )
- # Run ninja for the final build.
- repository_ctx.report_progress("Building the Clang toolchain...")
- _run(
- repository_ctx,
- [ninja],
- timeout = 10800,
- # This is very slow, so print output as a form of progress.
- quiet = False,
- )
- # Create an empty BUILD file to mark the package. The files are used without
- # Bazel labels directly pointing at them.
- repository_ctx.file("BUILD", content = "")
- bootstrap_clang_toolchain = repository_rule(
- implementation = _bootstrap_clang_toolchain_impl,
- configure = True,
- attrs = {
- # We use a label pointing at the workspace file to compute the
- # workspace directory.
- "_workspace": attr.label(
- default = Label("//:WORKSPACE"),
- allow_single_file = True,
- ),
- },
- environ = ["CC", "CXX"],
- )
|