Skip to content
Jean-Sebastien Mouret edited this page Feb 2, 2018 · 6 revisions

TL;DR

Use /Z7 instead of /Zi

Different kinds of PDB files

Let's take a simple project hierarchy.

 src/
   a.cpp
   b.cpp
 obj/
   a.obj
   b.obj
   project.pdb   <--- made by cl.exe /Zi
 output/
   project.exe
   project.pdb   <--- made by link.exe /debug

We can see there are 2 project.pdb files. The one in the obj folder is made by cl.exe, the other one by link.exe.

To build output/project.pdb, the linker collects debug information from obj/project.pdb and/or from the object files themselves.

Caching support

When compiling, both cpp files (a.cpp, b.cpp) will output their debug information into the same PDB file (obj/project.pdb). When multi-threading builds, it requires to use /FS so that writes to the shared PDB file are streamlined through mspdbsrv.exe.

This is a bottleneck for caching as we cannot store individual PDB bits for each cpp files.

To solve this, Stashed will rewrite the command lines to generate the following hierarchy.

 src/
   a.cpp
   b.cpp
 obj/
   a.obj
   b.obj
   project.1234.pdb   <--- PDB for a.obj
   project.5678.pdb   <--- PDB for b.obj
 output/
   project.exe
   project.pdb

Now that there is one PDB per object file, the build can be easily cached and multithreaded.

The final output/project.pdb will still be correctly built as it automatically fetches debug information for each object from its corresponding individual PDB file.

That makes the trick completely transparent.

Limitation

When dealing with large projects, this technique can lead to longer link times and more memory consumption.

Instead of reading from one obj/project.pdb, the linker needs to read from many (thousands!) obj/project.1234.pdb... which causes more file I/O and uses more memory.

Solution

Instead of storing debug information in a separate PDB file, it can be stored directly inside the object file by using the /Z7 flag instead of /Zi.

The project hierarchy will look like that.

 src/
   a.cpp
   b.cpp
 obj/
   a.obj   <--- contains a.cpp debug info
   b.obj   <--- contains b.cpp debug info
 output/
   project.exe
   project.pdb  <--- still produced by link.exe /debug

Linking time and memory usage is reduced as less files need to be opened.

The project will still have a full PDB that can be shipped for debug builds.

Clone this wiki locally