forked from ClangBuiltLinux/tc-build
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathbuild-rust.py
More file actions
executable file
·213 lines (181 loc) · 7.87 KB
/
build-rust.py
File metadata and controls
executable file
·213 lines (181 loc) · 7.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#!/usr/bin/env python3
# pylint: disable=invalid-name
from argparse import ArgumentParser, RawTextHelpFormatter
from pathlib import Path
import textwrap
import time
import tc_build.utils
from tc_build.rust import RustBuilder, RustSourceManager
# This is a known good revision of Rust for building the kernel
GOOD_REVISION = '69b3959afec9b5468d5de15133b199553f6e55d2'
parser = ArgumentParser(formatter_class=RawTextHelpFormatter)
clone_options = parser.add_mutually_exclusive_group()
parser.add_argument(
'--debug',
help=textwrap.dedent('''\
Build a debug compiler and standard library. This enables debug assertions,
debug logging, overflow checks and debug info. The debug assertions and overflow
checks can help catch issues when compiling.
'''),
action='store_true',
)
parser.add_argument(
'-b',
'--build-folder',
help=textwrap.dedent('''\
By default, the script will create a "build/rust" folder in the same folder as this
script and build each requested stage within that containing folder. To change the
location of the containing build folder, pass it to this parameter. This can be either
an absolute or relative path. If it is provided, then a custom LLVM install folder
needs to be provided as well to prevent mistakes.
'''),
type=str,
)
parser.add_argument(
'-c',
'--configure-set-args',
help=textwrap.dedent('''\
Pass the provided values to configure via the '--set' argument.
For example:
--configure-set-args build.foo=false build.bar=true
would pass
--set build.foo=false --set build.bar=true
to configure.
'''),
nargs='+',
)
parser.add_argument(
'-i',
'--install-folder',
help=textwrap.dedent('''\
By default, the script will leave the toolchain in its build folder. To install it
outside the build folder for persistent use, pass the installation location that you
desire to this parameter. This can be either an absolute or relative path.
'''),
type=str,
)
parser.add_argument(
'-l',
'--llvm-install-folder',
help=textwrap.dedent('''\
By default, the script will try to use a built LLVM by './build-llvm.py'. To use
another LLVM installation (perhaps from './build-llvm.py --install-folder'), pass
it to this parameter.
'''),
type=str,
)
parser.add_argument(
'-R',
'--rust-folder',
help=textwrap.dedent('''\
By default, the script will clone the Rust project into the tc-build repo. If you have
another Rust checkout that you would like to work out of, pass it to this parameter.
This can either be an absolute or relative path. Implies '--no-update'. When this
option is supplied, '--ref' and '--use-good-revision' do nothing, as the script does
not manipulate a repository it does not own.
'''),
type=str,
)
parser.add_argument(
'-n',
'--no-update',
help=textwrap.dedent('''\
By default, the script always updates the Rust repo before building. This prevents
that, which can be helpful during something like bisecting or manually managing the
repo to pin it to a particular revision.
'''),
action='store_true',
)
parser.add_argument(
'-r',
'--ref',
help=textwrap.dedent('''\
By default, the script builds the main branch (tip of tree) of Rust. If you would
like to build an older branch, use this parameter. This may be helpful in tracking
down an older bug to properly bisect. This value is just passed along to 'git checkout'
so it can be a branch name, tag name, or hash. This will have no effect if
'--rust-folder' is provided, as the script does not manipulate a repository that it
does not own.
'''),
default='main',
type=str,
)
parser.add_argument(
'--show-build-commands',
help=textwrap.dedent('''\
By default, the script only shows the output of the comands it is running. When this option
is enabled, the invocations of the build tools will be shown to help with reproducing
issues outside of the script.
'''),
action='store_true',
)
clone_options.add_argument(
'--use-good-revision',
help=textwrap.dedent('''\
By default, the script updates Rust to the latest tip of tree revision, which may at times be
broken or not work right. With this option, it will checkout a known good revision of Rust
that builds and works properly. If you use this option often, please remember to update the
script as the known good revision will change. This option may work best with a matching good
revision used to build LLVM by './build-llvm.py'.
'''),
action='store_const',
const=GOOD_REVISION,
dest='ref',
)
parser.add_argument(
'--vendor-string',
help=textwrap.dedent('''\
Add this value to the Rust version string (like "rustc ... (ClangBuiltLinux)"). Useful when
reverting or applying patches on top of upstream Rust to differentiate a toolchain built
with this script from upstream Rust or to distinguish a toolchain built with this script
from the system's Rust. Defaults to ClangBuiltLinux, can be set to an empty string to
override this and have no vendor in the version string.
'''),
type=str,
default='ClangBuiltLinux',
)
args = parser.parse_args()
# Start tracking time that the script takes
script_start = time.time()
# Folder validation
tc_build_folder = Path(__file__).resolve().parent
src_folder = Path(tc_build_folder, 'src')
if args.build_folder:
build_folder = Path(args.build_folder).resolve()
if not args.llvm_install_folder:
raise RuntimeError(
'Build folder customized, but no custom LLVM install folder provided -- this is likely a mistake. Provide both if you want to build in a custom folder?'
)
else:
build_folder = Path(tc_build_folder, 'build/rust')
if args.llvm_install_folder:
llvm_install_folder = Path(args.llvm_install_folder).resolve()
else:
llvm_install_folder = Path(tc_build_folder, 'build/llvm/final')
# Validate and configure Rust source
if args.rust_folder:
if not (rust_folder := Path(args.rust_folder).resolve()).exists():
raise RuntimeError(f"Provided Rust folder ('{args.rust_folder}') does not exist?")
else:
rust_folder = Path(src_folder, 'rust')
rust_source = RustSourceManager(rust_folder)
rust_source.download(args.ref)
if not (args.rust_folder or args.no_update):
rust_source.update(args.ref)
# Build Rust
tc_build.utils.print_header('Building Rust')
# Final build
final = RustBuilder()
final.folders.source = rust_folder
final.folders.build = Path(build_folder, 'final')
final.folders.install = Path(args.install_folder).resolve() if args.install_folder else None
final.llvm_install_folder = llvm_install_folder
if args.configure_set_args:
final.configure_set_args += args.configure_set_args
final.debug = args.debug
final.vendor_string = args.vendor_string
final.show_commands = args.show_build_commands
final.configure()
final.build()
final.show_install_info()
print(f"Script duration: {tc_build.utils.get_duration(script_start)}")