17

I use Visual Studio 2017. In a project (that I target as x64), I get error : C1060, compiler is out of heap space, and sadly learned there happen to exist a memory limitation for compilation.

When monitoring CL.exe, it indeed stop just before reaching 4GB. So it looks like CL.exe is by default a 32bits application, as seen at : https://docs.microsoft.com/en-us/cpp/build/how-to-enable-a-64-bit-visual-cpp-toolset-on-the-command-line

After reading this page, I installed "Universal Windows Platform workload" hoping to get access to a 64 bit version of CL.exe. But no change when compiling my project, and I can't see a single option in visual studio to choose compiler version.

I assume that there must exist a workaround to be able to use more than 4GB for a single compilation unit, but I couldn't find it for now. Any help would be much appreciated.

Edit : I hit limitation in Debug mode. Compilation is doing fine in Release mode. Which is suppose makes sense.

brahmin
  • 558
  • 1
  • 4
  • 16
  • 4
    Have you tried figuring out why does compilation need so much RAM? It may be caused by serious code issues, such as template bloat. – user7860670 Oct 11 '17 at 08:28
  • I suppose the workaround is to reduce the size of the or complexity of compilation units by breaking them up (so the compiler doesn't consume so much memory). You haven't given any information about why you can't do this. What's the cause of your compilation unit being so big? – Ben Oct 11 '17 at 08:28
  • It's a heavily template oriented project. I didn't mention this since it's a bit out of the scope of the question. So short answer : no I can't split the compilation unit. And it's doing just fine on other platforms such as Xcode or Linux. – brahmin Oct 11 '17 at 08:31
  • I agree with @VTT template problems are the most likely cause of runaway compiler memory usage. For example you may be recursively instantiating a template. – Ben Oct 11 '17 at 08:33
  • 1
    ... and while there are ways to make that work provided recursion terminates, if you are compiling cross-platform you may have accidentally introduced a bug where it terminates under CLang or GCC but not under MSVC. For example when using different names for a type, the types may be the same under CLang but different under MSVC, depending on compiler options etc. – Ben Oct 11 '17 at 08:36
  • 1
    Edited question : fine in release mode – brahmin Oct 11 '17 at 08:40
  • 3
    Project > Properties > VC++ Directories > Executable Directories setting. Change $(VC_ExecutablePath_x86) to $(VC_ExecutablePath_x64_x86). This was broken in the RTM release btw, no idea if they fixed it yet. – Hans Passant Oct 11 '17 at 10:15
  • You're a hero @HansPassant, thanks. I added $(VC_ExecutablePath_x64_x86) and $(VC_ExecutablePath_x64_x64) and it's compiling. I couldn't find a way to trace CL.exe and be sure which one is used, but looks like it's the x64 one since when monitoring it, it went over 4GB. Feel free to add an answer. – brahmin Oct 11 '17 at 13:33

1 Answers1

24

By default Visual Studio uses the 32-bit toolchain (i.e. the compiler is 32-bit and cross-compiles 64-bit executables). Visual Studio 2015 and 2017 include both 32-bit and 64-bit versions of all the compilers (x86, x64, arm, arm64).

You can opt-in to using the 64-bit toolchain on a 64-bit system by two methods:

  1. Add a environment variable on your build machine (either system-wide or from a VS Developer Command Prompt).

For example:

set PreferredToolArchitecture=x64
devenv
  1. You can edit your vcxproj files to do this as well with the <PreferredToolArchitecture>x64</PreferredToolArchitecture> element:

For example:

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v141</PlatformToolset>
    <PreferredToolArchitecture>x64</PreferredToolArchitecture>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>

I use the second method in the UWP (C++/WinRT) versions of my Direct3D Game VS Templates, and I just noticed that I should add it to my UWP (C++/CX) and Win32 versions. The Xbox One XDK automatically does this in it's platform build rules as well.

Note this question has been answered in the past: How to make Visual Studio use the native amd64 toolchain

Chuck Walbourn
  • 33,359
  • 2
  • 51
  • 77
  • Perfect, `x64` did the trick. Extra kudos for the complete snippet about where to put the change. – Cerno Sep 30 '21 at 12:00