How to find which crate brings specific external link-time dependency

Hello,

I have a project targeting windows XP (and later). I tried to recompile it after almost a year with latest nightly compiler, upgraded dependencies and couple of code changes (all at once, yes, I know ...).
I started receiving a link-time error about missing synchronization.lib which is understandable as this library is not yet available in Windows SDK 7.1.

The full error output is https://gist.github.com/jsen-/cdafd676eca575e87267ea649b5ecb77
Now I'm trying to find out which crate actually brought this dependency in, so I could work around it somehow.
I tried grepping the project dir but no luck :frowning:

Any idea how the link argument collection works?

Edit: Just found out that ANY crate with proc-macro = true brings this dependency in. I guess this one won't be so easy to fix after all.

1 Like

Some crate somewhere in the rustc dependency tree is enabling the synchapi feature of winapi which causes that dependency on synchronization.lib. Do note that you can use a newer version of the Windows SDK with an older VC++ toolchain, allowing you to still target Windows XP, but with import libraries from newer versions. The Windows SDK is backward compatible in the sense that as long as you don't actually use any symbols only available on newer versions it will still run fine on older Windows.

1 Like

I tried to use a newer SDK (XP target), but running the final binary on my testing server just ended up with a msgbox saying "Not a valid Win32 application".
It's actually an old Win2k3 server and I only managed to produce a working binary with SDK 7.1. On newer systems, however, there was no problem running binaries produced with any SDK.

I guess it will just not be possible for me to use proc_macro crates. I guess I can live with that until the hardware finally dies. I "fixed" it by removing dependency on serde_derive.

But now I'm running into GetFinalPathNameByHandleW not being exported from kernel32.dll. I figured one of my dependencies calls std::fs::canonicalize, but which one ... :question:

Is there a way to generate call graph of specific function?

You can set up your environment such that you use an older linker toolchain and CRT, but with the newer Windows SDK import libraries. Just involves a lot of manual prodding of your environment variables.

As for generating call graphs, there's a couple of methods. The easiest option is probably to wipe your CARGO_HOME\registry\src directory and then do a clean build. The stuff in that directory will then be any crate that your build ended up using and you can do an rg search for suspect functions. The harder option is to use something like IDA to disassemble your binary and that will provide all the detailed call graphs you could want.

1 Like

I'll test this next week.

This seems reasonable and actually revealed the culprit.

I just gave IDA a quick look and one of the screenshots actually shows this capability :slight_smile:. I will give it a try once I'm done with this project.

Thank you for your time. It's been very valuable to me.