cc-rs icon indicating copy to clipboard operation
cc-rs copied to clipboard

Support LIBPATH on Windows

Open xobs opened this issue 7 years ago • 8 comments

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.

xobs avatar Jun 13 '18 13:06 xobs

Sounds reasonable to me to set! Is LIBPATH the same as LIB? Or otherwise what's the value to synthesize to insert here?

alexcrichton avatar Jun 28 '18 18:06 alexcrichton

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.

xobs avatar Jul 01 '18 11:07 xobs

Sounds plausible to me!

alexcrichton avatar Jul 02 '18 14:07 alexcrichton

To quote MSDN

LIBPATH, which specifies directories to search for metadata files referenced with #using. See #using for more information on LIBPATH.

retep998 avatar Aug 22 '18 22:08 retep998

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.

jerry73204 avatar Aug 19 '19 08:08 jerry73204

The /LIBPATH linker argument is not the same as the LIBPATH environment variable.

retep998 avatar Aug 19 '19 16:08 retep998

How to work around this issue?

asilvas avatar Sep 25 '20 03:09 asilvas

I wrote the vcvars crate. You can get INCLUDE, WindowsLibPath and other environment variables out of it.

Enyium avatar Jan 31 '23 02:01 Enyium