Skip to content

Commit 917b0b6

Browse files
committed
Auto merge of #111562 - clubby789:speedup-bootstrap-py, r=jyn514
Improve startup time of bootstrap ~~If the user has a `build/host` symlink set up, we can determine the target triple by reading it rather than invoking rustc. This significantly reduces startup time of bootstrap once any kind of build has been done~~ New approach explained below ``` ➜ hyperfine -p 'git checkout -q master' -N './x.py -h' -r 50 Benchmark 1: ./x.py -h Time (mean ± σ): 140.7 ms ± 2.6 ms [User: 99.9 ms, System: 39.3 ms] Range (min … max): 136.8 ms … 149.6 ms 50 runs ➜ rust git:(master) hyperfine -p 'git checkout -q speedup-bootstrap-py' -N './x.py -h' -r 50 Benchmark 1: ./x.py -h Time (mean ± σ): 95.2 ms ± 1.5 ms [User: 67.7 ms, System: 26.7 ms] Range (min … max): 92.9 ms … 99.6 ms 50 runs ``` Also a small microoptimisation in using string splitting rather than regex when reading toml, which saves a few more milliseconds (2-5 testing locally), but less important. Profiling shows the remaining runtime is around half setting up the Python runtime, and the vast majority of the remaining time is spent in subprocess building and running bootstrap itself, so probably can't be improved much further.
2 parents 1221e43 + 9a86ceb commit 917b0b6

File tree

1 file changed

+44
-49
lines changed

1 file changed

+44
-49
lines changed

src/bootstrap/bootstrap.py

+44-49
Original file line numberDiff line numberDiff line change
@@ -226,16 +226,13 @@ def format_build_time(duration):
226226

227227
def default_build_triple(verbose):
228228
"""Build triple as in LLVM"""
229-
# If the user already has a host build triple with an existing `rustc`
230-
# install, use their preference. This fixes most issues with Windows builds
231-
# being detected as GNU instead of MSVC.
229+
# If we're on Windows and have an existing `rustc` toolchain, use `rustc --version --verbose`
230+
# to find our host target triple. This fixes an issue with Windows builds being detected
231+
# as GNU instead of MSVC.
232+
# Otherwise, detect it via `uname`
232233
default_encoding = sys.getdefaultencoding()
233234

234-
if sys.platform == 'darwin':
235-
if verbose:
236-
print("not using rustc detection as it is unreliable on macOS", file=sys.stderr)
237-
print("falling back to auto-detect", file=sys.stderr)
238-
else:
235+
if platform_is_win32():
239236
try:
240237
version = subprocess.check_output(["rustc", "--version", "--verbose"],
241238
stderr=subprocess.DEVNULL)
@@ -253,19 +250,17 @@ def default_build_triple(verbose):
253250
print("falling back to auto-detect", file=sys.stderr)
254251

255252
required = not platform_is_win32()
256-
ostype = require(["uname", "-s"], exit=required)
257-
cputype = require(['uname', '-m'], exit=required)
253+
uname = require(["uname", "-smp"], exit=required)
258254

259255
# If we do not have `uname`, assume Windows.
260-
if ostype is None or cputype is None:
256+
if uname is None:
261257
return 'x86_64-pc-windows-msvc'
262258

263-
ostype = ostype.decode(default_encoding)
264-
cputype = cputype.decode(default_encoding)
259+
kernel, cputype, processor = uname.decode(default_encoding).split()
265260

266261
# The goal here is to come up with the same triple as LLVM would,
267262
# at least for the subset of platforms we're willing to target.
268-
ostype_mapper = {
263+
kerneltype_mapper = {
269264
'Darwin': 'apple-darwin',
270265
'DragonFly': 'unknown-dragonfly',
271266
'FreeBSD': 'unknown-freebsd',
@@ -275,17 +270,18 @@ def default_build_triple(verbose):
275270
}
276271

277272
# Consider the direct transformation first and then the special cases
278-
if ostype in ostype_mapper:
279-
ostype = ostype_mapper[ostype]
280-
elif ostype == 'Linux':
281-
os_from_sp = subprocess.check_output(
282-
['uname', '-o']).strip().decode(default_encoding)
283-
if os_from_sp == 'Android':
284-
ostype = 'linux-android'
273+
if kernel in kerneltype_mapper:
274+
kernel = kerneltype_mapper[kernel]
275+
elif kernel == 'Linux':
276+
# Apple doesn't support `-o` so this can't be used in the combined
277+
# uname invocation above
278+
ostype = require(["uname", "-o"], exit=required).decode(default_encoding)
279+
if ostype == 'Android':
280+
kernel = 'linux-android'
285281
else:
286-
ostype = 'unknown-linux-gnu'
287-
elif ostype == 'SunOS':
288-
ostype = 'pc-solaris'
282+
kernel = 'unknown-linux-gnu'
283+
elif kernel == 'SunOS':
284+
kernel = 'pc-solaris'
289285
# On Solaris, uname -m will return a machine classification instead
290286
# of a cpu type, so uname -p is recommended instead. However, the
291287
# output from that option is too generic for our purposes (it will
@@ -294,34 +290,34 @@ def default_build_triple(verbose):
294290
cputype = require(['isainfo', '-k']).decode(default_encoding)
295291
# sparc cpus have sun as a target vendor
296292
if 'sparc' in cputype:
297-
ostype = 'sun-solaris'
298-
elif ostype.startswith('MINGW'):
293+
kernel = 'sun-solaris'
294+
elif kernel.startswith('MINGW'):
299295
# msys' `uname` does not print gcc configuration, but prints msys
300296
# configuration. so we cannot believe `uname -m`:
301297
# msys1 is always i686 and msys2 is always x86_64.
302298
# instead, msys defines $MSYSTEM which is MINGW32 on i686 and
303299
# MINGW64 on x86_64.
304-
ostype = 'pc-windows-gnu'
300+
kernel = 'pc-windows-gnu'
305301
cputype = 'i686'
306302
if os.environ.get('MSYSTEM') == 'MINGW64':
307303
cputype = 'x86_64'
308-
elif ostype.startswith('MSYS'):
309-
ostype = 'pc-windows-gnu'
310-
elif ostype.startswith('CYGWIN_NT'):
304+
elif kernel.startswith('MSYS'):
305+
kernel = 'pc-windows-gnu'
306+
elif kernel.startswith('CYGWIN_NT'):
311307
cputype = 'i686'
312-
if ostype.endswith('WOW64'):
308+
if kernel.endswith('WOW64'):
313309
cputype = 'x86_64'
314-
ostype = 'pc-windows-gnu'
315-
elif sys.platform == 'win32':
310+
kernel = 'pc-windows-gnu'
311+
elif platform_is_win32():
316312
# Some Windows platforms might have a `uname` command that returns a
317313
# non-standard string (e.g. gnuwin32 tools returns `windows32`). In
318314
# these cases, fall back to using sys.platform.
319315
return 'x86_64-pc-windows-msvc'
320316
else:
321-
err = "unknown OS type: {}".format(ostype)
317+
err = "unknown OS type: {}".format(kernel)
322318
sys.exit(err)
323319

324-
if cputype in ['powerpc', 'riscv'] and ostype == 'unknown-freebsd':
320+
if cputype in ['powerpc', 'riscv'] and kernel == 'unknown-freebsd':
325321
cputype = subprocess.check_output(
326322
['uname', '-p']).strip().decode(default_encoding)
327323
cputype_mapper = {
@@ -354,24 +350,23 @@ def default_build_triple(verbose):
354350
cputype = cputype_mapper[cputype]
355351
elif cputype in {'xscale', 'arm'}:
356352
cputype = 'arm'
357-
if ostype == 'linux-android':
358-
ostype = 'linux-androideabi'
359-
elif ostype == 'unknown-freebsd':
360-
cputype = subprocess.check_output(
361-
['uname', '-p']).strip().decode(default_encoding)
362-
ostype = 'unknown-freebsd'
353+
if kernel == 'linux-android':
354+
kernel = 'linux-androideabi'
355+
elif kernel == 'unknown-freebsd':
356+
cputype = processor
357+
kernel = 'unknown-freebsd'
363358
elif cputype == 'armv6l':
364359
cputype = 'arm'
365-
if ostype == 'linux-android':
366-
ostype = 'linux-androideabi'
360+
if kernel == 'linux-android':
361+
kernel = 'linux-androideabi'
367362
else:
368-
ostype += 'eabihf'
363+
kernel += 'eabihf'
369364
elif cputype in {'armv7l', 'armv8l'}:
370365
cputype = 'armv7'
371-
if ostype == 'linux-android':
372-
ostype = 'linux-androideabi'
366+
if kernel == 'linux-android':
367+
kernel = 'linux-androideabi'
373368
else:
374-
ostype += 'eabihf'
369+
kernel += 'eabihf'
375370
elif cputype == 'mips':
376371
if sys.byteorder == 'big':
377372
cputype = 'mips'
@@ -387,14 +382,14 @@ def default_build_triple(verbose):
387382
else:
388383
raise ValueError('unknown byteorder: {}'.format(sys.byteorder))
389384
# only the n64 ABI is supported, indicate it
390-
ostype += 'abi64'
385+
kernel += 'abi64'
391386
elif cputype == 'sparc' or cputype == 'sparcv9' or cputype == 'sparc64':
392387
pass
393388
else:
394389
err = "unknown cpu type: {}".format(cputype)
395390
sys.exit(err)
396391

397-
return "{}-{}".format(cputype, ostype)
392+
return "{}-{}".format(cputype, kernel)
398393

399394

400395
@contextlib.contextmanager

0 commit comments

Comments
 (0)