15

After VS2015 updated my project to the new Platform toolset v140, it fails to build due to a linker error : LNK1104 cannot open file 'libucrt.lib'.

It appears this library has been moved around due to the new Universal CRT as mentioned in this article : http://blogs.msdn.com/b/vcblog/archive/2015/03/03/introducing-the-universal-crt.aspx?PageIndex=2.

While the article does tell me what I should link towards now, it does not provide instructions how.

My Solution generates a .exe and a .dll it uses. I do not know what to do with the matrix the article describes below.

Release DLLs (/MD ): msvcrt.lib vcruntime.lib ucrt.lib

Release Static (/MT ): libcmt.lib libvcruntime.lib libucrt.lib

Jesse Meyer
  • 315
  • 1
  • 3
  • 12
  • The blog post looks pretty clear to me. It gives the new libs and the paths to find them. What steps did you do when you "updated" your project? – Ryan Bemrose Jul 21 '15 at 00:37
  • I selected my solution from the Solution Explorer, and 're-armed', I believe was the term, which remapped each project to the new compiler. I then added $(UniversalCRT_IncludePath) to Additional Include Directives in their configuration properties. – Jesse Meyer Jul 21 '15 at 01:16
  • Did you also add `$(UniversalCRT_LibraryPath_*)` (depending on your target processor) to the link settings? – Ryan Bemrose Jul 21 '15 at 01:35
  • I had not, and that resolved the issue. Thanks! If you submit that as an answer I'll accept it. – Jesse Meyer Jul 21 '15 at 01:44
  • 2
    Are you using Visual Studio 2015 RC or RTM? We made some tweaks in RTM to the targets to try to reduce the impact of the directories change. If you're using Visual Studio 2015 RTM, would you be willing to share [1] what your IncludePath and LibraryPath are set to in your project or [2] could you share the entire project file with us? We're interested in understanding what kinds of project files are not picking up the new default settings. (You may e-mail me at james.mcnellis@microsoft.com, if you'd like.) – James McNellis Jul 21 '15 at 01:58
  • James, if the steps have changed, can you please edit the answer below to make sure it's correct? – Ryan Bemrose Jul 21 '15 at 01:58
  • @RyanBemrose Your answer is a correct answer. The other option is to have the project derive its IncludePath and LibraryPath from the preset property values (e.g. via `[your stuff goes here];$(IncludePath)`). This is the preferable option, but doesn't always work because of quirky things that some projects or user targets files do. Thanks for answering the question; it's been a while...I hope you're doing well :-) – James McNellis Jul 21 '15 at 02:01
  • @JamesMcNellis Hi James! Thanks for spending time helping, I really appreciate it. I am using what was released today on Microsoft's website, which I don't think is either RC or RTM. Its version is 14.023107.0. I'm reviewing my license to see if I am at liberty to share with you my entire project, but for now, my VC++ Directory's Include Directory currently is $(DXSDK_DIR)\Include;$(IncludePath) and my Library Directories is $(VCInstallDir)lib;$(WindowsSDK_LibraryPath_x86);$(DXSDK_DIR)\Lib\x86. I do not see anything relating to Path in my configuration panel. – Jesse Meyer Jul 21 '15 at 03:40
  • I see. That makes sense; I don't need to see the project file. Your `IncludePath` is correct; it "dervies" from `$(IncludePath)`. Your `LibraryPath` should do the same and derive from `$(LibraryPath)`. Previously (e.g. in Visual Studio 2013), all of the runtime libraries for x86 were located in `$(VCInstallDir)lib`. Now, some of the libraries are in a new directory, `$(UniversalCRT_LibraryPath_x86)`. If your project derives its `LibraryPath` from the base `$(LibraryPath)` (just like you do for `IncludePath`), then it will find those libraries automatically. – James McNellis Jul 21 '15 at 03:44
  • Starting in RTM, if a project at least includes `$(VC_LibraryPath_x86)` in its `LibraryPath`, it'll also find the libraries. Unfortunately, your project refers directly to `$(VCInstallDir)lib`, and there's no way for us to "automatically" transform this into two paths to match the new layout of files on disk (at least not easily, and we don't want to write a bunch of one-off rules for transforming project files during project upgrade--that would not work well). – James McNellis Jul 21 '15 at 03:47
  • So, basically, your `LibraryPath` should ideally become `$(DXSDK_DIR)\Lib\x86;$(LibraryPath)` (if you really need the DirectX SDK to be after the Visual C++ SDK and Windows SDK paths, then you can add it after `$(LibraryPath)` too; I expect this is not really necessary). If you change your `LibraryPath` to this, it'll work in both Visual C++ 2013 and 2015. – James McNellis Jul 21 '15 at 03:49
  • Hi, along the lines of the first question. Where in the project file do we actually add the include and library? – Ali Oct 04 '17 at 19:39
  • I found out in vcxproj I have to add the variable to Project.ItemDefinitionGroup.Link.AdditionalLibraryDirectories The problem I have now is that the variable doesn't work and I had to type in the actual location of the directory'C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10150.0\ucrt\x64'. Any thoughts? – Ali Oct 04 '17 at 20:47

4 Answers4

11

When you convert your project, you need to make sure you update both the includes AND the linker settings to point to the new CRT.

For includes, add the following:

$(UniversalCRT_IncludePath)

For link, add one of the following depending on your target processor:

$(UniversalCRT_LibraryPath_x86)
$(UniversalCRT_LibraryPath_x64)
$(UniversalCRT_LibraryPath_arm)
Ryan Bemrose
  • 9,018
  • 1
  • 41
  • 54
  • The solution works for me when I was trying to adapting old c++ projects from VS2013 to VS2017. Thank you! – Cary Nov 20 '17 at 14:16
3

The built-in variable $(LibraryPath) resolves to all the library paths needed to build an application in Visual Studio, including UCRT paths in VS 2015.

Note: you might want to update the include path as well, the portable built-in variable for that is: $(IncludePath).

Or better yet, if you require no library or include path customization, is to use defaults (select <inherit from parent or defaults>).

Note 2: you can adjust the paths for multiple projects and multiple targets at the same time, just select multiple projects, then select "properties".

rustyx
  • 80,671
  • 25
  • 200
  • 267
3

I have downloaded the SDK 10.0.10586.0, which now contains the library libucrt.lib in C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10586.0\ucrt\x64. But I cannot get the linker to locate this library; it uses 10240 (the previous installed version).

The macros referred to above, $(LibraryPath) and $(UniversalCRT_LibraryPath_x64), both refer to C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\ucrt\x64. I don't know how to change the values for these macros, which presumably is necessary to get the linker to use the proper library.

Windows 7 Pro, 64-bit, Visual Studio 2015 update 1. Linking static libraries, C++ and Intel Fortran project.

Woody20
  • 791
  • 11
  • 30
  • 1
    I have the same problem, the macros point to an older version than what is installed. I have not yet found where this can be updated. – Zitrax Jun 20 '16 at 13:03
  • 3
    Ok I found a link describing what to do: https://msdn.microsoft.com/en-us/library/mt186161.aspx so basically right click the solution and chose "Retarget solution" and select the proper SDK version. – Zitrax Jun 20 '16 at 13:16
  • How do you know where the library variable points? I'm not seeing these definitions anywhere, and mine don't work. – Ali Oct 04 '17 at 21:47
2

By default if you compile your project with vs2015, Universal CRT will be in use. (Nothing special needs to be done)

But if you want to statically link (and get rid of ucrt dependency) - read this article:

Visual studio 2015 run-time dependencies or how to get rid of Universal CRT?

Community
  • 1
  • 1
TarmoPikaro
  • 4,723
  • 2
  • 50
  • 62