Skip to content

Commit af1d555

Browse files
amysparklu-zero
authored andcommitted
Convert MSVC native-link-libraries output to be pkg-config compliant
Fixes pkg-config files being unusable for tools like Meson.
1 parent f7d8d3c commit af1d555

File tree

1 file changed

+59
-11
lines changed

1 file changed

+59
-11
lines changed

src/build.rs

+59-11
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use anyhow::Context as _;
1616
use cargo_util::paths::{copy, create_dir_all, open, read, read_bytes, write};
1717
use implib::def::ModuleDef;
1818
use implib::{Flavor, ImportLibrary, MachineType};
19+
use itertools::Itertools;
1920
use semver::Version;
2021

2122
use crate::build_targets::BuildTargets;
@@ -998,6 +999,28 @@ fn deprecation_warnings(ws: &Workspace, args: &ArgMatches) -> anyhow::Result<()>
998999
Ok(())
9991000
}
10001001

1002+
fn static_libraries(link_line: &str, rustc_target: &target::Target) -> String {
1003+
link_line
1004+
.trim()
1005+
.split(' ')
1006+
.filter(|s| {
1007+
if rustc_target.env == "msvc" && s.starts_with("/defaultlib") {
1008+
return false;
1009+
}
1010+
!s.is_empty()
1011+
})
1012+
.unique()
1013+
.map(|lib| {
1014+
if rustc_target.env == "msvc" && lib.ends_with(".lib") {
1015+
return format!("-l{}", lib.trim_end_matches(".lib"));
1016+
}
1017+
lib.trim().to_string()
1018+
})
1019+
.filter(|s| !s.is_empty())
1020+
.collect::<Vec<_>>()
1021+
.join(" ")
1022+
}
1023+
10011024
pub fn cbuild(
10021025
ws: &mut Workspace,
10031026
config: &GlobalContext,
@@ -1111,25 +1134,21 @@ pub fn cbuild(
11111134
// if the hash value does not match.
11121135
if new_build && !cpkg.finger_print.is_valid() {
11131136
let name = &cpkg.capi_config.library.name;
1114-
let static_libs = if only_cdylib {
1115-
"".to_string()
1137+
let (pkg_config_static_libs, static_libs) = if only_cdylib {
1138+
(String::new(), String::new())
1139+
} else if let Some(libs) = exec.link_line.lock().unwrap().values().next() {
1140+
(static_libraries(libs, &rustc_target), libs.to_string())
11161141
} else {
1117-
exec.link_line
1118-
.lock()
1119-
.unwrap()
1120-
.values()
1121-
.next()
1122-
.map_or("", |s| s)
1123-
.to_string()
1142+
(String::new(), String::new())
11241143
};
11251144
let capi_config = &cpkg.capi_config;
11261145
let build_targets = &cpkg.build_targets;
11271146

11281147
let mut pc = PkgConfig::from_workspace(name, &cpkg.install_paths, args, capi_config);
11291148
if only_staticlib {
1130-
pc.add_lib(&static_libs);
1149+
pc.add_lib(&pkg_config_static_libs);
11311150
}
1132-
pc.add_lib_private(&static_libs);
1151+
pc.add_lib_private(&pkg_config_static_libs);
11331152

11341153
build_pc_files(ws, &capi_config.pkg_config.filename, &root_output, &pc)?;
11351154

@@ -1184,6 +1203,8 @@ pub fn cbuild(
11841203
}
11851204
}
11861205

1206+
// This can be supplied to Rust, so it must be in
1207+
// linker-native syntax
11871208
cpkg.finger_print.static_libs = static_libs;
11881209
cpkg.finger_print.store()?;
11891210
} else {
@@ -1316,4 +1337,31 @@ mod tests {
13161337
let sover = library.sover();
13171338
assert_eq!(sover, "1.0.0");
13181339
}
1340+
1341+
#[test]
1342+
pub fn test_lib_listing() {
1343+
let libs_osx = "-lSystem -lc -lm";
1344+
let libs_linux = "-lgcc_s -lutil -lrt -lpthread -lm -ldl -lc";
1345+
let libs_msvc = "kernel32.lib advapi32.lib kernel32.lib ntdll.lib userenv.lib ws2_32.lib kernel32.lib ws2_32.lib kernel32.lib msvcrt.lib /defaultlib:msvcrt";
1346+
let libs_mingw = "-lkernel32 -ladvapi32 -lkernel32 -lntdll -luserenv -lws2_32 -lkernel32 -lws2_32 -lkernel32";
1347+
1348+
let target_osx = target::Target::new(Some("x86_64-apple-darwin"), false).unwrap();
1349+
let target_linux = target::Target::new(Some("x86_64-unknown-linux-gnu"), false).unwrap();
1350+
let target_msvc = target::Target::new(Some("x86_64-pc-windows-msvc"), false).unwrap();
1351+
let target_mingw = target::Target::new(Some("x86_64-pc-windows-gnu"), false).unwrap();
1352+
1353+
assert_eq!(static_libraries(&libs_osx, &target_osx), "-lSystem -lc -lm");
1354+
assert_eq!(
1355+
static_libraries(&libs_linux, &target_linux),
1356+
"-lgcc_s -lutil -lrt -lpthread -lm -ldl -lc"
1357+
);
1358+
assert_eq!(
1359+
static_libraries(&libs_msvc, &target_msvc),
1360+
"-lkernel32 -ladvapi32 -lntdll -luserenv -lws2_32 -lmsvcrt"
1361+
);
1362+
assert_eq!(
1363+
static_libraries(&libs_mingw, &target_mingw),
1364+
"-lkernel32 -ladvapi32 -lntdll -luserenv -lws2_32"
1365+
);
1366+
}
13191367
}

0 commit comments

Comments
 (0)