Speed up #include

I’m testing cling with some code of non trivial size. It works fine, but it spends really a lot of time on the #include directive. I was wondering if there is a way to speed it up.

I have my program in a text file like this:

[code].I …/include
.L mylib.so

#include “myheader.hh” // <— this takes ages :frowning:

/*
actual code <— this is fast :slight_smile:
*/

.q[/code]
and I run cling with:

Many thanks!

Hi,
There are three solutions to this #include speedup problem:

  1. Best one: Use precompiled modules (PCMs) clang.llvm.org/docs/Modules.html - not implemented yet
  2. Use a precompiled header, build a giant PCH for everything in the include path. This is relatively cheep to implement in cling, we are not there yet. I am not sure if this is what you want, because you .L a user-specific library, which may or may not be in the include path or you will have to regenerate the PCH on every change in this library, which is even slower.
  3. Autoloading maps: a mirror of the original header file containing only forward declarations, which is very fast to parse. Upon use of contents in the header file the header file/fraction of the header file will be loaded. Recent developments can be found at: github.com/vgvassilev/cling/tree/cling-new-llvm

Cheers,
Vassil

PS: The #include doesn’t take any longer than what one gets by compiling the program with clang/gcc.

Hi,

Thanks for the reply. The library loaded with .L is quite stable, I won’t have to change it very often, so precompiling its headers is ok for me, I actually tried (and failed) before asking, now I learn that is not possible yet…

I am not going to move all the code outside the headers, leaving only forward declarations there. That would be an important amount of work resulting in an awful code. But if cling will take care of this I’ll be happy to test the feature!

So as far as I got there are many ways to tackle the issue but all of them are work in progress, right?

Cheers,
Dario

PS: Sure, packing my testing scripts into a main and recompile them every minor change is a tedious procedure, but I was expecting cling to be considerably faster than this, not just saving a tiny makefile…

Hi,
You might get away by doing:

$ clang/build/next/to/cling/binary/clang -cc1 -target-cpu x86-64 -fdeprecated-macro -fmath-errno -fexceptions -fcxx-exceptions -fgnu-keywords T.h -emit-pch -xc++ -std=c++11  -o T.pch
cling  -Xclang -trigraphs -Xclang  -include-pch -Xclang T.pch

Note that you need to build the PCH with the clang binary, compatible with cling. It is located next to the cling binary if you build from source.
Cheers,
Vassil

Hello,

Thanks, I’m going to test this solution!

Are you doing something like that for Root at the moment? Of course it is not possible to spend on the #include directives a time similar to the compilation of the full Root software every time a script is launched!
The code I’m working on is an experimental branch of Placet: a program to simulate beam dynamics and test corrections in linear accelerators. As the core is totally written in C++, it would be nice for a user to access it directly as can be done with Root.

Cheers,
Dario

The clang executable next to cling complains that it does not find the STL header. I don’t have this problem loading everything in cling :confused:

If you come up with other (feasible) ideas to load a bunch of precompiled code and fast process scripts based on it, please let me know.

Cheers,
Dario

Hi,
We have similar PCH infrastructure for ROOT. We just need to disentagle the a script building the PCH.

For the missing do you have libc++ which usually comes with gcc 4.8?
Cheers,
Vassil

Hi,
Since for the pch we are going behind the driver you will need something like:

cat TT.h 
#include <algorithm>
struct B{};
B b;
../../Debug+Asserts/bin/clang -cc1 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8 -internal-isystem /usr/local/include -internal-isystem /home/vvassilev/workspace/llvm-github/obj/Debug+Asserts/bin/../lib/clang/3.6.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include  -target-cpu x86-64 -fdeprecated-macro -fmath-errno -fexceptions -fcxx-exceptions -fgnu-keywords TT.h -emit-pch -xc++ -std=c++11  -o TT.pch

I.e you need to put all -I yourself. You can get them easily by doing:

../../Debug+Asserts/bin/clang -xc++ -fsyntax-only TT.h -v

Cheers,
Vassil

Hi,

I tried many times, even cloning the whole cling again but, although I precompiled the header at the first attempt, I haven’t been able to let cling like it:

$ cling -Xclang -trigraphs -Xclang -include-pch -Xclang TT.pch error: PCH file was compiled for the target linker version '' but the current translation unit is being compiled for target '2.24'

I’m using libc++ v4.9.0. It looks like a silly error, but I have no idea of its meaning.

Cheers,
Dario

Hi,
It looks like you need to pass in -target-linker-version 2.24 when generating the PCH. clang -cc1 --help | less can give you some more info about the available flags.
Vassil