Skip to content

Commit 3b13e08

Browse files
committed
Support target-specific rustflags
1 parent f712193 commit 3b13e08

5 files changed

Lines changed: 69 additions & 9 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ glob = "0.3"
4545
itertools = "0.14"
4646
implib = "0.4.0"
4747
object = { version = "0.37.1", default-features = false, features = ["std", "read_core", "pe"] }
48+
cargo-platform = "0.3.1"
4849

4950
[features]
5051
default = []

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ rustflags = "-Cpanic=abort"
154154
# Used to disable the generation of additional import library file in platforms
155155
# that have the concept such as Windows
156156
import_library = false
157+
158+
[package.metadata.capi.library.target.'cfg(target_os = "linux")']
159+
# Add target-specific rustflags, the are folded with the main rustflags above
160+
rustflags = "-Clink-arg=-Wl,--version-script=assets/version.map"
157161
```
158162

159163
### Custom data install

src/build.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::HashMap;
22
use std::hash::{DefaultHasher, Hash, Hasher};
33
use std::io::{ErrorKind, Read};
44
use std::path::{Path, PathBuf};
5+
use std::str::FromStr;
56
use std::sync::atomic::{AtomicBool, Ordering};
67
use std::sync::{Arc, Mutex};
78

@@ -14,6 +15,7 @@ use cargo::util::interning::InternedString;
1415
use cargo::{CliResult, GlobalContext};
1516

1617
use anyhow::Context as _;
18+
use cargo_platform::Platform;
1719
use cargo_util::paths::{copy, create_dir_all, open, read, read_bytes, write};
1820
use implib::def::ModuleDef;
1921
use implib::{Flavor, ImportLibrary, MachineType};
@@ -648,17 +650,38 @@ fn load_manifest_capi_config(
648650
});
649651
}
650652

653+
fn make_args(args: &str) -> impl Iterator<Item = String> + use<'_> {
654+
args.split(' ')
655+
.map(str::trim)
656+
.filter(|s| !s.is_empty())
657+
.map(str::to_string)
658+
}
659+
651660
import_library = library
652661
.get("import_library")
653662
.and_then(|v| v.as_bool())
654663
.unwrap_or(true);
664+
655665
if let Some(args) = library.get("rustflags").and_then(|v| v.as_str()) {
666+
rustflags.extend(make_args(args));
667+
}
668+
669+
if let Some(args) = library.get("target").and_then(|v| v.as_table()) {
656670
let args = args
657-
.split(' ')
658-
.map(str::trim)
659-
.filter(|s| !s.is_empty())
660-
.map(str::to_string);
661-
rustflags.extend(args);
671+
.iter()
672+
.filter_map(|(p, v)| {
673+
if Platform::from_str(p)
674+
.ok()
675+
.is_some_and(|p| p.matches(name, &rustc_target.cfg))
676+
{
677+
v.as_str()
678+
} else {
679+
None
680+
}
681+
})
682+
.flat_map(make_args);
683+
684+
rustflags.extend(args)
662685
}
663686
}
664687

src/build_targets.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ mod test {
237237
arch: String::from(""),
238238
os: os.to_string(),
239239
env: String::from(""),
240+
cfg: Vec::new(),
241+
target: None,
240242
};
241243
let file_names =
242244
FileNames::from_target(&target, "ferris", Path::new("/foo/bar"), false);
@@ -261,6 +263,8 @@ mod test {
261263
arch: String::from(""),
262264
os: os.to_string(),
263265
env: String::from(""),
266+
cfg: Vec::new(),
267+
target: None,
264268
};
265269
let file_names =
266270
FileNames::from_target(&target, "ferris", Path::new("/foo/bar"), false);
@@ -284,6 +288,8 @@ mod test {
284288
arch: String::from(""),
285289
os: String::from("windows"),
286290
env: String::from("msvc"),
291+
cfg: Vec::new(),
292+
target: None,
287293
};
288294
let file_names = FileNames::from_target(&target, "ferris", Path::new("/foo/bar"), false);
289295

@@ -305,6 +311,8 @@ mod test {
305311
arch: String::from(""),
306312
os: String::from("windows"),
307313
env: String::from("gnu"),
314+
cfg: Vec::new(),
315+
target: None,
308316
};
309317
let file_names = FileNames::from_target(&target, "ferris", Path::new("/foo/bar"), false);
310318

src/target.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use std::env::consts;
22
use std::path::{Path, PathBuf};
3-
4-
use anyhow::*;
3+
use std::str::FromStr;
54

65
use crate::build::CApiConfig;
6+
use anyhow::*;
7+
use cargo::core::compiler::CompileTarget;
8+
use cargo_platform::Cfg;
79

810
/// Split a target string to its components
911
///
@@ -16,15 +18,18 @@ pub struct Target {
1618
// pub vendor: String,
1719
pub os: String,
1820
pub env: String,
21+
pub target: Option<CompileTarget>,
22+
pub cfg: Vec<Cfg>,
1923
}
2024

2125
impl Target {
22-
pub fn new<T: AsRef<std::ffi::OsStr>>(
26+
pub fn new<T: AsRef<std::ffi::OsStr> + AsRef<str>>(
2327
target: Option<T>,
2428
is_target_overridden: bool,
25-
) -> Result<Self, anyhow::Error> {
29+
) -> Result<Self> {
2630
let rustc = std::env::var("RUSTC").unwrap_or_else(|_| "rustc".into());
2731
let mut cmd = std::process::Command::new(rustc);
32+
let target = target.as_ref();
2833

2934
cmd.arg("--print").arg("cfg");
3035
if let Some(target) = target {
@@ -46,18 +51,37 @@ impl Target {
4651

4752
let s = std::str::from_utf8(&out.stdout).unwrap();
4853

54+
let lines = s.lines();
55+
56+
let cfg = lines
57+
.map(|line| Ok(Cfg::from_str(line)?))
58+
.collect::<Result<Vec<_>>>()
59+
.with_context(|| {
60+
format!(
61+
"failed to parse the cfg from `rustc --print=cfg`, got:\n{}",
62+
s
63+
)
64+
})?;
65+
4966
Ok(Target {
5067
arch: match_re(arch_re, s),
5168
// vendor: match_re(vendor_re, s),
5269
os: match_re(os_re, s),
5370
env: match_re(env_re, s),
5471
is_target_overridden,
72+
target: target.map(|t| CompileTarget::new(t.as_ref())).transpose()?,
73+
cfg,
5574
})
5675
} else {
5776
Err(anyhow!("Cannot run {:?}", cmd))
5877
}
5978
}
6079

80+
/// Produce the target name, if known
81+
pub fn name(&self) -> Option<&str> {
82+
self.target.as_ref().map(|t| t.short_name())
83+
}
84+
6185
/// Build a list of linker arguments
6286
pub fn shared_object_link_args(
6387
&self,

0 commit comments

Comments
 (0)