aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorAdam C. Foltzer <acfoltzer@galois.com>2018-01-11 16:04:40 -0800
committerAdam C. Foltzer <acfoltzer@galois.com>2018-01-29 15:47:05 -0800
commit1d81efb03d5efee5899db01737880b1b3969e1fc (patch)
tree5333fba87ba73d881364934454ebdaaaf98cc7b0 /mesonbuild
parent7eb6a2918080fce37df7e6d25194d46ed98f0f35 (diff)
downloadmeson-1d81efb03d5efee5899db01737880b1b3969e1fc.zip
meson-1d81efb03d5efee5899db01737880b1b3969e1fc.tar.gz
meson-1d81efb03d5efee5899db01737880b1b3969e1fc.tar.bz2
Add cross-compilation support for `rustc`
This patch is largely modeled on the relatively-straightforward code for Fortran cross-compilation, so there might be some intricacies missing.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/backend/ninjabackend.py16
-rw-r--r--mesonbuild/compilers/rust.py15
-rw-r--r--mesonbuild/environment.py29
-rw-r--r--mesonbuild/interpreter.py4
4 files changed, 45 insertions, 19 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 77c7d50..e1f3909 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1291,7 +1291,11 @@ int dummy;
# installations
for rpath_arg in rpath_args:
args += ['-C', 'link-arg=' + rpath_arg + ':' + os.path.join(rustc.get_sysroot(), 'lib')]
- element = NinjaBuildElement(self.all_outputs, target_name, 'rust_COMPILER', relsrc)
+ crstr = ''
+ if target.is_cross:
+ crstr = '_CROSS'
+ compiler_name = 'rust%s_COMPILER' % crstr
+ element = NinjaBuildElement(self.all_outputs, target_name, compiler_name, relsrc)
if len(orderdeps) > 0:
element.add_orderdep(orderdeps)
element.add_item('ARGS', args)
@@ -1579,8 +1583,11 @@ int dummy;
outfile.write(restat)
outfile.write('\n')
- def generate_rust_compile_rules(self, compiler, outfile):
- rule = 'rule %s_COMPILER\n' % compiler.get_language()
+ def generate_rust_compile_rules(self, compiler, outfile, is_cross):
+ crstr = ''
+ if is_cross:
+ crstr = '_CROSS'
+ rule = 'rule %s%s_COMPILER\n' % (compiler.get_language(), crstr)
invoc = ' '.join([ninja_quote(i) for i in compiler.get_exelist()])
command = ' command = %s $ARGS $in\n' % invoc
description = ' description = Compiling Rust source $in.\n'
@@ -1671,8 +1678,7 @@ rule FORTRAN_DEP_HACK
self.generate_vala_compile_rules(compiler, outfile)
return
if langname == 'rust':
- if not is_cross:
- self.generate_rust_compile_rules(compiler, outfile)
+ self.generate_rust_compile_rules(compiler, outfile, is_cross)
return
if langname == 'swift':
if not is_cross:
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index b93289f..d1a05ed 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -19,9 +19,11 @@ from ..mesonlib import EnvironmentException, Popen_safe
from .compilers import Compiler, rust_buildtype_args
class RustCompiler(Compiler):
- def __init__(self, exelist, version):
+ def __init__(self, exelist, version, is_cross, exe_wrapper=None):
self.language = 'rust'
super().__init__(exelist, version)
+ self.is_cross = is_cross
+ self.exe_wrapper = exe_wrapper
self.id = 'rustc'
def needs_static_linker(self):
@@ -41,7 +43,16 @@ class RustCompiler(Compiler):
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('Rust compiler %s can not compile programs.' % self.name_string())
- if subprocess.call(output_name) != 0:
+ if self.is_cross:
+ if self.exe_wrapper is None:
+ # Can't check if the binaries run so we have to assume they do
+ return
+ cmdlist = self.exe_wrapper + [output_name]
+ else:
+ cmdlist = [output_name]
+ pe = subprocess.Popen(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+ pe.wait()
+ if pe.returncode != 0:
raise EnvironmentException('Executables created by Rust compiler %s are not runnable.' % self.name_string())
def get_dependency_gen_args(self, outfile):
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index e5aa43e..0e5dff0 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -278,6 +278,7 @@ class Environment:
self.default_objc = ['cc']
self.default_objcpp = ['c++']
self.default_fortran = ['gfortran', 'g95', 'f95', 'f90', 'f77', 'ifort']
+ self.default_rust = ['rustc']
self.default_static_linker = ['ar']
self.vs_static_linker = ['lib']
self.gcc_static_linker = ['gcc-ar']
@@ -688,16 +689,24 @@ class Environment:
return ValaCompiler(exelist, version)
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
- def detect_rust_compiler(self):
- exelist = ['rustc']
- try:
- p, out = Popen_safe(exelist + ['--version'])[0:2]
- except OSError:
- raise EnvironmentException('Could not execute Rust compiler "%s"' % ' '.join(exelist))
- version = search_version(out)
- if 'rustc' in out:
- return RustCompiler(exelist, version)
- raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
+ def detect_rust_compiler(self, want_cross):
+ popen_exceptions = {}
+ compilers, ccache, is_cross, exe_wrap = self._get_compilers('rust', 'RUSTC', want_cross)
+ for compiler in compilers:
+ if isinstance(compiler, str):
+ compiler = [compiler]
+ try:
+ p, out = Popen_safe(compiler + ['--version'])[0:2]
+ except OSError as e:
+ popen_exceptions[compiler] = e
+ continue
+
+ version = search_version(out)
+
+ if 'rustc' in out:
+ return RustCompiler(compiler, version, is_cross, exe_wrap)
+
+ self._handle_exceptions(popen_exceptions, compilers)
def detect_d_compiler(self, want_cross):
is_cross = False
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index c759892..fb29fe9 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1992,9 +1992,9 @@ to directly access options of other subprojects.''')
if need_cross_compiler:
cross_comp = self.environment.detect_d_compiler(True)
elif lang == 'rust':
- comp = self.environment.detect_rust_compiler()
+ comp = self.environment.detect_rust_compiler(False)
if need_cross_compiler:
- cross_comp = comp # FIXME, not correct.
+ cross_comp = self.environment.detect_rust_compiler(True)
elif lang == 'fortran':
comp = self.environment.detect_fortran_compiler(False)
if need_cross_compiler: