diff options
-rw-r--r-- | cross/ubuntu-armhf.txt | 1 | ||||
-rw-r--r-- | docs/markdown/snippets/rust-cross.md | 16 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 16 | ||||
-rw-r--r-- | mesonbuild/compilers/rust.py | 15 | ||||
-rw-r--r-- | mesonbuild/environment.py | 29 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 4 |
6 files changed, 62 insertions, 19 deletions
diff --git a/cross/ubuntu-armhf.txt b/cross/ubuntu-armhf.txt index 367eba3..6246ffe 100644 --- a/cross/ubuntu-armhf.txt +++ b/cross/ubuntu-armhf.txt @@ -3,6 +3,7 @@ # when cross compiled binaries can't be run we don't do that c = '/usr/bin/arm-linux-gnueabihf-gcc-7' cpp = '/usr/bin/arm-linux-gnueabihf-g++-7' +rust = ['rustc', '--target', 'arm-unknown-linux-gnueabihf', '-C', 'linker=/usr/bin/arm-linux-gnueabihf-gcc-7'] ar = '/usr/arm-linux-gnueabihf/bin/ar' strip = '/usr/arm-linux-gnueabihf/bin/strip' pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config' diff --git a/docs/markdown/snippets/rust-cross.md b/docs/markdown/snippets/rust-cross.md new file mode 100644 index 0000000..7f18c44 --- /dev/null +++ b/docs/markdown/snippets/rust-cross.md @@ -0,0 +1,16 @@ +## Rust cross-compilation + +Cross-compilation is now supported for Rust targets. Like other +cross-compilers, the Rust binary must be specified in your cross +file. It should specify a `--target` (as installed by `rustup target`) +and a custom linker pointing to your C cross-compiler. For example: + +``` +[binaries] +c = '/usr/bin/arm-linux-gnueabihf-gcc-7' +rust = [ + 'rustc', + '--target', 'arm-unknown-linux-gnueabihf', + '-C', 'linker=/usr/bin/arm-linux-gnueabihf-gcc-7', +] +``` 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: |