aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/backend/ninjabackend.py3
-rw-r--r--mesonbuild/build.py8
-rw-r--r--mesonbuild/compilers/rust.py14
3 files changed, 25 insertions, 0 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 8a3f72c..cd4cfb1 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -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_)
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index fefc28c..5743236 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -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
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index abdc2b3..450f657 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -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]