summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/cargo/interpreter.py30
-rw-r--r--mesonbuild/compilers/rust.py8
-rw-r--r--mesonbuild/interpreter/interpreter.py1
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml3
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/foo-0-rs/lib.rs5
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs.wrap2
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs/Cargo.toml7
-rw-r--r--test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs/lib.rs8
8 files changed, 59 insertions, 5 deletions
diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py
index 78bce95d2..a5d703e4e 100644
--- a/mesonbuild/cargo/interpreter.py
+++ b/mesonbuild/cargo/interpreter.py
@@ -20,9 +20,8 @@ import urllib.parse
import itertools
import typing as T
-from . import builder
-from . import version
-from ..mesonlib import MesonException, Popen_safe
+from . import builder, version, cfg
+from ..mesonlib import MesonException, Popen_safe, MachineChoice
from .. import coredata, mlog
from ..wrap.wrap import PackageDefinition
@@ -35,6 +34,7 @@ if T.TYPE_CHECKING:
from .. import mparser
from ..environment import Environment
from ..interpreterbase import SubProject
+ from ..compilers.rust import RustCompiler
# Copied from typeshed. Blarg that they don't expose this
class DataclassInstance(Protocol):
@@ -476,10 +476,13 @@ class PackageKey:
class Interpreter:
def __init__(self, env: Environment) -> None:
self.environment = env
+ self.host_rustc = T.cast('RustCompiler', self.environment.coredata.compilers[MachineChoice.HOST]['rust'])
# Map Cargo.toml's subdir to loaded manifest.
self.manifests: T.Dict[str, Manifest] = {}
# Map of cargo package (name + api) to its state
self.packages: T.Dict[PackageKey, PackageState] = {}
+ # Rustc's config
+ self.cfgs = self._get_cfgs()
def interpret(self, subdir: str) -> mparser.CodeBlockNode:
manifest = self._load_manifest(subdir)
@@ -526,6 +529,10 @@ class Interpreter:
self.environment.wrap_resolver.wraps[meson_depname].type is not None
pkg = PackageState(manifest, downloaded)
self.packages[key] = pkg
+ # Merge target specific dependencies that are enabled
+ for condition, dependencies in manifest.target.items():
+ if cfg.eval_cfg(condition, self.cfgs):
+ manifest.dependencies.update(dependencies)
# Fetch required dependencies recursively.
for depname, dep in manifest.dependencies.items():
if not dep.optional:
@@ -599,6 +606,23 @@ class Interpreter:
else:
self._enable_feature(pkg, f)
+ def _get_cfgs(self) -> T.Dict[str, str]:
+ cfgs = self.host_rustc.get_cfgs().copy()
+ rustflags = self.environment.coredata.get_external_args(MachineChoice.HOST, 'rust')
+ rustflags_i = iter(rustflags)
+ for i in rustflags_i:
+ if i == '--cfg':
+ cfgs.append(next(rustflags_i))
+ return dict(self._split_cfg(i) for i in cfgs)
+
+ @staticmethod
+ def _split_cfg(cfg: str) -> T.Tuple[str, str]:
+ pair = cfg.split('=', maxsplit=1)
+ value = pair[1] if len(pair) > 1 else ''
+ if value and value[0] == '"':
+ value = value[1:-1]
+ return pair[0], value
+
def _create_project(self, pkg: PackageState, build: builder.Builder) -> T.List[mparser.BaseNode]:
"""Create the project() function call
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index e687552be..5ebb09346 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -182,10 +182,14 @@ class RustCompiler(Compiler):
return stdo.split('\n', maxsplit=1)[0]
@functools.lru_cache(maxsize=None)
- def get_crt_static(self) -> bool:
+ def get_cfgs(self) -> T.List[str]:
cmd = self.get_exelist(ccache=False) + ['--print', 'cfg']
p, stdo, stde = Popen_safe_logged(cmd)
- return bool(re.search('^target_feature="crt-static"$', stdo, re.MULTILINE))
+ return stdo.splitlines()
+
+ @functools.lru_cache(maxsize=None)
+ def get_crt_static(self) -> bool:
+ return 'target_feature="crt-static"' in self.get_cfgs()
def get_debug_args(self, is_debug: bool) -> T.List[str]:
return clike_debug_args[is_debug]
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 750e54742..cd3318b45 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -1050,6 +1050,7 @@ class Interpreter(InterpreterBase, HoldableObject):
mlog.warning('Cargo subproject is an experimental feature and has no backwards compatibility guarantees.',
once=True, location=self.current_node)
if self.environment.cargo is None:
+ self.add_languages(['rust'], True, MachineChoice.HOST)
self.environment.cargo = cargo.Interpreter(self.environment)
with mlog.nested(subp_name):
ast = self.environment.cargo.interpret(subdir)
diff --git a/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml
index 8c5351a77..dd8525b54 100644
--- a/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml
+++ b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml
@@ -27,6 +27,9 @@ features = ["f1"]
[dependencies.libname]
version = "1"
+[target."cfg(unix)".dependencies.unixdep]
+version = "0.1"
+
[features]
default = ["f1"]
f1 = ["f2", "f3"]
diff --git a/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/lib.rs b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/lib.rs
index 4497dc4a4..c57981599 100644
--- a/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/lib.rs
+++ b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/lib.rs
@@ -8,6 +8,11 @@ extern "C" {
#[cfg(feature = "foo")]
#[no_mangle]
pub extern "C" fn rust_func() -> i32 {
+ #[cfg(unix)]
+ {
+ extern crate unixdep;
+ assert!(unixdep::only_on_unix() == 0);
+ }
assert!(common::common_func() == 0);
assert!(libothername::stuff() == 42);
let v: i32;
diff --git a/test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs.wrap b/test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs.wrap
new file mode 100644
index 000000000..99686e90e
--- /dev/null
+++ b/test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs.wrap
@@ -0,0 +1,2 @@
+[wrap-file]
+method = cargo
diff --git a/test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs/Cargo.toml b/test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs/Cargo.toml
new file mode 100644
index 000000000..d72fb39be
--- /dev/null
+++ b/test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "unixdep"
+version = "0.1"
+edition = "2021"
+
+[lib]
+path = "lib.rs"
diff --git a/test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs/lib.rs b/test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs/lib.rs
new file mode 100644
index 000000000..a736e8a26
--- /dev/null
+++ b/test cases/rust/22 cargo subproject/subprojects/unixdep-0.1-rs/lib.rs
@@ -0,0 +1,8 @@
+pub fn only_on_unix() -> i32 {
+ 0
+}
+
+#[cfg(not(unix))]
+pub fn broken() -> i32 {
+ plop
+}