How to Precompile <bits/stdc++.h> header file in ubuntu 20.04 / 22.04?

Viewed 766

Is there any way to precompile the <bits/stdc++.h> header file in ubuntu 20.04 like we can do in Windows OS so that I can execute programs faster in my Sublime text editor?

I use the FastOlympicCoding extension for fast execution, but I miss the old way of using an input-output file. I searched everywhere but didn't find any 'layman' approach to do that.

4 Answers

An example creating a precompiled header:

mkdir -p pch/bits &&
g++ -O3 -std=c++20 -pedantic-errors -o pch/bits/stdc++.h.gch \
   /usr/include/c++/11/x86_64-redhat-linux/bits/stdc++.h

Check what you got:

$ file pch/bits/stdc++.h.gch
pch/bits/stdc++.h.gch: GCC precompiled header (version 014) for C++

$ ls -l pch/bits/stdc++.h.gch
-rw-r--r-- 1 ted users 118741428  8 mar 23.27 pch/bits/stdc++.h.gch

A program using it:

#include <bits/stdc++.h>

int main() {
    std::vector<int> foo{1, 2, 3};
    for(auto v : foo) std::cout << v << '\n';
}

Example compilation (put -Ipch first of the -I directives):

$ strace -f g++ -Ipch -O3 -std=c++20 -pedantic-errors -o program program.cpp 2>&1 | grep 'stdc++.h'
[pid 13964] read(3, "#include <bits/stdc++.h>\n\nint ma"..., 122) = 122
[pid 13964] newfstatat(AT_FDCWD, "pch/bits/stdc++.h.gch", {st_mode=S_IFREG|0644, st_size=118741428, ...}, 0) = 0
[pid 13964] openat(AT_FDCWD, "pch/bits/stdc++.h.gch", O_RDONLY|O_NOCTTY) = 4

Building on Ted's answer, I would actually do something like this (untested):

my_pch.h:

#include <bits/stdc++.h>          // might need to specify the full path here

And then:

g++ -O3 -std=c++20 -pedantic-errors -o pch/bits/my_pch.h.gch my_pch.h

And finally, your program would look like this:

#include "my_pch.h"

int main() {
    // ...
}

This means you don't need to put #include <bits/stdc++.h> directly in your source files, since that is a bit naughty. It also means you can add other include files to my_pch.h if you want them.

I think, also, it wouldn't cost you anything to put, say, #include <string> after including my_pch.h, and that doing that sort of thing might be wise. If you're ever going to move the code into production you could then recompile it with my_pch.h empty.


Edit: Another thing to consider (which I also can't test) is just to include the things you actually use (string, vector, whatever) in my_pch.h. That will probably pull in bits/stdc++.h anyway, when building the precompiled header. Make it a comprehensive list so that you don't need to have to keep adding to it. Then you have portable code and people won't keep beating you up about it.

So, After having help from @TedLyngmo's answer and doing a little bit more research, I decided to answer the question myself with more clear steps.

PS: This answer will be more relatable to those who are using sublime with their custom build file and are on Linux OS (Ubuntu).

  1. You need to find where stdc++.h header file is present, so open the terminal and use the command:

    find /usr/include -name 'stdc++.h'

    Output:

    /usr/include/x86_64-linux-gnu/c++/11/bits/stdc++.h

  2. Go to the above location and open the terminal there and now we are ready to precompile bits/stdc++.h header file.

  3. Use the following command:

    sudo g++ -std=c++17 stdc++.h

  4. You'll observe stdc++.h.gch file is now created implying that precompiling is done.

PS: You need to use sudo as we need root privileges when g++ makes stdc++.h.gch file.

NOTE: Here as I was using the c++17 version in my custom build file so I mentioned c++17, you can use whatever version you are using.

It worked perfectly for me so I hope it helps you too!

You should not #include <bits/stdc++.h> from ths source code, for at least two reasons:

  • It's not portable, so it would need to be guarded by ugly #ifdefs.

  • Unlike GCC, Clang never uses PCHs for #includes.

Instead you should include the PCH using the -include flag. This is the only option accepted by both GCC and Clang.

  1. Precompile the header using g++ -xc++-header /path/to/bits/stdc++.h -o stdc++.h.gch.

  2. Include it with -include: g++ foo.cpp -include stdc++.h.

Notice that -include automatically appends .gch to the filename; the current directory doesn't have to contain stdc++.h.

If there's no .gch file, -include falls back to including the regular non-PCH header, if it exists. If both exist in the include path, the PCH gets precedence.

Related