compiler,rust: fix sanity check and internal deps for baremetal rust project/target

Sanity check for bare metal rust wasn't working for a while and there is a pending PR (#12175).
To workaround this problem, we used to let sanity check for build machine and manually defined
rustc target.

Commit 18f8aeda8b breaks this workaround as, even without an
exe_wrapper, native_static_libs are appends as internal deps.

This behaviour makes sense for cross compiled rust in a rich environment but not any for
no-std rust. As said in comments, one can't tell if the code is no-std or not because this is
an annotation from sources. From our point of view, it is pretty clear that building a no-std
rust target means that one has to define system='bare metal' and kernel='none' in his cross-file.

According to that, sanity_check for rust compiler is modified to handle kernel == 'none' case
by building a specific no-std rust snippet, with an extra args if rust_ld is ls.bfd (in order
to prevent the linker to link with a potentially non existing startfile for the given target).
'native_static_libs' is also leave empty in that very case.

This commit fix the spurious native static libs for no-std case and allow us to remove
our dirty workaround which by-passed non working sanity check for bare metal rust.

One who wants to use meson for baremetal Rust project only have to define the rust target
in their cross file.
 e.g.
   rust = ['rustc', '--target', '<rustc valid target>']
pull/12899/head^2
Florent Valette 6 months ago committed by Dylan Baker
parent 8eaeff5b1f
commit 1aac6cc1ec
  1. 5
      mesonbuild/build.py
  2. 36
      mesonbuild/compilers/rust.py

@ -2133,6 +2133,11 @@ class StaticLibrary(BuildTarget):
if self.rust_crate_type == 'staticlib':
# FIXME: In the case of no-std we should not add those libraries,
# but we have no way to know currently.
# XXX:
# In the case of no-std, we are likely in a bare metal case
# and thus, machine_info kernel should be set to 'none'.
# In that case, native_static_libs list is empty.
rustc = self.compilers['rust']
d = dependencies.InternalDependency('undefined', [], [],
rustc.native_static_libs,

@ -76,13 +76,33 @@ class RustCompiler(Compiler):
def sanity_check(self, work_dir: str, environment: 'Environment') -> None:
source_name = os.path.join(work_dir, 'sanity.rs')
output_name = os.path.join(work_dir, 'rusttest')
with open(source_name, 'w', encoding='utf-8') as ofile:
ofile.write(textwrap.dedent(
'''fn main() {
}
'''))
cmdlist = self.exelist.copy()
cmdlist = self.exelist + ['-o', output_name, source_name]
with open(source_name, 'w', encoding='utf-8') as ofile:
# If machine kernel is not `none`, try to compile a dummy program.
# If 'none', this is likely a `no-std`(i.e. bare metal) project.
if self.info.kernel != 'none':
ofile.write(textwrap.dedent(
'''fn main() {
}
'''))
else:
# If rustc linker is gcc, add `-nostartfiles`
if 'ld.' in self.linker.id:
cmdlist.extend(['-C', 'link-arg=-nostartfiles'])
ofile.write(textwrap.dedent(
'''#![no_std]
#![no_main]
#[no_mangle]
pub fn _start() {
}
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
'''))
cmdlist.extend(['-o', output_name, source_name])
pc, stdo, stde = Popen_safe_logged(cmdlist, cwd=work_dir)
if pc.returncode != 0:
raise EnvironmentException(f'Rust compiler {self.name_string()} cannot compile programs.')
@ -107,6 +127,10 @@ class RustCompiler(Compiler):
raise EnvironmentException('Rust compiler cannot compile staticlib.')
match = re.search('native-static-libs: (.*)$', stde, re.MULTILINE)
if not match:
if self.info.kernel == 'none':
# no match and kernel == none (i.e. baremetal) is a valid use case.
# return and let native_static_libs list empty
return
raise EnvironmentException('Failed to find native-static-libs in Rust compiler output.')
# Exclude some well known libraries that we don't need because they
# are always part of C/C++ linkers. Rustc probably should not print

Loading…
Cancel
Save