rust: get stdlib arguments for non-rust languages when linking

Otherwise we might not get things like libstdc++, which we need.
pull/11902/head
Dylan Baker 2 years ago
parent 5d16bd5308
commit 772cb92624
  1. 5
      mesonbuild/backend/ninjabackend.py
  2. 31
      mesonbuild/build.py
  3. 18
      test cases/rust/20 rust and cpp/lib.cpp
  4. 8
      test cases/rust/20 rust and cpp/lib.hpp
  5. 19
      test cases/rust/20 rust and cpp/main.rs
  6. 14
      test cases/rust/20 rust and cpp/meson.build

@ -2040,6 +2040,11 @@ class NinjaBackend(backends.Backend):
if d == '':
d = '.'
args += ['-L', d]
# Because of the way rustc links, this must come after any potential
# library need to link with their stdlibs (C++ and Fortran, for example)
args.extend(target.get_used_stdlib_args('rust'))
target_deps = target.get_dependencies()
has_shared_deps = any(isinstance(dep, build.SharedLibrary) for dep in target_deps)
has_rust_shared_deps = any(dep.uses_rust()

@ -698,6 +698,15 @@ class BuildTarget(Target):
install_dir: T.List[T.Union[str, Literal[False]]]
# This set contains all the languages a linker can link natively
# without extra flags. For instance, nvcc (cuda) can link C++
# without injecting -lc++/-lstdc++, see
# https://github.com/mesonbuild/meson/issues/10570
_MASK_LANGS: T.FrozenSet[T.Tuple[str, str]] = frozenset([
# (language, linker)
('cpp', 'cuda'),
])
def __init__(
self,
name: str,
@ -1579,14 +1588,6 @@ You probably should put it in link_with instead.''')
# Languages used by dependencies
dep_langs = self.get_langs_used_by_deps()
# This set contains all the languages a linker can link natively
# without extra flags. For instance, nvcc (cuda) can link C++
# without injecting -lc++/-lstdc++, see
# https://github.com/mesonbuild/meson/issues/10570
MASK_LANGS = frozenset([
# (language, linker)
('cpp', 'cuda'),
])
# Pick a compiler based on the language priority-order
for l in clink_langs:
if l in self.compilers or l in dep_langs:
@ -1597,10 +1598,7 @@ You probably should put it in link_with instead.''')
f'Could not get a dynamic linker for build target {self.name!r}. '
f'Requires a linker for language "{l}", but that is not '
'a project language.')
stdlib_args: T.List[str] = []
for dl in itertools.chain(self.compilers, dep_langs):
if dl != linker.language and (dl, linker.language) not in MASK_LANGS:
stdlib_args += all_compilers[dl].language_stdlib_only_link_flags(self.environment)
stdlib_args: T.List[str] = self.get_used_stdlib_args(linker.language)
# Type of var 'linker' is Compiler.
# Pretty hard to fix because the return value is passed everywhere
return linker, stdlib_args
@ -1616,6 +1614,15 @@ You probably should put it in link_with instead.''')
raise AssertionError(f'Could not get a dynamic linker for build target {self.name!r}')
def get_used_stdlib_args(self, link_language: str) -> T.List[str]:
all_compilers = self.environment.coredata.compilers[self.for_machine]
all_langs = set(all_compilers).union(self.get_langs_used_by_deps())
stdlib_args: T.List[str] = []
for dl in all_langs:
if dl != link_language and (dl, link_language) not in self._MASK_LANGS:
stdlib_args.extend(all_compilers[dl].language_stdlib_only_link_flags(self.environment))
return stdlib_args
def uses_rust(self) -> bool:
return 'rust' in self.compilers

@ -0,0 +1,18 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright © 2023 Intel Corporation
#include "lib.hpp"
#include <string>
namespace {
uint64_t priv_length(const std::string & str) {
return str.length();
}
}
extern "C" uint64_t lib_length(const char * str) {
return priv_length(str);
}

@ -0,0 +1,8 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright © 2023 Intel Corporation
#include <cstddef>
#include <cstdint>
extern "C" uint64_t lib_length(const char * str);

@ -0,0 +1,19 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright © 2023 Intel Corporation
use std::ffi::CString;
use std::os::raw::c_char;
extern "C" {
fn lib_length(s: *const c_char) -> u64;
}
fn main() {
let len: u64;
unsafe {
let c_str = CString::new("Hello, world!").unwrap();
len = lib_length(c_str.as_ptr());
}
std::process::exit(if len == 13 { 0 } else { 1 })
}

@ -0,0 +1,14 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright © 2023 Intel Corporation
project(
'Rust and C++',
'rust', 'cpp',
default_options : ['cpp_std=c++14'],
meson_version : '>= 1.2.0',
)
cpplib = static_library('cpp', 'lib.cpp')
exe = executable('main', 'main.rs', link_with : cpplib)
test('main', exe)
Loading…
Cancel
Save