Skip to content

Commit a7f206c

Browse files
committed
cargo: Add support for target specific dependencies
1 parent 8676322 commit a7f206c

File tree

8 files changed

+59
-5
lines changed

8 files changed

+59
-5
lines changed

mesonbuild/cargo/interpreter.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@
2121
import urllib.parse
2222
import typing as T
2323

24-
from . import builder
25-
from . import version
26-
from ..mesonlib import MesonException, Popen_safe
24+
from . import builder, version, cfg
25+
from ..mesonlib import MesonException, Popen_safe, MachineChoice
2726
from .. import coredata, mlog
2827
from ..wrap.wrap import PackageDefinition
2928

@@ -34,6 +33,7 @@
3433
from .. import mparser
3534
from ..environment import Environment
3635
from ..interpreterbase import SubProject
36+
from ..compilers.rust import RustCompiler
3737

3838
# tomllib is present in python 3.11, before that it is a pypi module called tomli,
3939
# we try to import tomllib, then tomli,
@@ -458,10 +458,13 @@ class PackageKey:
458458
class Interpreter:
459459
def __init__(self, env: Environment) -> None:
460460
self.environment = env
461+
self.host_rustc = T.cast('RustCompiler', self.environment.coredata.compilers[MachineChoice.HOST]['rust'])
461462
# Map Cargo.toml's subdir to loaded manifest.
462463
self.manifests: T.Dict[str, Manifest] = {}
463464
# Map of cargo package (name + api) to its state
464465
self.packages: T.Dict[PackageKey, PackageState] = {}
466+
# Rustc's config
467+
self.cfgs = self._get_cfgs()
465468

466469
def interpret(self, subdir: str) -> mparser.CodeBlockNode:
467470
manifest = self._load_manifest(subdir)
@@ -505,6 +508,10 @@ def _fetch_package(self, package_name: str, api: str) -> T.Tuple[PackageState, b
505508
manifest = self._load_manifest(subdir)
506509
pkg = PackageState(manifest)
507510
self.packages[key] = pkg
511+
# Merge target specific dependencies that are enabled
512+
for condition, dependencies in manifest.target.items():
513+
if cfg.eval_cfg(condition, self.cfgs):
514+
manifest.dependencies.update(dependencies)
508515
# Fetch required dependencies recursively.
509516
for depname, dep in manifest.dependencies.items():
510517
if not dep.optional:
@@ -572,6 +579,23 @@ def _enable_feature(self, pkg: PackageState, feature: str) -> None:
572579
else:
573580
self._enable_feature(pkg, f)
574581

582+
def _get_cfgs(self) -> T.Dict[str, str]:
583+
cfgs = self.host_rustc.get_cfgs().copy()
584+
rustflags = self.environment.coredata.get_external_args(MachineChoice.HOST, 'rust')
585+
rustflags_i = iter(rustflags)
586+
for i in rustflags_i:
587+
if i == '--cfg':
588+
cfgs.append(next(rustflags_i))
589+
return dict(self._split_cfg(i) for i in cfgs)
590+
591+
@staticmethod
592+
def _split_cfg(cfg: str) -> T.Tuple[str, str]:
593+
pair = cfg.split('=', maxsplit=1)
594+
value = pair[1] if len(pair) > 1 else ''
595+
if value and value[0] == '"':
596+
value = value[1:-1]
597+
return pair[0], value
598+
575599
def _create_project(self, pkg: PackageState, build: builder.Builder) -> T.List[mparser.BaseNode]:
576600
"""Create the project() function call
577601

mesonbuild/compilers/rust.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,20 @@ def _native_static_libs(self, work_dir: str, source_name: str) -> None:
142142
def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]:
143143
return ['--dep-info', outfile]
144144

145+
@functools.lru_cache(maxsize=None)
145146
def get_sysroot(self) -> str:
146147
cmd = self.get_exelist(ccache=False) + ['--print', 'sysroot']
147148
p, stdo, stde = Popen_safe_logged(cmd)
148149
return stdo.split('\n', maxsplit=1)[0]
149150

150151
@functools.lru_cache(maxsize=None)
151-
def get_crt_static(self) -> bool:
152+
def get_cfgs(self) -> T.List[str]:
152153
cmd = self.get_exelist(ccache=False) + ['--print', 'cfg']
153154
p, stdo, stde = Popen_safe_logged(cmd)
154-
return bool(re.search('^target_feature="crt-static"$', stdo, re.MULTILINE))
155+
return stdo.splitlines()
156+
157+
def get_crt_static(self) -> bool:
158+
return 'target_feature="crt-static"' in self.get_cfgs()
155159

156160
def get_debug_args(self, is_debug: bool) -> T.List[str]:
157161
return clike_debug_args[is_debug]

mesonbuild/interpreter/interpreter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,7 @@ def _do_subproject_cargo(self, subp_name: str, subdir: str,
10461046
mlog.warning('Cargo subproject is an experimental feature and has no backwards compatibility guarantees.',
10471047
once=True, location=self.current_node)
10481048
if self.environment.cargo is None:
1049+
self.add_languages(['rust'], True, MachineChoice.HOST)
10491050
self.environment.cargo = cargo.Interpreter(self.environment)
10501051
with mlog.nested(subp_name):
10511052
ast = self.environment.cargo.interpret(subdir)

test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ features = ["f1"]
2727
[dependencies.libname]
2828
version = "1"
2929

30+
[target."cfg(unix)".dependencies.unixdep]
31+
version = "0.1"
32+
3033
[features]
3134
default = ["f1"]
3235
f1 = ["f2", "f3"]

test cases/rust/22 cargo subproject/subprojects/foo-0-rs/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ extern "C" {
88
#[cfg(feature = "foo")]
99
#[no_mangle]
1010
pub extern "C" fn rust_func() -> i32 {
11+
#[cfg(unix)]
12+
{
13+
extern crate unixdep;
14+
assert!(unixdep::only_on_unix() == 0);
15+
}
1116
assert!(common::common_func() == 0);
1217
assert!(libothername::stuff() == 42);
1318
let v: i32;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[wrap-file]
2+
method = cargo
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "unixdep"
3+
version = "0.1"
4+
edition = "2021"
5+
6+
[lib]
7+
path = "lib.rs"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
pub fn only_on_unix() -> i32 {
2+
0
3+
}
4+
5+
#[cfg(not(unix))]
6+
pub fn broken() -> i32 {
7+
plop
8+
}

0 commit comments

Comments
 (0)