cc-rs
cc-rs copied to clipboard
Support LIBPATH on Windows
On Windows, the cc crate takes great pains to synthesize a usable environment by replicating MSVC in how it generates an environment. However, the environment is incomplete, and does not allow for building software such as UWP.
One example is tether, which can only be compiled if run under an environment set up by vcvars64.bat.
The only environment variable that is required to get cl.exe working is LIBPATH. If we call std::env::set_var("LIBPATH", r"path-from-vcvars64.bat"); prior to compiling a UWP binary, the build succeeds.
For the tether project, LIBPATH must contain two values prior to building. On my system, Visual Studio is installed in D:\Software, so I must cann:
env::set_var("LIBPATH", r"D:\Software\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\lib\x86\store\references;C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17134.0;");
It would be nice to get the version number and the SDK in order to add the UnionMetadata path, and to get the MSVC platform lib path. It would also be nice to have the LIBPATH variable set automatically.
Sounds reasonable to me to set! Is LIBPATH the same as LIB? Or otherwise what's the value to synthesize to insert here?
I can only speak on Vs2017 (i.e. version 15), but the values that are necessary are defined in winsdk.bat and vcvars.bat.
winsdk.bat:
if EXIST "%WindowsSdkDir%UnionMetadata\%_WinSdkVer_tmp%" (
set "WindowsLibPath=%WindowsSdkDir%UnionMetadata\%_WinSdkVer_tmp%;%WindowsSdkDir%References\%_WinSdkVer_tmp%"
) else (
set "WindowsLibPath=%WindowsSdkDir%UnionMetadata;%WindowsSdkDir%References"
)
This results in environment variables that are slightly different from LIB, but could probably be added in add_sdks():
LIB:
C:\Program Files (x86)\Windows Kits\10\lib\10.0.17134.0\ucrt\x86
C:\Program Files (x86)\Windows Kits\10\lib\10.0.17134.0\um\x86
LIBPATH:
C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17134.0
C:\Program Files (x86)\Windows Kits\10\References\10.0.17134.0
There are three more paths that are included, and these are defined in vcvars.bat:
call :add_to_libpath_optional "%VCToolsInstallDir%lib\x86\store\references" "%__VCVARS_X86_STORE_REF_OVERRIDE%"
%VCToolsInstallDir%lib\x86
%VCToolsInstallDir%ATLMFC\lib\x86
These three can probably be added in get_tool() since they have the same base directory, and you already add %VCToolsInstallDir%ATLMFC\lib\x86 and %VCToolsInstallDir%lib\x86 to LIB. All that would change is that you'd add these to LIBPATH, and also add %VCToolsInstallDir%lib\x86\store\references as well as the two paths listed above.
Sounds plausible to me!
To quote MSDN
LIBPATH, which specifies directories to search for metadata files referenced with #using. See #using for more information on LIBPATH.
I once tried flag("/link").flag("/LIBPATH:C:\to\your\path") and ended up in D8003: missing source filename error. It seems the cl.exe compiler treats options after /link as linker flags. However, I cannot find a way to arrange flag order.
The /LIBPATH linker argument is not the same as the LIBPATH environment variable.
How to work around this issue?
I wrote the vcvars crate. You can get INCLUDE, WindowsLibPath and other environment variables out of it.