3 # This script bumps the version of LLVM in *all* the different places where
4 # it needs to be defined. Which is quite a few.
8 import packaging
.version
9 from pathlib
import Path
11 from typing
import Optional
15 def process_line(self
, line
: str) -> str:
16 raise NotImplementedError()
18 def process_file(self
, fpath
: Path
, version
: packaging
.version
.Version
) -> None:
19 self
.version
= version
20 self
.major
, self
.minor
, self
.patch
, self
.suffix
= (
26 data
= fpath
.read_text()
29 for line
in data
.splitlines(True):
30 nline
= self
.process_line(line
)
32 # Print the failing line just to inform the user.
34 print(f
"{fpath.name}: {line.strip()} -> {nline.strip()}")
36 new_data
.append(nline
)
38 fpath
.write_text("".join(new_data
), newline
="\n")
40 # Return a string from the version class
41 # optionally include the suffix (-rcX)
44 version
: Optional
[packaging
.version
.Version
] = None,
45 include_suffix
: bool = True,
48 version
= self
.version
50 ver
= f
"{version.major}.{version.minor}.{version.micro}"
51 if include_suffix
and version
.pre
:
52 ver
+= f
"-{version.pre[0]}{version.pre[1]}"
57 class CMakeProcessor(Processor
):
58 def process_line(self
, line
: str) -> str:
61 # LLVM_VERSION_SUFFIX should be set to -rcX or be blank if we are
62 # building a final version.
63 if "set(LLVM_VERSION_SUFFIX" in line
:
66 r
"set\(LLVM_VERSION_SUFFIX(.*)\)",
67 f
"set(LLVM_VERSION_SUFFIX -{self.suffix[0]}{self.suffix[1]})",
72 r
"set\(LLVM_VERSION_SUFFIX(.*)\)", f
"set(LLVM_VERSION_SUFFIX)", line
75 # Check the rest of the LLVM_VERSION_ lines.
76 elif "set(LLVM_VERSION_" in line
:
78 ("MAJOR", self
.major
),
79 ("MINOR", self
.minor
),
80 ("PATCH", self
.patch
),
83 rf
"set\(LLVM_VERSION_{c} (\d+)",
84 rf
"set(LLVM_VERSION_{c} {cver}",
94 class GNIProcessor(Processor
):
95 def process_line(self
, line
: str) -> str:
96 if "llvm_version_" in line
:
98 ("major", self
.major
),
99 ("minor", self
.minor
),
100 ("patch", self
.patch
),
103 rf
"llvm_version_{c} = \d+", f
"llvm_version_{c} = {cver}", line
111 # LIT python file, a simple tuple
112 class LitProcessor(Processor
):
113 def process_line(self
, line
: str) -> str:
114 if "__versioninfo__" in line
:
116 rf
"__versioninfo__(.*)\((\d+), (\d+), (\d+)\)",
117 f
"__versioninfo__\\1({self.major}, {self.minor}, {self.patch})",
124 # Handle libc++ config header
125 class LibCXXProcessor(Processor
):
126 def process_line(self
, line
: str) -> str:
127 # match #define _LIBCPP_VERSION 160000 in a relaxed way
128 match
= re
.match(r
".*\s_LIBCPP_VERSION\s+(\d{6})$", line
)
130 verstr
= f
"{str(self.major).zfill(2)}{str(self.minor).zfill(2)}{str(self.patch).zfill(2)}"
133 rf
"_LIBCPP_VERSION (\d+)",
134 f
"_LIBCPP_VERSION {verstr}",
141 if __name__
== "__main__":
142 parser
= argparse
.ArgumentParser(
143 usage
="Call this script with a version and it will bump the version for you"
145 parser
.add_argument("version", help="Version to bump to, e.g. 15.0.1", default
=None)
146 parser
.add_argument("--rc", default
=None, type=int, help="RC version")
151 help="LLVM source root (/path/llvm-project). Defaults to the llvm-project the script is located in.",
154 args
= parser
.parse_args()
156 verstr
= args
.version
158 verstr
+= f
"-rc{args.rc}"
160 # parse the version string with distutils.
161 # note that -rc will end up as version.pre here
162 # since it's a prerelease
163 version
= packaging
.version
.parse(verstr
)
165 # Find llvm-project root
166 source_root
= Path(__file__
).resolve().parents
[3]
169 source_root
= Path(args
.source_root
).resolve()
173 (source_root
/ "llvm" / "CMakeLists.txt", CMakeProcessor()),
176 "llvm/utils/lit/lit/__init__.py",
181 "llvm/utils/gn/secondary/llvm/version.gni",
185 "libcxx/include/__config",
190 for f
, processor
in files_to_update
:
191 processor
.process_file(source_root
/ Path(f
), version
)