Summary
Non-Visual Studio builds serialize on a common PDB file.
Example:
These compilations are both serialized on "vc80.pdb"
cl.exe /c foo.cpp /Zi /Fd"vc80.pdb" …
cl.exe /c bar.cpp /Zi /Fd"vc80.pdb" …
This occurs because cl.exe updates the PDB file when compiling each source file.
Solution
There are two solutions to enable parallelization:
-
Embed the debug information in the object file (use /Z7 rather than /Zi or /ZI)
cl.exe /c foo.cpp /Z7 …
cl.exe /c bar.cpp /Z7 … -
Generate multiple PDB files
cl.exe /c foo.cpp /Zi /Fd"vc80_00.pdb" …
cl.exe /c bar.cpp /Zi /Fd"vc80_01.pdb" …
Either method will parallelize the compilations, however, using /Z7 will not produce all of the debugging information provided by /Zi. See https://www.debuginfo.com/articles/gendebuginfo.html for the differences. Note: When using multiple PDBs, PCH must be turned off. This may cause compilation errors - see solutions below.
cl.exe
Electric Cloud provides a cl.exe 'stub' ("eccl.exe") that can perform either of these substitutions automatically:
How to use eccl.exe:
-
Call eccl.exe in place of cl.exe. It will call cl.exe with the modified arguments. This requires changes to makefiles only.
-
Rename eccl.exe to cl.exe and the existing cl.exe to $(ECCL_PATH) (default cl_orig.exe). This requires no makefile changes but cl.exe must be renamed on all agent hosts. Other users of these agents will be unaffected.
Modification of arguments:
-
With no environment variables, the arguments for cl.exe are unmodified.
-
With ECCL_FORCE_Z7 defined, /ZI and /Zi are replaced with /Z7. (This overrides ECCL_MAX_PDB_FILES)
-
With ECCL_MAX_PDB_FILES=, the PDB file is renamed to fall in one of at most 'n' PDB files. The source file is used as the basis for determining which PDB file a particular compilation uses.
In this case, PCH is switched OFF and may cause build errors. /Yc, /Yu, /YX, and /Fp are all removed.
If /Fd is a directory (that is, does not end in .pdb), you may use "ECCL_PREFIX" (default "vc80") to define a prefix for the PDB file.
If /Fd is a filename, the existiing filename is appended with "_XX.pdb" where XX is the two-digit bucket.
Example:
/Fd"Debug" with ECCL_PREFIX undefined becomes /Fd"Debug\vc80_XX.pdb"
/Fd"Debug" with ECCL_PREFIX=MyProject becomes /Fd"Debug\MyProject _XX.pdb"
/Fd"Debug\MyApp.pdb" becomes /Fd"Debug\MyApp_XX.pdb", irrespective of ECCL_PREFIX.
Where inline files are used, eccl.exe will modify the temporary file accordingly.
Fixing compilation errors because PCH is switched off
-
Missing PCH header (for example, "stdafx.h"), or use of wrong PCH header.
If the PCH user is not in the same directory as the PCH creator (or stdafx.h), either move the source file or specify the correct path to stdafx.h.
-
Invalid code before "stdafx.h" inclusion.
Remove/correct the offending code.