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:
"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(),
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(
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"],
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,
),
)
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"],
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(
"""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),
"@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
#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()