Friday night header reorganization

One of my pet peeves is stupid header organization. Like most large-scale software projects, we have hundreds (thousands?) of headers in our source tree. Those headers take a long time to compile. There are lots of ways to optimize compilation time (check out the absolutely necessary The C++ Programming Language for a good discussion of the issues). One way is using precompiled headers.

To try to improve our compile time, I decided I’d play with a more efficient PCH scheme, wherein the system headers and standard library headers are precompiled into a globally shared PCH file and the cross-project shared headers within our own codebase are compiled into a second level of PCH. The rationale is that the latter set of headers, which includes headers for several internal libraries, etc., changes somewhat more often than the system headers. Using a two-level PCH scheme, you get out of having to recompile the system headers if you change an internal header.

There is an obtuse but intriguing tutorial on the issue in the VC docs, but the problem is that it doesn’t work. Another person reported the issue on USENET a few months ago, with no answers. I’m now suspicious that I’ve found a compiler bug.

Anyhow, my USENET post from this evening has more details if you’re curious. Meanwhile, the experimentation continues.

UPDATE: This really looks like a compiler bug. It works fine on cl 13.x.y but breaks on cl 14.x.y. Here are the files I’m using (or download a ZIP: pch.zip:

--------
Makefile
--------
all:
    cl -nologo -Ic:\\winddk\\5384\\inc\\api \\
        -Ic:\\winddk\\5384\\inc\\crt \\
        -Ycsystem-precomp.h -Fpsystem-precomp.pch \\
        -c system-precomp.cpp
    cl -nologo -Ic:\\winddk\\5384\\inc\\api \\
        -Ic:\\winddk\\5384\\inc\\crt \\
        -Yusystem-precomp.h -Fpsystem-precomp.pch \\
        -c -Yc precomp.cpp
    cl -nologo -Ic:\\winddk\\5384\\inc\\api \\
        -Ic:\\winddk\\5384\\inc\\crt \\
        -Yuprecomp.h -Fpprecomp.pch \\
        -c junk.cpp

clean:
    del *.pch *.obj

----------------
system-precomp.h
----------------
#define UNICODE
#include 

------------------
system-precomp.cpp
------------------
#include "system-precomp.h"

---------
precomp.h
---------
#include "junk.h"

-----------
precomp.cpp
-----------
#pragma once
#include "system-precomp.h"
#include "junk.h"
#pragma hdrstop("precomp.pch")

------
junk.h
------
#pragma once

class A
{
        int x;
};

--------
junk.cpp
--------
#include "precomp.h"

int main()
{
        MessageBox(0, L"Hello", L"Hello", 0);
}

With cl 13, from the 3790.1830 DDK, it works. With cl 14, from the beta 2 WDK, it fails:

C:\\dev\\sandbox\\pch>cl
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version
13.10.4035 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

C:\\dev\\sandbox\\pch>make
        cl -nologo -Ic:\\winddk\\5384\\inc\\api -Ic:\\winddk\\5384\\inc\\crt
-Ycsystem-precomp.h -Fpsystem-precomp.pch -c system-precomp.cpp

system-precomp.cpp
        cl -nologo -Ic:\\winddk\\5384\\inc\\api -Ic:\\winddk\\5384\\inc\\crt
-Yusystem-precomp.h -Fpsystem-precomp.pch -c -Yc precomp.cpp
precomp.cpp
        cl -nologo -Ic:\\winddk\\5384\\inc\\api -Ic:\\winddk\\5384\\inc\\crt
 -Yuprecomp.h -Fpprecomp.pch -c junk.cpp
junk.cpp

C:\\dev\\sandbox\\pch>

---

C:\\dev\\sandbox\\pch>make clean
        del *.pch *.obj

C:\\dev\\sandbox\\pch>cl
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version
14.00.50727.93 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

C:\\dev\\sandbox\\pch>make
        cl -nologo -Ic:\\winddk\\5384\\inc\\api -Ic:\\winddk\\5384\\inc\\crt
-Ycsystem-precomp.h -Fpsystem-precomp.pch -c system-precomp.cpp

system-precomp.cpp
        cl -nologo -Ic:\\winddk\\5384\\inc\\api -Ic:\\winddk\5384\\inc\\crt
-Yusystem-precomp.h -Fpsystem-precomp.pch -c -Yc precomp.cpp
precomp.cpp
precomp.cpp(4) : fatal error C1083: Cannot open precompiled header file:
'precomp.pch': The process cannot access the file because it is being
used by another process.

NMAKE :  U1077: 'c:\\WinDDK\\5384\\bin\\x86\\x86\\cl.EXE' :
return code '0x2'
Stop.

C:\\dev\\sandbox\\pch>

Leave a Reply