rust: Add system libs used by rust std to staticlib external deps

pull/10714/merge
Xavier Claessens 2 years ago committed by Xavier Claessens
parent 01bb756484
commit c6db870fc7
  1. 3
      mesonbuild/backend/ninjabackend.py
  2. 8
      mesonbuild/build.py
  3. 14
      mesonbuild/compilers/rust.py
  4. 10
      test cases/rust/5 polyglot static/meson.build

@ -2011,6 +2011,9 @@ class NinjaBackend(backends.Backend):
external_deps.extend(d.external_deps)
for e in external_deps:
for a in e.get_link_args():
if a in rustc.native_static_libs:
# Exclude link args that rustc already add by default
continue
if a.endswith(('.dll', '.so', '.dylib')):
dir_, lib = os.path.split(a)
linkdirs.add(dir_)

@ -2005,6 +2005,14 @@ class StaticLibrary(BuildTarget):
if self.rust_crate_type == 'rlib' and any(c in self.name for c in ['-', ' ', '.']):
raise InvalidArguments('Rust crate type "rlib" does not allow spaces, periods or dashes in the library name '
'due to a limitation of rustc. Replace them with underscores, for example')
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.
rustc = self.compilers['rust']
d = dependencies.InternalDependency('undefined', [], [],
rustc.native_static_libs,
[], [], [], [], [], {}, [], [], [])
self.external_deps.append(d)
# By default a static library is named libfoo.a even on Windows because
# MSVC does not have a consistent convention for what static libraries
# are called. The MSVC CRT uses libfoo.lib syntax but nothing else uses

@ -15,6 +15,7 @@ from __future__ import annotations
import subprocess, os.path
import textwrap
import re
import typing as T
from .. import coredata, mlog
@ -66,6 +67,7 @@ class RustCompiler(Compiler):
self.base_options.update({OptionKey(o) for o in ['b_colorout', 'b_ndebug']})
if 'link' in self.linker.id:
self.base_options.add(OptionKey('b_vscrt'))
self.native_static_libs: T.List[str] = []
def needs_static_linker(self) -> bool:
return False
@ -100,6 +102,18 @@ class RustCompiler(Compiler):
pe.wait()
if pe.returncode != 0:
raise EnvironmentException(f'Executables created by Rust compiler {self.name_string()} are not runnable.')
# Get libraries needed to link with a Rust staticlib
cmdlist = self.exelist + ['--crate-type', 'staticlib', '--print', 'native-static-libs', source_name]
p, stdo, stde = Popen_safe(cmdlist, cwd=work_dir)
if p.returncode == 0:
match = re.search('native-static-libs: (.*)$', stde, re.MULTILINE)
if match:
# Exclude some well known libraries that we don't need because they
# are always part of C/C++ linkers. Rustc probably should not print
# them, pkg-config for example never specify them.
# FIXME: https://github.com/rust-lang/rust/issues/55120
exclude = {'-lc', '-lgcc_s', '-lkernel32', '-ladvapi32'}
self.native_static_libs = [i for i in match.group(1).split() if i not in exclude]
def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]:
return ['--dep-info', outfile]

@ -1,18 +1,8 @@
project('static rust and c polyglot executable', 'c', 'rust')
deps = [
meson.get_compiler('c').find_library('dl', required: false),
meson.get_compiler('c').find_library('m', required: false),
dependency('threads'),
]
extra_winlibs = meson.get_compiler('c').get_id() in ['msvc', 'clang-cl'] ? ['userenv.lib', 'ws2_32.lib', 'bcrypt.lib'] : []
r = static_library('stuff', 'stuff.rs', rust_crate_type : 'staticlib')
l = static_library('clib', 'clib.c', link_with : r, install : true)
e = executable('prog', 'prog.c',
dependencies: deps,
link_with : l,
link_args: extra_winlibs,
install : true)
test('polyglottest', e)

Loading…
Cancel
Save