зеркало из https://github.com/mozilla/gecko-dev.git
197 строки
7.6 KiB
Python
197 строки
7.6 KiB
Python
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
|
# vim: set filetype=python:
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
option('--disable-rust', help='Don\'t include Rust language sources')
|
|
|
|
@depends('--enable-rust')
|
|
def rust_compiler_names(value):
|
|
if value:
|
|
return ['rustc']
|
|
|
|
@depends('--enable-rust')
|
|
def cargo_binary_names(value):
|
|
if value:
|
|
return ['cargo']
|
|
|
|
rustc = check_prog('RUSTC', rust_compiler_names, allow_missing=True)
|
|
cargo = check_prog('CARGO', cargo_binary_names, allow_missing=True)
|
|
|
|
@depends_if(rustc)
|
|
@checking('rustc version', lambda info: info.version)
|
|
def rustc_info(rustc):
|
|
out = check_cmd_output(rustc, '--version', '--verbose').splitlines()
|
|
info = dict((s.strip() for s in line.split(':', 1)) for line in out[1:])
|
|
return namespace(
|
|
version=Version(info.get('release', '0')),
|
|
commit=info.get('commit-hash', 'unknown'),
|
|
)
|
|
|
|
@depends_if(cargo)
|
|
@checking('cargo support for --frozen')
|
|
@imports('subprocess')
|
|
@imports('os')
|
|
def cargo_supports_frozen(cargo):
|
|
try:
|
|
lines = subprocess.check_output(
|
|
[cargo, 'help', 'build']
|
|
).splitlines()
|
|
supported = any(' --frozen' in l for l in lines)
|
|
if 'MOZ_AUTOMATION' in os.environ and not supported:
|
|
die('cargo in automation must support --frozen')
|
|
return supported
|
|
except subprocess.CalledProcessError as e:
|
|
die('Failed to call cargo: %s', e.message)
|
|
|
|
set_config('MOZ_CARGO_SUPPORTS_FROZEN', cargo_supports_frozen)
|
|
|
|
@depends('--enable-rust', rustc, rustc_info)
|
|
@imports(_from='textwrap', _import='dedent')
|
|
def rust_compiler(value, rustc, rustc_info):
|
|
if value:
|
|
if not rustc:
|
|
die(dedent('''\
|
|
Rust compiler not found.
|
|
To compile rust language sources, you must have 'rustc' in your path.
|
|
See https//www.rust-lang.org/ for more information.
|
|
|
|
You can install rust by running './mach bootstrap'
|
|
or by directly running the installer from https://rustup.rs/
|
|
'''))
|
|
version = rustc_info.version
|
|
min_version = Version('1.13')
|
|
if version < min_version:
|
|
die(dedent('''\
|
|
Rust compiler {} is too old.
|
|
|
|
To compile Rust language sources please install at least
|
|
version {} of the 'rustc' toolchain and make sure it is
|
|
first in your path.
|
|
|
|
You can verify this by typing 'rustc --version'.
|
|
|
|
If you have the 'rustup' tool installed you can upgrade
|
|
to the latest release by typing 'rustup update'. The
|
|
installer is available from https://rustup.rs/
|
|
'''.format(version, min_version)))
|
|
return True
|
|
|
|
set_config('MOZ_RUST', rust_compiler)
|
|
|
|
@template
|
|
def rust_triple_alias(host_or_target):
|
|
"""Template defining the alias used for rustc's --target flag.
|
|
`host_or_target` is either `host` or `target` (the @depends functions
|
|
from init.configure).
|
|
"""
|
|
assert host_or_target in (host, target)
|
|
|
|
@depends(rustc, host_or_target, when=rust_compiler)
|
|
@imports('os')
|
|
@imports('subprocess')
|
|
@imports(_from='mozbuild.configure.util', _import='LineIO')
|
|
@imports(_from='mozbuild.shellutil', _import='quote')
|
|
@imports(_from='tempfile', _import='mkstemp')
|
|
@imports(_from='textwrap', _import='dedent')
|
|
def rust_target(rustc, host_or_target):
|
|
# Rust's --target options are similar to, but not exactly the same
|
|
# as, the autoconf-derived targets we use. An example would be that
|
|
# Rust uses distinct target triples for targetting the GNU C++ ABI
|
|
# and the MSVC C++ ABI on Win32, whereas autoconf has a single
|
|
# triple and relies on the user to ensure that everything is
|
|
# compiled for the appropriate ABI. We need to perform appropriate
|
|
# munging to get the correct option to rustc.
|
|
#
|
|
# The canonical list of targets supported can be derived from:
|
|
#
|
|
# https://github.com/rust-lang/rust/tree/master/mk/cfg
|
|
|
|
# Avoid having to write out os+kernel for all the platforms where
|
|
# they don't differ.
|
|
os_or_kernel = host_or_target.kernel if host_or_target.kernel == 'Linux' and host_or_target.os != 'Android' else host_or_target.os
|
|
rustc_target = {
|
|
# DragonFly
|
|
('x86_64', 'DragonFly'): 'x86_64-unknown-dragonfly',
|
|
# FreeBSD
|
|
('x86', 'FreeBSD'): 'i686-unknown-freebsd',
|
|
('x86_64', 'FreeBSD'): 'x86_64-unknown-freebsd',
|
|
# NetBSD
|
|
('x86_64', 'NetBSD'): 'x86_64-unknown-netbsd',
|
|
# OpenBSD
|
|
('x86_64', 'OpenBSD'): 'x86_64-unknown-openbsd',
|
|
# Linux
|
|
('x86', 'Linux'): 'i686-unknown-linux-gnu',
|
|
# Linux
|
|
('x86_64', 'Linux'): 'x86_64-unknown-linux-gnu',
|
|
# OS X and iOS
|
|
('x86', 'OSX'): 'i686-apple-darwin',
|
|
('x86', 'iOS'): 'i386-apple-ios',
|
|
('x86_64', 'OSX'): 'x86_64-apple-darwin',
|
|
# Android
|
|
('x86', 'Android'): 'i686-linux-android',
|
|
('arm', 'Android'): 'armv7-linux-androideabi',
|
|
# Windows
|
|
# XXX better detection of CXX needed here, to figure out whether
|
|
# we need i686-pc-windows-gnu instead, since mingw32 builds work.
|
|
('x86', 'WINNT'): 'i686-pc-windows-msvc',
|
|
('x86_64', 'WINNT'): 'x86_64-pc-windows-msvc',
|
|
}.get((host_or_target.cpu, os_or_kernel), None)
|
|
|
|
if rustc_target is None:
|
|
die("Don't know how to translate {} for rustc".format(host_or_target.alias))
|
|
|
|
# Check to see whether our rustc has a reasonably functional stdlib
|
|
# for our chosen target.
|
|
target_arg = '--target=' + rustc_target
|
|
in_fd, in_path = mkstemp(prefix='conftest', suffix='.rs')
|
|
out_fd, out_path = mkstemp(prefix='conftest', suffix='.rlib')
|
|
os.close(out_fd)
|
|
try:
|
|
source = 'pub extern fn hello() { println!("Hello world"); }'
|
|
log.debug('Creating `%s` with content:', in_path)
|
|
with LineIO(lambda l: log.debug('| %s', l)) as out:
|
|
out.write(source)
|
|
|
|
os.write(in_fd, source)
|
|
os.close(in_fd)
|
|
|
|
cmd = [
|
|
rustc,
|
|
'--crate-type', 'staticlib',
|
|
target_arg,
|
|
'-o', out_path,
|
|
in_path,
|
|
]
|
|
def failed():
|
|
die(dedent('''\
|
|
Cannot compile for {} with {}
|
|
The target may be unsupported, or you may not have
|
|
a rust std library for that target installed. Try:
|
|
|
|
rustup target add {}
|
|
'''.format(host_or_target.alias, rustc, rustc_target)))
|
|
check_cmd_output(*cmd, onerror=failed)
|
|
if not os.path.exists(out_path) or os.path.getsize(out_path) == 0:
|
|
failed()
|
|
finally:
|
|
os.remove(in_path)
|
|
os.remove(out_path)
|
|
|
|
# This target is usable.
|
|
return rustc_target
|
|
|
|
return rust_target
|
|
|
|
rust_target_triple = rust_triple_alias(target)
|
|
rust_host_triple = rust_triple_alias(host)
|
|
|
|
set_config('RUST_TARGET', rust_target_triple)
|
|
set_config('RUST_HOST_TARGET', rust_host_triple)
|
|
|
|
# Until we remove all the other Rust checks in old-configure.
|
|
add_old_configure_assignment('MOZ_RUST', rust_compiler)
|
|
add_old_configure_assignment('RUSTC', rustc)
|
|
add_old_configure_assignment('RUST_TARGET', rust_target_triple)
|