7

With Visual Studio 2015 I am no longer able to compile and link a simple C++ program using the command line tools.

Consider main.cpp:

#include <stdlib.h>
int main() { return 0; }

In previous releases (for example Visual Studio 2012) I was able to compile and link main.cpp easily:

C:\Users\bkircher\src\test>cl main.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.61030 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
Microsoft (R) Incremental Linker Version 11.00.61030.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:main.exe
main.obj

And done.

With Visual Studio 2015 however, I no longer have proper CRT include and library paths set:

C:\Users\bkircher\src\test>cl main.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23026 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
main.cpp(1): fatal error C1083: Cannot open include file: 'stdlib.h': No such file or directory

I understand that Microsoft distributes the C runtime as a new Windows operating system component, the Universal CRT.

As described in Introducing the Universal CRT, I should use following MSBuild properties to find the appropriate paths

$(UniversalCRT_IncludePath)
$(UniversalCRT_LibraryPath_x64)

Despite that, how do I get proper library and include paths for build systems other than devenv or MSBuild?

For the sake of it:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC>set include
INCLUDE=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE;C:\Program Files (x86)\Windows Kits\10\include\wdf\ucrt;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um;C:\Program Files (x86)\Windows Kits\10\include\wdf\shared;C:\Program Files (x86)\Windows Kits\10\include\wdf\um;C:\Program Files (x86)\Windows Kits\10\include\wdf\winrt;

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC>set lib
LIB=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\LIB\amd64;C:\Program Files (x86)\Windows Kits\10\lib\wdf\ucrt\x64;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\lib\um\x64;C:\Program Files (x86)\Windows Kits\10\lib\wdf\um\x64;
LIBPATH=C:\Windows\Microsoft.NET\Framework64\v4.0.30319;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\LIB\amd64;C:\Program Files (x86)\Windows Kits\10\UnionMetadata;C:\Program Files (x86)\Windows Kits\10\References;C:\Program Files (x86)\Windows Kits\10\References\Windows.Foundation.UniversalApiContract\1.0.0.0;C:\Program Files (x86)\Windows Kits\10\References\Windows.Foundation.FoundationContract\1.0.0.0;C:\Program Files (x86)\Windows Kits\10\References\indows.Networking.Connectivity.WwanContract\1.0.0.0;C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs\14.0\References\CommonConfiguration\neutral;
crashmstr
  • 28,043
  • 9
  • 61
  • 79
Ben Kircher
  • 152
  • 1
  • 7

1 Answers1

8

Including the contents of the environment variables was a good idea. Based on the paths appearing there, it seems that you have the Windows Driver Kit installed and you're encountering this issue reported on Connect.

According to the description of the issue, the wdf directory created by the WDK confuses the batch file that tries to determine the latest SDK versions available. For example, instead of

C:\Program Files (x86)\Windows Kits\10\include\wdf\ucrt

in the INCLUDE variable, you should have something like

C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt

The "carpet-bombing" solution: uninstall the WDK, make sure the wdf directories are gone, and things should return to normal.


If that's not an option, here's a "surgical" solution: you need to edit

"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\vcvarsqueryregistry.bat"

(back it up first, of course)

1. Look for the following two labels:

:GetWindowsSdkDirHelper32
:GetWindowsSdkDirHelper64

Under each of them, you'll find the following line:

@REM Get windows 10 sdk version number
@if not "%WindowsSdkDir%"=="" @FOR /F "delims=" %%i IN ('dir "%WindowsSdkDir%include\" /b /ad-h /on') DO @set WindowsSDKVersion=%%i\

Change it to:

@REM Get windows 10 sdk version number
@if not "%WindowsSdkDir%"=="" @FOR /F "delims=" %%i IN ('dir "%WindowsSdkDir%include\" /b /ad-h /on') DO (
   @if not "%%i"=="wdf" (
      @set WindowsSDKVersion=%%i\
   )
)

2. Look for the following two labels:

:GetUniversalCRTSdkDirHelper32
:GetUniversalCRTSdkDirHelper64

Under each of them, change the following line:

@FOR /F "delims=" %%i IN ('dir "%UniversalCRTSdkDir%include\" /b /ad-h /on') DO @SET UCRTVersion=%%i

to:

@FOR /F "delims=" %%i IN ('dir "%UniversalCRTSdkDir%include\" /b /ad-h /on') DO (
   @if not "%%i"=="wdf" (
      @SET UCRTVersion=%%i
   )
)

That's it. Let me know if it helped.

Keep in mind that this will skip the wdf directories altogether. If the WDK command prompt setup scripts happen to use the same vcvarsqueryregistry.bat batch file (I doubt it, but...), then they won't work correctly anymore; a bit more hacking will be needed in this case to select the proper batch file for each build environment.

bogdan
  • 9,229
  • 2
  • 33
  • 48
  • Thanks for the link and the provided solutions. Your analysis was correct. I did uninstall the Windows SDK and the Windows Driver Kit and everything works like a charm again – Ben Kircher Oct 02 '15 at 10:45
  • 3
    `Let me know if it helped.` Thanks, it helped w/o uninstalling WDK. – RIscRIpt Oct 09 '15 at 19:21
  • 2
    Note also the workaround posted on the Microsoft site linked in the above answer. Making the wdf folder hidden also solves this issue. – patthoyts Dec 02 '15 at 11:58
  • 1
    I have the same situation but my vcvarsqueryregistry.bat has none of the labels mentioned above. Windows 7, VS 2015 Professional, I have uninstalled Windows Driver Kit. Still no luck from command line. – Bruce Aug 11 '16 at 07:33
  • 1
    @Bruce You seem to have a newer version of VS 2015 (one of the updates), where the issue above should be fixed. The `32` and `64` labels have been unified into `GetUniversalCRTSdkDirHelper` (and similarly for the Windows SDK). If I read the updated script correctly, it should skip directories under `include` that don't begin with `10.`, so the `wdf` directory shouldn't affect the result. I would try to look at the resulting `INCLUDE` to figure out where the incorrect paths come from. – bogdan Aug 11 '16 at 11:53