Skip to content

Commit b5d0cb6

Browse files
committed
add LibraryTypes
1 parent 56656f8 commit b5d0cb6

File tree

2 files changed

+108
-62
lines changed

2 files changed

+108
-62
lines changed

src/build.rs

+87-55
Original file line numberDiff line numberDiff line change
@@ -102,28 +102,27 @@ fn build_pc_files(
102102

103103
fn patch_target(
104104
pkg: &mut Package,
105-
libkinds: &[&str],
105+
library_types: LibraryTypes,
106106
capi_config: &CApiConfig,
107107
) -> anyhow::Result<()> {
108108
use cargo::core::compiler::CrateType;
109109

110110
let manifest = pkg.manifest_mut();
111111
let targets = manifest.targets_mut();
112112

113-
let kinds: Vec<_> = libkinds
114-
.iter()
115-
.map(|&kind| match kind {
116-
"staticlib" => CrateType::Staticlib,
117-
"cdylib" => CrateType::Cdylib,
118-
_ => unreachable!(),
119-
})
120-
.collect();
113+
let mut kinds = Vec::with_capacity(2);
121114

122-
for target in targets.iter_mut() {
123-
if target.is_lib() {
124-
target.set_kind(TargetKind::Lib(kinds.clone()));
125-
target.set_name(&capi_config.library.name);
126-
}
115+
if library_types.staticlib {
116+
kinds.push(CrateType::Staticlib);
117+
}
118+
119+
if library_types.cdylib {
120+
kinds.push(CrateType::Cdylib);
121+
}
122+
123+
for target in targets.iter_mut().filter(|t| t.is_lib()) {
124+
target.set_kind(TargetKind::Lib(kinds.to_vec()));
125+
target.set_name(&capi_config.library.name);
127126
}
128127

129128
Ok(())
@@ -952,7 +951,7 @@ impl CPackage {
952951
fn from_package(
953952
pkg: &mut Package,
954953
args: &ArgMatches,
955-
libkinds: &[&str],
954+
library_types: LibraryTypes,
956955
rustc_target: &target::Target,
957956
root_output: &Path,
958957
) -> anyhow::Result<CPackage> {
@@ -961,16 +960,16 @@ impl CPackage {
961960
let root_path = pkg.root().to_path_buf();
962961
let capi_config = load_manifest_capi_config(pkg, rustc_target)?;
963962

964-
patch_target(pkg, libkinds, &capi_config)?;
963+
patch_target(pkg, library_types, &capi_config)?;
965964

966965
let name = &capi_config.library.name;
967966

968967
let install_paths = InstallPaths::new(name, rustc_target, args, &capi_config);
969-
let build_targets = BuildTargets::new(
968+
let build_targets = BuildTargets::new_help(
970969
name,
971970
rustc_target,
972971
root_output,
973-
libkinds,
972+
library_types,
974973
&capi_config,
975974
args.get_flag("meson"),
976975
)?;
@@ -998,6 +997,54 @@ fn deprecation_warnings(ws: &Workspace, args: &ArgMatches) -> anyhow::Result<()>
998997
Ok(())
999998
}
1000999

1000+
/// What library types to build
1001+
#[derive(Debug, Clone, Copy)]
1002+
pub(crate) struct LibraryTypes {
1003+
pub(crate) staticlib: bool,
1004+
pub(crate) cdylib: bool,
1005+
}
1006+
1007+
impl LibraryTypes {
1008+
fn from_target(target: &target::Target) -> Self {
1009+
Self {
1010+
staticlib: true,
1011+
cdylib: target.os != "none" && target.env != "musl",
1012+
}
1013+
}
1014+
1015+
fn from_config(target: &target::Target, args: &ArgMatches) -> Self {
1016+
match args.get_many::<String>("library-type") {
1017+
Some(library_types) => Self::from_library_types(target, library_types),
1018+
None => Self::from_target(target),
1019+
}
1020+
}
1021+
1022+
pub(crate) fn from_library_types<S: AsRef<str>>(
1023+
target: &target::Target,
1024+
library_types: impl Iterator<Item = S>,
1025+
) -> Self {
1026+
let (mut staticlib, mut cdylib) = (false, false);
1027+
1028+
for library_type in library_types {
1029+
staticlib |= library_type.as_ref() == "staticlib";
1030+
cdylib |= library_type.as_ref() == "cdylib";
1031+
}
1032+
1033+
// in this case, a cdylib cannot be produced
1034+
cdylib &= target.os != "none";
1035+
1036+
Self { staticlib, cdylib }
1037+
}
1038+
1039+
const fn only_staticlib(self) -> bool {
1040+
self.staticlib && !self.cdylib
1041+
}
1042+
1043+
const fn only_cdylib(self) -> bool {
1044+
self.cdylib && !self.staticlib
1045+
}
1046+
}
1047+
10011048
pub fn cbuild(
10021049
ws: &mut Workspace,
10031050
config: &GlobalContext,
@@ -1006,28 +1053,15 @@ pub fn cbuild(
10061053
) -> anyhow::Result<(Vec<CPackage>, CompileOptions)> {
10071054
deprecation_warnings(ws, args)?;
10081055

1009-
let rustc = config.load_global_rustc(Some(ws))?;
1010-
let targets = args.targets()?;
1011-
let (target, is_target_overridden) = match targets.len() {
1012-
0 => (rustc.host.to_string(), false),
1013-
1 => (targets[0].to_string(), true),
1014-
_ => {
1015-
anyhow::bail!("Multiple targets not supported yet");
1016-
}
1056+
let (target, is_target_overridden) = match args.targets()?.as_slice() {
1057+
[] => (config.load_global_rustc(Some(ws))?.host.to_string(), false),
1058+
[target] => (target.to_string(), true),
1059+
[..] => anyhow::bail!("Multiple targets not supported yet"),
10171060
};
10181061

10191062
let rustc_target = target::Target::new(Some(&target), is_target_overridden)?;
10201063

1021-
let default_kind = || match (rustc_target.os.as_str(), rustc_target.env.as_str()) {
1022-
("none", _) | (_, "musl") => vec!["staticlib"],
1023-
_ => vec!["staticlib", "cdylib"],
1024-
};
1025-
1026-
let libkinds = args
1027-
.get_many::<String>("library-type")
1028-
.map_or_else(default_kind, |v| v.map(String::as_str).collect::<Vec<_>>());
1029-
let only_staticlib = !libkinds.contains(&"cdylib");
1030-
let only_cdylib = !libkinds.contains(&"staticlib");
1064+
let library_types = LibraryTypes::from_config(&rustc_target, args);
10311065

10321066
let profile = args.get_profile_name(default_profile, ProfileChecking::Custom)?;
10331067

@@ -1043,10 +1077,7 @@ pub fn cbuild(
10431077
.join(PathBuf::from(target))
10441078
.join(profiles.get_dir_name());
10451079

1046-
let capi_feature = InternedString::new("capi");
1047-
10481080
let mut members = Vec::new();
1049-
10501081
let mut pristine = false;
10511082

10521083
let requested: Vec<_> = compile_opts
@@ -1056,22 +1087,23 @@ pub fn cbuild(
10561087
.map(|p| p.package_id())
10571088
.collect();
10581089

1059-
for m in ws.members_mut().filter(|m| {
1060-
m.library().is_some()
1061-
&& m.summary().features().contains_key(&capi_feature)
1062-
&& requested.contains(&m.package_id())
1063-
}) {
1064-
let cpkg = CPackage::from_package(m, args, &libkinds, &rustc_target, &root_output)?;
1090+
let capi_feature = InternedString::new("capi");
1091+
let is_relevant_package = |package: &Package| {
1092+
package.library().is_some()
1093+
&& package.summary().features().contains_key(&capi_feature)
1094+
&& requested.contains(&package.package_id())
1095+
};
1096+
1097+
for m in ws.members_mut().filter(|p| is_relevant_package(p)) {
1098+
let cpkg = CPackage::from_package(m, args, library_types, &rustc_target, &root_output)?;
10651099

1066-
pristine = pristine || cpkg.finger_print.load_previous().is_err();
1100+
pristine |= cpkg.finger_print.load_previous().is_err();
10671101

10681102
members.push(cpkg);
10691103
}
10701104

1071-
if pristine {
1072-
// If the cache is somehow missing force a full rebuild;
1073-
compile_opts.build_config.force_rebuild = true;
1074-
}
1105+
// If the cache is somehow missing force a full rebuild;
1106+
compile_opts.build_config.force_rebuild |= pristine;
10751107

10761108
let exec = Arc::new(Exec::default());
10771109
let out_dirs = compile_with_exec(
@@ -1111,7 +1143,7 @@ pub fn cbuild(
11111143
// if the hash value does not match.
11121144
if new_build && !cpkg.finger_print.is_valid() {
11131145
let name = &cpkg.capi_config.library.name;
1114-
let static_libs = if only_cdylib {
1146+
let static_libs = if library_types.only_cdylib() {
11151147
"".to_string()
11161148
} else {
11171149
exec.link_line
@@ -1126,14 +1158,14 @@ pub fn cbuild(
11261158
let build_targets = &cpkg.build_targets;
11271159

11281160
let mut pc = PkgConfig::from_workspace(name, &cpkg.install_paths, args, capi_config);
1129-
if only_staticlib {
1161+
if library_types.only_staticlib() {
11301162
pc.add_lib(&static_libs);
11311163
}
11321164
pc.add_lib_private(&static_libs);
11331165

11341166
build_pc_files(ws, &capi_config.pkg_config.filename, &root_output, &pc)?;
11351167

1136-
if !only_staticlib && capi_config.library.import_library {
1168+
if !library_types.only_staticlib() && capi_config.library.import_library {
11371169
let lib_name = name;
11381170
build_def_file(ws, lib_name, &rustc_target, &root_output)?;
11391171
build_implib_file(ws, lib_name, &rustc_target, &root_output)?;
@@ -1155,11 +1187,11 @@ pub fn cbuild(
11551187
}
11561188

11571189
if name.contains('-') {
1158-
let from_build_targets = BuildTargets::new(
1190+
let from_build_targets = BuildTargets::new_help(
11591191
&name.replace('-', "_"),
11601192
&rustc_target,
11611193
&root_output,
1162-
&libkinds,
1194+
library_types,
11631195
capi_config,
11641196
args.get_flag("meson"),
11651197
)?;

src/build_targets.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::ffi::OsString;
22
use std::path::{Path, PathBuf};
33

4-
use crate::build::{CApiConfig, InstallTarget};
4+
use crate::build::{CApiConfig, InstallTarget, LibraryTypes};
55
use crate::install::LibType;
66
use crate::target::Target;
77

@@ -66,6 +66,24 @@ impl BuildTargets {
6666
libkinds: &[&str],
6767
capi_config: &CApiConfig,
6868
use_meson_naming_convention: bool,
69+
) -> anyhow::Result<BuildTargets> {
70+
Self::new_help(
71+
name,
72+
target,
73+
targetdir,
74+
LibraryTypes::from_library_types(target, libkinds.iter()),
75+
capi_config,
76+
use_meson_naming_convention,
77+
)
78+
}
79+
80+
pub(crate) fn new_help(
81+
name: &str,
82+
target: &Target,
83+
targetdir: &Path,
84+
library_types: LibraryTypes,
85+
capi_config: &CApiConfig,
86+
use_meson_naming_convention: bool,
6987
) -> anyhow::Result<BuildTargets> {
7088
let pc = targetdir.join(format!("{}.pc", &capi_config.pkg_config.filename));
7189
let include = if capi_config.header.enabled && capi_config.header.generation {
@@ -82,15 +100,11 @@ impl BuildTargets {
82100
));
83101
};
84102

85-
// Bare metal does not support shared objects
86-
let build_shared_lib = libkinds.contains(&"cdylib") && target.os.as_str() != "none";
87-
let build_static_lib = libkinds.contains(&"staticlib");
88-
89103
Ok(BuildTargets {
90104
pc,
91105
include,
92-
static_lib: build_static_lib.then_some(file_names.static_lib),
93-
shared_lib: build_shared_lib.then_some(file_names.shared_lib),
106+
static_lib: library_types.staticlib.then_some(file_names.static_lib),
107+
shared_lib: library_types.cdylib.then_some(file_names.shared_lib),
94108
impl_lib: file_names.impl_lib,
95109
debug_info: file_names.debug_info,
96110
def: file_names.def,

0 commit comments

Comments
 (0)