brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · b976f39 Raw
199 lines · plain
1# This file is licensed under the Apache License v2.0 with LLVM Exceptions.2# See https://llvm.org/LICENSE.txt for license information.3# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception4 5"""Helper macros to configure the LLVM overlay project."""6 7# Directory of overlay files relative to WORKSPACE8DEFAULT_OVERLAY_PATH = "llvm-project-overlay"9 10DEFAULT_TARGETS = [11    "AArch64",12    "AMDGPU",13    "ARM",14    "AVR",15    "BPF",16    "Hexagon",17    "Lanai",18    "LoongArch",19    "Mips",20    "MSP430",21    "NVPTX",22    "PowerPC",23    "RISCV",24    "Sparc",25    "SPIRV",26    "SystemZ",27    "VE",28    "WebAssembly",29    "X86",30    "XCore",31]32 33def _overlay_directories(repository_ctx):34    src_path = repository_ctx.path(Label("@llvm-raw//:WORKSPACE")).dirname35    bazel_path = src_path.get_child("utils").get_child("bazel")36    overlay_path = bazel_path.get_child("llvm-project-overlay")37    script_path = bazel_path.get_child("overlay_directories.py")38 39    python_bin = repository_ctx.which("python3")40    if not python_bin:41        # Windows typically just defines "python" as python3. The script itself42        # contains a check to ensure python3.43        python_bin = repository_ctx.which("python")44 45    if not python_bin:46        fail("Failed to find python3 binary")47 48    cmd = [49        python_bin,50        script_path,51        "--src",52        src_path,53        "--overlay",54        overlay_path,55        "--target",56        ".",57    ]58    exec_result = repository_ctx.execute(cmd, timeout = 20)59 60    if exec_result.return_code != 0:61        fail(("Failed to execute overlay script: '{cmd}'\n" +62              "Exited with code {return_code}\n" +63              "stdout:\n{stdout}\n" +64              "stderr:\n{stderr}\n").format(65            cmd = " ".join([str(arg) for arg in cmd]),66            return_code = exec_result.return_code,67            stdout = exec_result.stdout,68            stderr = exec_result.stderr,69        ))70 71def _extract_cmake_settings(repository_ctx, llvm_cmake):72    # The list to be written to vars.bzl73    # `CMAKE_CXX_STANDARD` may be used from WORKSPACE for the toolchain.74    c = {75        "CMAKE_CXX_STANDARD": None,76        "LLVM_VERSION_MAJOR": None,77        "LLVM_VERSION_MINOR": None,78        "LLVM_VERSION_PATCH": None,79        "LLVM_VERSION_SUFFIX": None,80    }81 82    # It would be easier to use external commands like sed(1) and python.83    # For portability, the parser should run on Starlark.84    llvm_cmake_path = repository_ctx.path(Label("//:" + llvm_cmake))85    for line in repository_ctx.read(llvm_cmake_path).splitlines():86        # Extract "set ( FOO bar ... "87        setfoo = line.partition("(")88        if setfoo[1] != "(":89            continue90        if setfoo[0].strip().lower() != "set":91            continue92 93        # `kv` is assumed as \s*KEY\s+VAL\s*\).*94        # Typical case is like95        #   LLVM_REQUIRED_CXX_STANDARD 17)96        # Possible case -- It should be ignored.97        #   CMAKE_CXX_STANDARD ${...} CACHE STRING "...")98        kv = setfoo[2].strip()99        i = kv.find(" ")100        if i < 0:101            continue102        k = kv[:i]103 104        # Prefer LLVM_REQUIRED_CXX_STANDARD instead of CMAKE_CXX_STANDARD105        if k == "LLVM_REQUIRED_CXX_STANDARD":106            k = "CMAKE_CXX_STANDARD"107            c[k] = None108        if k not in c:109            continue110 111        # Skip if `CMAKE_CXX_STANDARD` is set with112        # `LLVM_REQUIRED_CXX_STANDARD`.113        # Then `v` will not be desired form, like "${...} CACHE"114        if c[k] != None:115            continue116 117        # Pick up 1st word as the value.118        # Note: It assumes unquoted word.119        v = kv[i:].strip().partition(")")[0].partition(" ")[0]120        c[k] = v121 122    # Synthesize `LLVM_VERSION` for convenience.123    c["LLVM_VERSION"] = "{}.{}.{}".format(124        c["LLVM_VERSION_MAJOR"],125        c["LLVM_VERSION_MINOR"],126        c["LLVM_VERSION_PATCH"],127    )128 129    c["PACKAGE_VERSION"] = "{}.{}.{}{}".format(130        c["LLVM_VERSION_MAJOR"],131        c["LLVM_VERSION_MINOR"],132        c["LLVM_VERSION_PATCH"],133        c["LLVM_VERSION_SUFFIX"],134    )135 136    return c137 138def _write_dict_to_file(repository_ctx, filepath, header, vars):139    # (fci + individual vars) + (fcd + dict items) + (fct)140    fci = header141    fcd = "\nllvm_vars={\n"142    fct = "}\n"143 144    for k, v in vars.items():145        fci += '{} = "{}"\n'.format(k, v)146        fcd += '    "{}": "{}",\n'.format(k, v)147 148    repository_ctx.file(filepath, content = fci + fcd + fct)149 150def _llvm_configure_impl(repository_ctx):151    _overlay_directories(repository_ctx)152 153    llvm_cmake = "llvm/CMakeLists.txt"154    vars = _extract_cmake_settings(155        repository_ctx,156        llvm_cmake,157    )158 159    # Grab version info and merge it with the other vars160    version = _extract_cmake_settings(161        repository_ctx,162        "cmake/Modules/LLVMVersion.cmake",163    )164    version = {k: v for k, v in version.items() if v != None}165    vars.update(version)166 167    _write_dict_to_file(168        repository_ctx,169        filepath = "vars.bzl",170        header = "# Generated from {}\n\n".format(llvm_cmake),171        vars = vars,172    )173 174    # Create a starlark file with the requested LLVM targets.175    llvm_targets = repository_ctx.attr.targets176    repository_ctx.file(177        "llvm/targets.bzl",178        content = "llvm_targets = " + str(llvm_targets),179        executable = False,180    )181 182    # Create a starlark file with the requested BOLT targets.183    bolt_targets = ["AArch64", "X86", "RISCV"]  # Supported targets.184    bolt_targets = [t for t in llvm_targets if t in bolt_targets]185    repository_ctx.file(186        "bolt/targets.bzl",187        content = "bolt_targets = " + str(bolt_targets),188        executable = False,189    )190 191llvm_configure = repository_rule(192    implementation = _llvm_configure_impl,193    local = True,194    configure = True,195    attrs = {196        "targets": attr.string_list(default = DEFAULT_TARGETS),197    },198)199