Skip to content

Commit

Permalink
Convert MSVC native-link-libraries output to be pkg-config compliant
Browse files Browse the repository at this point in the history
Fixes pkg-config files being unusable for tools like Meson.
  • Loading branch information
amyspark committed Sep 12, 2024
1 parent 56656f8 commit f71408e
Showing 1 changed file with 64 additions and 9 deletions.
73 changes: 64 additions & 9 deletions src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use anyhow::Context as _;
use cargo_util::paths::{copy, create_dir_all, open, read, read_bytes, write};
use implib::def::ModuleDef;
use implib::{Flavor, ImportLibrary, MachineType};
use itertools::Itertools;
use semver::Version;

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

fn static_libraries(link_line: &str, rustc_target: &target::Target) -> String {
link_line
.trim()
.split(' ')
.filter(|s| {
if rustc_target.env == "msvc" && s.starts_with("/defaultlib") {
return false;
}
!s.is_empty()
})
.unique()
.map(|lib| {
if rustc_target.env == "msvc" && lib.ends_with(".lib") {
return format!("-l{}", lib.trim_end_matches(".lib"));
}
lib.trim().to_string()
})
.filter(|s| !s.is_empty())
.collect::<Vec<_>>()
.join(" ")
}

pub fn cbuild(
ws: &mut Workspace,
config: &GlobalContext,
Expand Down Expand Up @@ -1112,15 +1135,18 @@ pub fn cbuild(
if new_build && !cpkg.finger_print.is_valid() {
let name = &cpkg.capi_config.library.name;
let static_libs = if only_cdylib {
"".to_string()
String::new()
} else if let Some(libs) = exec.link_line.lock().unwrap().values().next() {
static_libraries(libs, &rustc_target)
} else {
exec.link_line
.lock()
.unwrap()
.values()
.next()
.map_or("", |s| s)
.to_string()
String::new()
};
let capi_static_libs = if only_cdylib {
String::new()
} else if let Some(libs) = exec.link_line.lock().unwrap().values().next() {
libs.to_string()
} else {
String::new()
};
let capi_config = &cpkg.capi_config;
let build_targets = &cpkg.build_targets;
Expand Down Expand Up @@ -1184,7 +1210,9 @@ pub fn cbuild(
}
}

cpkg.finger_print.static_libs = static_libs;
// This can be supplied to Rust, so it must be in
// linker-native syntax
cpkg.finger_print.static_libs = capi_static_libs;
cpkg.finger_print.store()?;
} else {
// It is not a new build, recover the static_libs value from the cache
Expand Down Expand Up @@ -1316,4 +1344,31 @@ mod tests {
let sover = library.sover();
assert_eq!(sover, "1.0.0");
}

#[test]
pub fn test_lib_listing() {
let libs_osx = "-lSystem -lc -lm";
let libs_linux = "-lgcc_s -lutil -lrt -lpthread -lm -ldl -lc";
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";
let libs_mingw = "-lkernel32 -ladvapi32 -lkernel32 -lntdll -luserenv -lws2_32 -lkernel32 -lws2_32 -lkernel32";

let target_osx = target::Target::new(Some("x86_64-apple-darwin"), false).unwrap();
let target_linux = target::Target::new(Some("x86_64-unknown-linux-gnu"), false).unwrap();
let target_msvc = target::Target::new(Some("x86_64-pc-windows-msvc"), false).unwrap();
let target_mingw = target::Target::new(Some("x86_64-pc-windows-gnu"), false).unwrap();

assert_eq!(static_libraries(&libs_osx, &target_osx), "-lSystem -lc -lm");
assert_eq!(
static_libraries(&libs_linux, &target_linux),
"-lgcc_s -lutil -lrt -lpthread -lm -ldl -lc"
);
assert_eq!(
static_libraries(&libs_msvc, &target_msvc),
"-lkernel32 -ladvapi32 -lntdll -luserenv -lws2_32 -lmsvcrt"
);
assert_eq!(
static_libraries(&libs_mingw, &target_mingw),
"-lkernel32 -ladvapi32 -lntdll -luserenv -lws2_32"
);
}
}

0 comments on commit f71408e

Please sign in to comment.