From f72601a89f30b066e9c572d3d81bebe6435deae8 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 8 Jan 2023 20:39:09 +0900 Subject: [PATCH] [Bazel] Use `LLVM_VERSION` from `llvm/CMakeLists.txt` * Generate `//:vars.bzl` from `llvm/CMakeLists.txt` `_extract_cmake_settings()` generates `//:vars.bzl` in `llvm_configure()`. It would be easier to use external commands like sed(1) and python. For portability, I think the parser should run on Starlark. `@llvm-project//:vars.bzl` may be loaded from both WORKSPACE and BUILD. At the moment, `vars.bzl` provides some values as string. - CMAKE_CXX_STANDARD = "17" - LLVM_VERSION_MAJOR = "16" - LLVM_VERSION_MINOR = "0" - LLVM_VERSION_PATCH = "0" - LLVM_VERSION = "16.0.0" - llvm_vars = (dict of these values) `CMAKE_CXX_STANDARD` may be used to configure toolchain. * Use `//vars.bzl` for each BUILD files It would be smarter if the BUILD phase could generate `llvm-config.h`. Since I am afraid of the discussion in D126581, I just remove LLVM_VERSION stuff out of the static `llvm-config.h`. * Eliminate Bazel stuff in 'bump-version.py' Current version of `bump-version.py` tries to substitute CLANG_VERSION. It is the reason why I modify bump-version in this change rather than incoming patch. Differential Revision: https://reviews.llvm.org/D136392 --- llvm/utils/release/bump-version.py | 54 --------------- utils/bazel/configure.bzl | 80 ++++++++++++++++++++++ utils/bazel/llvm-project-overlay/clang/BUILD.bazel | 25 +++++-- utils/bazel/llvm-project-overlay/lld/BUILD.bazel | 7 +- utils/bazel/llvm-project-overlay/llvm/config.bzl | 12 ++++ .../llvm/include/llvm/Config/llvm-config.h | 8 +-- 6 files changed, 121 insertions(+), 65 deletions(-) diff --git a/llvm/utils/release/bump-version.py b/llvm/utils/release/bump-version.py index e508bd1..f064e4e 100755 --- a/llvm/utils/release/bump-version.py +++ b/llvm/utils/release/bump-version.py @@ -88,43 +88,6 @@ class CMakeProcessor(Processor): return nline -# Process the many bazel files. -class BazelProcessor(Processor): - def process_line(self, line: str) -> str: - # This matches the CLANG_VERSION line of clang/Config/config.h - nline = line - if "CLANG_VERSION " in line: - nline = re.sub( - r"#define CLANG_VERSION (.*)'", - f"#define CLANG_VERSION {self.version_str(include_suffix=False)}'", - line, - ) - # Match version strings of LLVM, Clang and LLD overlay headers - elif "LLVM_VERSION_STRING" in line or "CLANG_VERSION_STRING" in line or "LLD_VERSION_STRING" in line: - nline = re.sub( - r"#define (LLVM|CLANG|LLD)_VERSION_STRING ([\\\"]+)[0-9\.rcgit-]+([\\\"]+)", - rf"#define \g<1>_VERSION_STRING \g<2>{self.version_str()}\g<3>", - line, - ) - # Match the split out MAJOR/MINOR/PATCH versions of LLVM and Clang overlay headers - # in LLVM the define is called _PATCH and in clang it's called _PATCHLEVEL - elif "LLVM_VERSION_" in line or "CLANG_VERSION_" in line: - for c, cver in ( - ("(MAJOR)", self.major), - ("(MINOR)", self.minor), - ("(PATCH|PATCHLEVEL)", self.patch), - ): - nline = re.sub( - fr"(LLVM|CLANG)_VERSION_{c} \d+", - rf"\g<1>_VERSION_\g<2> {cver}", - line, - ) - if nline != line: - break - - return nline - - # GN build system class GNIProcessor(Processor): def process_line(self, line: str) -> str: @@ -214,23 +177,6 @@ if __name__ == "__main__": "llvm/utils/gn/secondary/llvm/version.gni", GNIProcessor(), ), - # Bazel build system - ( - "utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/llvm-config.h", - BazelProcessor(), - ), - ( - "utils/bazel/llvm-project-overlay/clang/BUILD.bazel", - BazelProcessor(), - ), - ( - "utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h", - BazelProcessor(), - ), - ( - "utils/bazel/llvm-project-overlay/lld/BUILD.bazel", - BazelProcessor(), - ), ( "libcxx/include/__config", LibCXXProcessor(), diff --git a/utils/bazel/configure.bzl b/utils/bazel/configure.bzl index 0a731a8..b4d2785 100644 --- a/utils/bazel/configure.bzl +++ b/utils/bazel/configure.bzl @@ -71,9 +71,89 @@ def _overlay_directories(repository_ctx): stderr = exec_result.stderr, )) +def _extract_cmake_settings(repository_ctx, llvm_cmake): + # The list to be written to vars.bzl + # `CMAKE_CXX_STANDARD` may be used from WORKSPACE for the toolchain. + c = { + "CMAKE_CXX_STANDARD": None, + "LLVM_VERSION_MAJOR": None, + "LLVM_VERSION_MINOR": None, + "LLVM_VERSION_PATCH": None, + } + + # It would be easier to use external commands like sed(1) and python. + # For portability, the parser should run on Starlark. + llvm_cmake_path = repository_ctx.path(Label("//:" + llvm_cmake)) + for line in repository_ctx.read(llvm_cmake_path).splitlines(): + # Extract "set ( FOO bar ... " + setfoo = line.partition("(") + if setfoo[1] != "(": + continue + if setfoo[0].strip().lower() != "set": + continue + # `kv` is assumed as \s*KEY\s+VAL\s*\).* + # Typical case is like + # LLVM_REQUIRED_CXX_STANDARD 17) + # Possible case -- It should be ignored. + # CMAKE_CXX_STANDARD ${...} CACHE STRING "...") + kv = setfoo[2].strip() + i = kv.find(" ") + if i < 0: + continue + k = kv[:i] + # Prefer LLVM_REQUIRED_CXX_STANDARD instead of CMAKE_CXX_STANDARD + if k == "LLVM_REQUIRED_CXX_STANDARD": + k = "CMAKE_CXX_STANDARD" + c[k] = None + if k not in c: + continue + # Skip if `CMAKE_CXX_STANDARD` is set with + # `LLVM_REQUIRED_CXX_STANDARD`. + # Then `v` will not be desired form, like "${...} CACHE" + if c[k] != None: + continue + # Pick up 1st word as the value. + # Note: It assumes unquoted word. + v = kv[i:].strip().partition(")")[0].partition(" ")[0] + c[k] = v + + # Synthesize `LLVM_VERSION` for convenience. + c["LLVM_VERSION"] = "{}.{}.{}".format( + c["LLVM_VERSION_MAJOR"], + c["LLVM_VERSION_MINOR"], + c["LLVM_VERSION_PATCH"], + ) + + return c + +def _write_dict_to_file(repository_ctx, filepath, header, vars): + # (fci + individual vars) + (fcd + dict items) + (fct) + fci = header + fcd = "\nllvm_vars={\n" + fct = "}\n" + + for k, v in vars.items(): + fci += '{} = "{}"\n'.format(k, v) + fcd += ' "{}": "{}",\n'.format(k, v) + + repository_ctx.file(filepath, content=fci + fcd + fct) + def _llvm_configure_impl(repository_ctx): _overlay_directories(repository_ctx) + llvm_cmake = "llvm/CMakeLists.txt" + vars = _extract_cmake_settings( + repository_ctx, + llvm_cmake, + ) + + _write_dict_to_file( + repository_ctx, + filepath="vars.bzl", + header="# Generated from {}\n\n".format(llvm_cmake), + vars=vars, + ) + # Create a starlark file with the requested LLVM targets. targets = repository_ctx.attr.targets repository_ctx.file( diff --git a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel index 0ec1690..8764739 100644 --- a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel @@ -7,6 +7,14 @@ load("//llvm:tblgen.bzl", "gentbl") load("//llvm:binary_alias.bzl", "binary_alias") load("//llvm:cc_plugin_library.bzl", "cc_plugin_library") +load( + "//:vars.bzl", + "LLVM_VERSION", + "LLVM_VERSION_MAJOR", + "LLVM_VERSION_MINOR", + "LLVM_VERSION_PATCH", +) + package( default_visibility = ["//visibility:public"], features = ["layering_check"], @@ -360,12 +368,17 @@ genrule( name = "basic_version_gen", outs = ["include/clang/Basic/Version.inc"], cmd = ( - "echo '#define CLANG_VERSION 16.0.0' >> $@\n" + - "echo '#define CLANG_VERSION_MAJOR 16' >> $@\n" + - "echo '#define CLANG_VERSION_MAJOR_STRING \"16\"' >> $@\n" + - "echo '#define CLANG_VERSION_MINOR 0' >> $@\n" + - "echo '#define CLANG_VERSION_PATCHLEVEL 0' >> $@\n" + - "echo '#define CLANG_VERSION_STRING \"16.0.0\"' >> $@\n" + "echo '#define CLANG_VERSION {vers}' >> $@\n" + + "echo '#define CLANG_VERSION_MAJOR {major}' >> $@\n" + + "echo '#define CLANG_VERSION_MAJOR_STRING \"{major}\"' >> $@\n" + + "echo '#define CLANG_VERSION_MINOR {minor}' >> $@\n" + + "echo '#define CLANG_VERSION_PATCHLEVEL {patch}' >> $@\n" + + "echo '#define CLANG_VERSION_STRING \"{vers}\"' >> $@\n" + ).format( + vers=LLVM_VERSION, + major=LLVM_VERSION_MAJOR, + minor=LLVM_VERSION_MINOR, + patch=LLVM_VERSION_PATCH, ), ) diff --git a/utils/bazel/llvm-project-overlay/lld/BUILD.bazel b/utils/bazel/llvm-project-overlay/lld/BUILD.bazel index 87041f3..729a33d 100644 --- a/utils/bazel/llvm-project-overlay/lld/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/lld/BUILD.bazel @@ -5,6 +5,11 @@ load("@bazel_skylib//rules:expand_template.bzl", "expand_template") load("//llvm:tblgen.bzl", "gentbl") +load( + "//:vars.bzl", + "LLVM_VERSION", +) + package( default_visibility = ["//visibility:public"], features = ["layering_check"], @@ -16,7 +21,7 @@ licenses(["notice"]) genrule( name = "config_version_gen", outs = ["include/lld/Common/Version.inc"], - cmd = "echo '#define LLD_VERSION_STRING \"16.0.0\"' > $@", + cmd = "echo '#define LLD_VERSION_STRING \"{}\"' > $@".format(LLVM_VERSION), ) genrule( diff --git a/utils/bazel/llvm-project-overlay/llvm/config.bzl b/utils/bazel/llvm-project-overlay/llvm/config.bzl index 5beb3cc..5507f80 100644 --- a/utils/bazel/llvm-project-overlay/llvm/config.bzl +++ b/utils/bazel/llvm-project-overlay/llvm/config.bzl @@ -4,6 +4,14 @@ """Defines variables that use selects to configure LLVM based on platform.""" +load( + "//:vars.bzl", + "LLVM_VERSION", + "LLVM_VERSION_MAJOR", + "LLVM_VERSION_MINOR", + "LLVM_VERSION_PATCH", +) + def native_arch_defines(arch, triple): return [ r'LLVM_NATIVE_ARCH=\"{}\"'.format(arch), @@ -89,6 +97,10 @@ llvm_config_defines = os_defines + select({ "@bazel_tools//src/conditions:linux_s390x": native_arch_defines("SystemZ", "systemz-unknown-linux_gnu"), "//conditions:default": native_arch_defines("X86", "x86_64-unknown-linux-gnu"), }) + [ + "LLVM_VERSION_MAJOR={}".format(LLVM_VERSION_MAJOR), + "LLVM_VERSION_MINOR={}".format(LLVM_VERSION_MINOR), + "LLVM_VERSION_PATCH={}".format(LLVM_VERSION_PATCH), + r'LLVM_VERSION_STRING=\"{}git\"'.format(LLVM_VERSION), # These shouldn't be needed by the C++11 standard, but are for some # platforms (e.g. glibc < 2.18. See # https://sourceware.org/bugzilla/show_bug.cgi?id=15366). These are also diff --git a/utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/llvm-config.h b/utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/llvm-config.h index 60d915e..5240b82 100644 --- a/utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/llvm-config.h +++ b/utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/llvm-config.h @@ -74,16 +74,16 @@ #define LLVM_USE_PERF 0 /* Major version of the LLVM API */ -#define LLVM_VERSION_MAJOR 16 +/* #undef LLVM_VERSION_MAJOR */ /* Minor version of the LLVM API */ -#define LLVM_VERSION_MINOR 0 +/* #undef LLVM_VERSION_MINOR */ /* Patch version of the LLVM API */ -#define LLVM_VERSION_PATCH 0 +/* #undef LLVM_VERSION_PATCH */ /* LLVM version string */ -#define LLVM_VERSION_STRING "16.0.0git" +/* #undef LLVM_VERSION_STRING */ /* Whether LLVM records statistics for use with GetStatistics(), * PrintStatistics() or PrintStatisticsJSON() -- 2.7.4