Skip to content

Commit

Permalink
Initial work to add modifiers to Cargo.toml and env variable options
Browse files Browse the repository at this point in the history
  • Loading branch information
deg4uss3r committed Jan 19, 2025
1 parent 38acdbc commit 7d544ff
Show file tree
Hide file tree
Showing 4 changed files with 298 additions and 23 deletions.
117 changes: 105 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,24 @@ impl Dependencies {
// available and let the linking fail if the user is wrong.
let is_static_lib_available = should_be_linked_statically;

let modifiers = if should_be_linked_statically {
let lib_modifier = env
.get(&EnvVariable::new_modifier(Some(name)))
.unwrap_or_default();

// prefer lib specific modifier if it exists, otherwise use the `SYSTEM_DEPS_MODIFIER` instead
if lib_modifier.is_empty() {
env.get(&EnvVariable::Modifiers(None)).unwrap_or_default()
} else {
lib_modifier

Check warning on line 438 in src/lib.rs

View check run for this annotation

Codecov / codecov/patch

src/lib.rs#L438

Added line #L438 was not covered by tests
}
} else {
String::new()
};

lib.libs = split_string(&value)
.into_iter()
.map(|l| InternalLib::new(l, is_static_lib_available))
.map(|l| InternalLib::new(l, is_static_lib_available, modifiers.clone()))
.collect();
}
if let Some(value) = env.get(&EnvVariable::new_lib_framework(name)) {
Expand Down Expand Up @@ -470,6 +485,7 @@ impl Dependencies {
flags.add(BuildFlag::Lib(
l.name.clone(),
lib.statik && l.is_static_available,
lib.modifiers.clone(),
))
});
lib.frameworks
Expand All @@ -493,6 +509,7 @@ impl Dependencies {
EnvVariable::new_build_internal(None),
));
flags.add(BuildFlag::RerunIfEnvChanged(EnvVariable::new_link(None)));
flags.add(BuildFlag::RerunIfEnvChanged(EnvVariable::Modifiers(None)));

for (name, _lib) in self.libs.iter() {
EnvVariable::set_rerun_if_changed_for_all_variants(&mut flags, name);
Expand Down Expand Up @@ -559,6 +576,7 @@ enum EnvVariable {
BuildInternal(Option<String>),
Link(Option<String>),
LinkerArgs(String),
Modifiers(Option<String>),
}

impl EnvVariable {
Expand Down Expand Up @@ -598,6 +616,10 @@ impl EnvVariable {
Self::Link(lib.map(|l| l.to_string()))
}

fn new_modifier(lib: Option<&str>) -> Self {
Self::Modifiers(lib.map(|m| m.to_string()))
}

fn suffix(&self) -> &'static str {
match self {
EnvVariable::Lib(_) => "LIB",
Expand All @@ -609,6 +631,7 @@ impl EnvVariable {
EnvVariable::BuildInternal(_) => "BUILD_INTERNAL",
EnvVariable::Link(_) => "LINK",
EnvVariable::LinkerArgs(_) => "LDFLAGS",
EnvVariable::Modifiers(_) => "MODIFIER",
}
}

Expand All @@ -626,6 +649,7 @@ impl EnvVariable {
add_to_flags(flags, EnvVariable::new_no_pkg_config(name));
add_to_flags(flags, EnvVariable::new_build_internal(Some(name)));
add_to_flags(flags, EnvVariable::new_link(Some(name)));
add_to_flags(flags, EnvVariable::new_modifier(Some(name)));
}
}

Expand All @@ -643,7 +667,12 @@ impl fmt::Display for EnvVariable {
| EnvVariable::Link(Some(lib)) => {
format!("{}_{}", lib.to_shouty_snake_case(), self.suffix())
}
EnvVariable::BuildInternal(None) | EnvVariable::Link(None) => self.suffix().to_string(),
EnvVariable::Modifiers(Some(modifier)) => {
format!("{}_{}", modifier.to_shouty_snake_case(), self.suffix())
}
EnvVariable::BuildInternal(None)
| EnvVariable::Link(None)
| EnvVariable::Modifiers(None) => self.suffix().to_string(),
};
write!(f, "SYSTEM_DEPS_{}", suffix)
}
Expand Down Expand Up @@ -816,6 +845,25 @@ impl Config {
.has_value(&EnvVariable::new_link(Some(name)), "static")
|| self.env.has_value(&EnvVariable::new_link(None), "static");

// does the static linked lib have any modifiers?
let modifiers = if statik {
let lib_modifier = self
.env
.get(&EnvVariable::new_modifier(Some(name)))
.unwrap_or_default();

//prefer the lib modifier if it is specified otherwise use the `SYSTEM_DEPS` catchall
if lib_modifier.is_empty() {
self.env
.get(&EnvVariable::new_modifier(None))
.unwrap_or_default()
} else {
lib_modifier
}
} else {
String::new()
};

let mut library = if self.env.contains(&EnvVariable::new_no_pkg_config(name)) {
Library::from_env_variables(name)
} else if build_internal == BuildInternal::Always {
Expand All @@ -829,7 +877,9 @@ impl Config {
.statik(statik);

match Self::probe_with_fallback(config, lib_name, fallback_lib_names) {
Ok((lib_name, lib)) => Library::from_pkg_config(lib_name, lib),
Ok((lib_name, lib)) => {
Library::from_pkg_config(lib_name, lib, modifiers.clone())
}
Err(e) => {
if build_internal == BuildInternal::Auto {
// Try building the lib internally as a fallback
Expand All @@ -843,9 +893,14 @@ impl Config {
}
}
};

library.statik = statik;

if statik {
// if the library is statically linked add the modifiers from the toml
// or an empty string which will not affect the linking later.
library.modifiers = modifiers;
}

libraries.add(name, library);
}
Ok(libraries)
Expand Down Expand Up @@ -991,13 +1046,16 @@ pub struct InternalLib {
pub name: String,
/// Indicates if a static library is available on the system
pub is_static_available: bool,
/// Optional Modifiers for static linking libraries
pub modifiers: String,
}

impl InternalLib {
fn new(name: String, is_static_available: bool) -> Self {
fn new(name: String, is_static_available: bool, modifiers: String) -> Self {
InternalLib {
name,
is_static_available,
modifiers,
}
}
}
Expand Down Expand Up @@ -1027,10 +1085,12 @@ pub struct Library {
pub version: String,
/// library is statically linked
pub statik: bool,
/// Modifiers for statically linked libraries
pub modifiers: String,
}

impl Library {
fn from_pkg_config(name: &str, l: pkg_config::Library) -> Self {
fn from_pkg_config(name: &str, l: pkg_config::Library, modifiers: String) -> Self {
// taken from: https://github.com/rust-lang/pkg-config-rs/blob/54325785816695df031cef3b26b6a9a203bbc01b/src/lib.rs#L502
let system_roots = if cfg!(target_os = "macos") {
vec![PathBuf::from("/Library"), PathBuf::from("/System")]
Expand Down Expand Up @@ -1073,7 +1133,17 @@ impl Library {
libs: l
.libs
.iter()
.map(|lib| InternalLib::new(lib.to_owned(), is_static_available(lib)))
.map(|lib| {
InternalLib::new(
lib.to_owned(),
is_static_available(lib),
if is_static_available(lib) {
modifiers.clone()
} else {
String::new()
},
)
})
.collect(),
link_paths: l.link_paths,
include_paths: l.include_paths,
Expand All @@ -1083,6 +1153,7 @@ impl Library {
defines: l.defines,
version: l.version,
statik: false,
modifiers: String::new(),
}
}

Expand All @@ -1099,6 +1170,7 @@ impl Library {
defines: HashMap::new(),
version: String::new(),
statik: false,
modifiers: String::new(),
}
}

Expand Down Expand Up @@ -1154,9 +1226,23 @@ impl Library {

env::set_var("PKG_CONFIG_PATH", old.unwrap_or_else(|_| "".into()));

// Get any modifiers for the lib or SYSTEM_DEPS
// does the static linked lib have any modifiers?
let modifiers = {
let lib_modifier =
env::var(EnvVariable::new_modifier(Some(lib)).to_string()).unwrap_or_default();

//prefer the lib modifier if it is specified otherwise use the `SYSTEM_DEPS` catchall
if lib_modifier.is_empty() {
env::var(EnvVariable::new_modifier(None).to_string()).unwrap_or_default()

Check warning on line 1237 in src/lib.rs

View check run for this annotation

Codecov / codecov/patch

src/lib.rs#L1231-L1237

Added lines #L1231 - L1237 were not covered by tests
} else {
lib_modifier

Check warning on line 1239 in src/lib.rs

View check run for this annotation

Codecov / codecov/patch

src/lib.rs#L1239

Added line #L1239 was not covered by tests
}
};

match pkg_lib {
Ok(pkg_lib) => {
let mut lib = Self::from_pkg_config(lib, pkg_lib);
let mut lib = Self::from_pkg_config(lib, pkg_lib, modifiers);

Check warning on line 1245 in src/lib.rs

View check run for this annotation

Codecov / codecov/patch

src/lib.rs#L1245

Added line #L1245 was not covered by tests
lib.statik = true;
Ok(lib)
}
Expand Down Expand Up @@ -1210,7 +1296,7 @@ enum BuildFlag {
Include(String),
SearchNative(String),
SearchFramework(String),
Lib(String, bool), // true if static
Lib(String, bool, String), // lib name, true if static, optional linking modifiers
LibFramework(String),
RerunIfEnvChanged(EnvVariable),
LinkArg(Vec<String>),
Expand All @@ -1222,12 +1308,19 @@ impl fmt::Display for BuildFlag {
BuildFlag::Include(paths) => write!(f, "include={}", paths),
BuildFlag::SearchNative(lib) => write!(f, "rustc-link-search=native={}", lib),
BuildFlag::SearchFramework(lib) => write!(f, "rustc-link-search=framework={}", lib),
BuildFlag::Lib(lib, statik) => {
BuildFlag::Lib(lib, statik, modifiers) => {
let mut link_string = String::from("rustc-link-lib=");
if *statik {
write!(f, "rustc-link-lib=static={}", lib)
if modifiers.is_empty() {
link_string = format!("{link_string}static={lib}");
} else {
link_string = format!("{link_string}static:{modifiers}={lib}");
}
} else {
write!(f, "rustc-link-lib={}", lib)
link_string = format!("{link_string}{lib}");
}

write!(f, "{link_string}")
}
BuildFlag::LibFramework(lib) => write!(f, "rustc-link-lib=framework={}", lib),
BuildFlag::RerunIfEnvChanged(env) => write!(f, "rerun-if-env-changed={}", env),
Expand Down
17 changes: 17 additions & 0 deletions src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub(crate) struct Dependency {
pub(crate) optional: bool,
pub(crate) cfg: Option<cfg_expr::Expression>,
pub(crate) version_overrides: Vec<VersionOverride>,
pub(crate) modifier: Option<String>,
}

impl Dependency {
Expand All @@ -45,6 +46,7 @@ impl Default for Dependency {
optional: false,
cfg: None,
version_overrides: Vec::new(),
modifier: None,
}
}
}
Expand Down Expand Up @@ -137,6 +139,7 @@ pub(crate) struct VersionOverride {
pub(crate) name: Option<String>,
pub(crate) fallback_names: Option<Vec<String>>,
pub(crate) optional: Option<bool>,
pub(crate) modifier: Option<String>,
}

struct VersionOverrideBuilder {
Expand All @@ -145,6 +148,7 @@ struct VersionOverrideBuilder {
full_name: Option<String>,
fallback_names: Option<Vec<String>>,
optional: Option<bool>,
modifier: Option<String>,
}

impl VersionOverrideBuilder {
Expand All @@ -155,6 +159,7 @@ impl VersionOverrideBuilder {
full_name: None,
fallback_names: None,
optional: None,
modifier: None,
}
}

Expand All @@ -169,6 +174,7 @@ impl VersionOverrideBuilder {
name: self.full_name,
fallback_names: self.fallback_names,
optional: self.optional,
modifier: self.modifier,
})
}
}
Expand Down Expand Up @@ -295,6 +301,9 @@ impl MetaData {
("optional", &toml::Value::Boolean(optional)) => {
dep.optional = optional;
}
("modifiers", toml::Value::String(s)) => {
dep.modifier = Some(s.clone());
}
(version_feature, toml::Value::Table(version_settings))
if version_feature.starts_with('v') =>
{
Expand Down Expand Up @@ -482,6 +491,7 @@ mod tests {
name: None,
fallback_names: None,
optional: None,
modifier: None,
}],
..Default::default()
},]
Expand All @@ -506,13 +516,15 @@ mod tests {
name: None,
fallback_names: None,
optional: None,
modifier: None,
},
VersionOverride {
key: "v6".into(),
version: "6".into(),
name: None,
fallback_names: None,
optional: None,
modifier: None,
},
],
..Default::default()
Expand Down Expand Up @@ -567,20 +579,23 @@ mod tests {
name: None,
fallback_names: None,
optional: None,
modifier: None,
},
VersionOverride {
key: "v2".into(),
version: "2.0".into(),
name: None,
fallback_names: Some(vec!["testlib-2.0".into()]),
optional: None,
modifier: None,
},
VersionOverride {
key: "v99".into(),
version: "99.0".into(),
name: None,
fallback_names: Some(vec![]),
optional: None,
modifier: None,
},
],
..Default::default()
Expand Down Expand Up @@ -613,6 +628,7 @@ mod tests {
name: Some("testlib-5.0".into()),
fallback_names: None,
optional: Some(false),
modifier: None,
},],
..Default::default()
},
Expand All @@ -625,6 +641,7 @@ mod tests {
name: None,
fallback_names: None,
optional: Some(true),
modifier: None,
},],
..Default::default()
},
Expand Down
Loading

0 comments on commit 7d544ff

Please sign in to comment.