Skip to content

WIP: Initial work to add modifiers to Cargo.toml and env variable options #117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
// 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 @@
flags.add(BuildFlag::Lib(
l.name.clone(),
lib.statik && l.is_static_available,
lib.modifiers.clone(),
))
});
lib.frameworks
Expand All @@ -493,6 +509,7 @@
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 @@
BuildInternal(Option<String>),
Link(Option<String>),
LinkerArgs(String),
Modifiers(Option<String>),
}

impl EnvVariable {
Expand Down Expand Up @@ -598,6 +616,10 @@
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 @@
EnvVariable::BuildInternal(_) => "BUILD_INTERNAL",
EnvVariable::Link(_) => "LINK",
EnvVariable::LinkerArgs(_) => "LDFLAGS",
EnvVariable::Modifiers(_) => "MODIFIER",
}
}

Expand All @@ -626,6 +649,7 @@
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 @@
| 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 @@
.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 @@
.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 @@
}
}
};

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 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 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 @@
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 @@
defines: l.defines,
version: l.version,
statik: false,
modifiers: String::new(),
}
}

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

Expand Down Expand Up @@ -1154,9 +1226,23 @@

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 @@
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 @@
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
Loading