rust-lang / cc-rs

Rust library for build scripts to compile C/C++ code into a Rust library
https://docs.rs/cc
Apache License 2.0
1.81k stars 438 forks source link

Support getting Windows SDK from the environment #625

Closed ChrisDenton closed 2 years ago

ChrisDenton commented 2 years ago

One thing that was brought up recently with the Windows CI's update was a desire to stay with a particular version of the Windows SDK even when a newer version is avaliable. Currently cc always gets the latest with no easy way (as far as I'm aware) to override it. Usually this works out fine but not always.

It would be great if it could default to using the environment before falling back to finding the latest. Possibly relevant environment variables (set by vcvarsall.bat or developer powershell):

I don't have the bandwidth to test a fix for this atm, so if anyone else wants to look into it I'd appreciate it.

nico-abram commented 2 years ago

Are you interested in staying on the latest compiler version and changing the SDK it uses (So trying to use the VS 2019 msvc with 2017's SDK for example), if that's even possible, or would changing the used compiler and tools to the other VS installation satisfy your requirements? I think cc-rs just uses whatever SDK the compiler it finds uses by default.

Glancing at the cc-rs code it looks like it only uses 3 pieces of information from vswhere at the moment: https://github.com/alexcrichton/cc-rs/blob/main/src/vs_instances.rs#L15-L42 installation_name, installation_path and installation_version

I think installation_name is only used here https://github.com/alexcrichton/cc-rs/blob/e643cc14c497007a73fbf347d295a15cde6cd70f/src/windows_registry.rs#L254-L270 to determine version name, so really it's 2 pieces of information: The version and the installation_path.

installation_path for my 2019 vswhere is C:\Program Files (x86)\Microsoft Visual Studio\2019\Community . cc-rs seems to just append to that path to find the tools (Which sometimes depends on the tool and the version, see the specific code all over https://github.com/alexcrichton/cc-rs/blob/e643cc14c497007a73fbf347d295a15cde6cd70f/src/windows_registry.rs )

vcvarsall.bat seems to put the equivalent path to "installation_path" from vswhere in the VSINSTALLDIR environment variable. If using an entire VS toolset from the currently configured environment (And not just the SDK) is enough, maybe just adding a check for that env var and using it instead of the output from vswhere.

For the version, vswhere with 2019 for me gives installationVersion: 16.11.32002.261. Aside: This seems weird becuase it is 2019 imagen

I don't see this version string in any environment variables set by vcvarsall. We could maybe do a string contains for 2019/17/etc on the install dir, but I don't know how brittle that is if VS is installed in a non default location (Is that possible?). Here's everything I see in a vcvarsall with 19 and 261 in case anyone else has any ideas: imagen

ChrisDenton commented 2 years ago

Sorry, I should have explained better. The background for this is rust-lang/rust#88796 where, at the time, using the newer Windows SDK 10.0.20348 broke whereas the older 10.0.19041 worked. I thought it would be good for cc-rs to be able to support specifying/overriding the lib version somehow.

Getting the SDK is a separate step to getting the VC install and is implemented in fn add_sdks(). The version is sorted "asciibetically" and only the latest is returned:

nico-abram commented 2 years ago

Thanks for the clarification, sent a pull request.