Precompiled headers

I’m having a go at using precompiled headers, but it doesn’t seem to be working. What am I doing wrong?

C:\test>type a.h
#include
using namespace std;

C:\test>type a.cpp
#include “a.h”

int main() {
cout << “test\n”;
return 0;
}

C:\test>clang --version
clang version 3.7.0 (tags/RELEASE_370/final)
Target: x86_64-pc-windows-msvc
Thread model: posix

C:\test>clang -fms-compatibility-version=19 -x c+±header a.h

C:\test>dir
Volume in drive C is OS
Volume Serial Number is C685-B1F1

Directory of C:\test

11/12/2015 15:51 .
11/12/2015 15:51 …
11/12/2015 15:45 67 a.cpp
11/12/2015 15:44 41 a.h
11/12/2015 15:51 4,677,904 a.h.gch
11/12/2015 15:51 250 test.bat
4 File(s) 4,678,262 bytes
2 Dir(s) 181,629,882,368 bytes free

C:\test>clang-cl -fms-compatibility-version=19 -Xclang -include-pch a.h.gch a.cpp
error: invalid value ‘precompiled-header’ in ‘-x precompiled-header’
error: unable to read PCH file -o: ‘no such file or directory’
error: error reading ‘C:\Users\w\AppData\Local\Temp\a-1b7148.obj’
error: unable to read PCH file -o: ‘no such file or directory’
fatal error: malformed or corrupted AST file: ‘Unable to load module “-o”: module file not found’
4 errors generated.

C:\test>clang-cl -fms-compatibility-version=19 -Xclang -include-pch a.h a.cpp
error: unable to read PCH file -o: ‘no such file or directory’
fatal error: malformed or corrupted AST file: ‘Unable to load module “-o”: module file not found’
2 errors generated.
error: unable to read PCH file -o: ‘no such file or directory’
error: error reading ‘C:\Users\w\AppData\Local\Temp\a-5cd097.obj’
error: unable to read PCH file -o: ‘no such file or directory’
fatal error: malformed or corrupted AST file: ‘Unable to load module “-o”: module file not found’
4 errors generated.

C:\test>dir
Volume in drive C is OS
Volume Serial Number is C685-B1F1

Directory of C:\test

11/12/2015 15:51 .
11/12/2015 15:51 …
11/12/2015 15:45 67 a.cpp
11/12/2015 15:44 41 a.h
11/12/2015 15:51 250 test.bat
3 File(s) 358 bytes
2 Dir(s) 181,634,908,160 bytes free

I’m having a go at using precompiled headers, but it doesn’t seem to be working. What am I doing wrong?

C:\test>type a.h
#include
using namespace std;

C:\test>type a.cpp
#include “a.h”

int main() {
cout << “test\n”;
return 0;
}

C:\test>clang --version
clang version 3.7.0 (tags/RELEASE_370/final)
Target: x86_64-pc-windows-msvc
Thread model: posix

C:\test>clang -fms-compatibility-version=19 -x c+±header a.h

C:\test>dir
Volume in drive C is OS
Volume Serial Number is C685-B1F1

Directory of C:\test

11/12/2015 15:51 .
11/12/2015 15:51 …
11/12/2015 15:45 67 a.cpp
11/12/2015 15:44 41 a.h
11/12/2015 15:51 4,677,904 a.h.gch
11/12/2015 15:51 250 test.bat
4 File(s) 4,678,262 bytes
2 Dir(s) 181,629,882,368 bytes free

C:\test>clang-cl -fms-compatibility-version=19 -Xclang -include-pch a.h.gch a.cpp
error: invalid value ‘precompiled-header’ in ‘-x precompiled-header’
error: unable to read PCH file -o: ‘no such file or directory’
error: error reading ‘C:\Users\w\AppData\Local\Temp\a-1b7148.obj’
error: unable to read PCH file -o: ‘no such file or directory’
fatal error: malformed or corrupted AST file: ‘Unable to load module “-o”: module file not found’
4 errors generated.

C:\test>clang-cl -fms-compatibility-version=19 -Xclang -include-pch a.h a.cpp

-Xclang passes only the immediately following argument to cc1. You need

clang-cl -fms-compatibility-version=19 -Xclang -include-pch -Xclang a.h.gch a.cpp

Also, the -Xclang / -cc1 interface is not really supported and has no stability guarantees; do the cl.exe flags for PCH not work in clang-cl? (If not, please file a bug on that.)

Nico was going to take a shot at making the /Y preprocessor flags work with
clang-cl, but I don't think he got around to it. I think it's not as easy
as adding more aliases, you have to add some driver logic.

-Xclang twice sort of works, but it seems to make the compiler forget how to call the linker?

C:\test>clang-cl -fms-compatibility-version=19 -Xclang -include-pch -Xclang a.h.gch a.cpp
a-427777.obj : error LNK2019: unresolved external symbol “class std::basic_ostream<char,struct std::char_traits > std::cout” (?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A) referenced in function main
a-427777.obj : error LNK2019: unresolved external symbol “bool __cdecl std::uncaught_exception(void)” (?uncaught_exception@std@@YA_NXZ) referenced in function “public: __cdecl std::basic_ostream<char,struct std::char_traits >::sentry::~sentry(void)” (??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAA@XZ)
a-427777.obj : error LNK2019: unresolved external symbol “char const * __cdecl std::_Syserror_map(int)” (?_Syserror_map@std@@YAPEBDH@Z) referenced in function "public: virtual class std::basic_string<char,struct std::char_traits,class std::allocator > __cdecl std::_Generic_error_category::message(int)const " (?message@_Generic_error_category@std@@UEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@H@Z)
a-427777.obj : error LNK2019: unresolved external symbol “void __cdecl std::_Xout_of_range(char const *)” (?_Xout_of_range@std@@YAXPEBD@Z) referenced in function "public: void __cdecl std::basic_string<char,struct std::char_traits,class std::allocator >::_Xran(void)const " (?_Xran@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAXXZ)
a-427777.obj : error LNK2019: unresolved external symbol “void __cdecl std::_Xlength_error(char const *)” (?_Xlength_error@std@@YAXPEBD@Z) referenced in function "public: void __cdecl std::basic_string<char,struct std::char_traits,class std::allocator >::_Xlen(void)const " (?_Xlen@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAXXZ)
a-427777.obj : error LNK2019: unresolved external symbol “void __cdecl std::_Xbad_alloc(void)” (?_Xbad_alloc@std@@YAXXZ) referenced in function “char * __cdecl std::_Allocate(unsigned __int64,char *,bool)” (??$_Allocate@D@std@@YAPEAD_KPEAD_N@Z)
a.exe : fatal error LNK1120: 6 unresolved externals

-Xclang passes only the immediately following argument to cc1. You need

clang-cl -fms-compatibility-version=19 -Xclang -include-pch -Xclang
a.h.gch a.cpp

Also, the -Xclang / -cc1 interface is not really supported and has no
stability guarantees; do the cl.exe flags for PCH not work in clang-cl? (If
not, please file a bug on that.)

Nico was going to take a shot at making the /Y preprocessor flags work
with clang-cl, but I don't think he got around to it. I think it's not as
easy as adding more aliases, you have to add some driver logic.

I actually have a pretty complete patch that seems to work modulo testing
and error handling (the most significant problem is that if your
precompiled header fails to build, the driver currently still goes ahead
and tries to use the (non-existent) gch file to produce the .obj file in
/Yc mode).

That sounds good. After all, when creating a precompiled header file, you don’t even want an object file at that time anyway, and if the precompiled header fails to build, you expect to have to stop and fix it before you can usefully do anything else.