Anyone had any success getting precompiled headers working with GCC? I have had no luck in my attempts and I haven't seen many good examples for how to set it up. I've tried on cygwin gcc 3.4.4 and using 4.0 on Ubuntu.
I have managed to get precompiled headers working under gcc once in the past, and I recall having problems then as well. The thing to remember is that gcc will ignore the file (header.h.gch or similar) if certain conditions are not met, a list of which can be found on the gcc precompiled header documentation page.
Generally it's safest to have your build system compile the .gch file as a first step, with the same command line options and executable as the rest of your source. This ensures the file is up to date and that there are no subtle differences.
It's probably also a good idea to get it working with a contrived example first, just to remove the possibility that your problems are specific to source code in your project.
Call gcc same way as you call it for your source file but with a header file.
e.g.
g++ $(CPPFLAGS) test.h
this generates a file called test.h.gch
Every time gcc searches for test.h it look first for test.h.gch and if it finds it it uses it automatically.
More information can be found under GCC Precompiled Headers
Firstly, see the documentation here.
You compile headers just like any other file but you put the output inside a file with a suffix of .gch
.
So for example if you precompile stdafx.h you will have a precompiled header that will be automatically searched for called stdafx.h.gch
anytime you include stdafx.h
Example:
stdafx.h:
#include <string>
#include <stdio.h>
a.cpp:
#include "stdafx.h"
int main(int argc, char**argv)
{
std::string s = "Hi";
return 0;
}
Then compile as:
> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out
Your compilation will work even if you remove stdafx.h after step 1.
I have definitely had success. First, I used the following code:
#include <boost/xpressive/xpressive.hpp>
#include <iostream>
using namespace std;
using namespace boost::xpressive;
//A simple regex test
int main()
{
std::string hello( "hello world!" );
sregex rex = sregex::compile( "(\\w+) (\\w+)!" );
smatch what;
if( regex_match( hello, what, rex ) )
{
std::cout << what[0] << '\n'; // whole match
std::cout << what[1] << '\n'; // first capture
std::cout << what[2] << '\n'; // second capture
}
return 0;
}
This was just a hello world from Boost Xpressive (see below for link). First, I compiled with the -H
option in gcc. It showed an enormous list of headers that it used. Then, I took a look at the compile flags my IDE (code::blocks) was producing and saw something like this:
g++ -Wall -fexceptions -g -c main.cpp -o obj/Debug/main.o
So I wrote a command to compile the Xpressive.hpp file with the exact same flags:
sudo g++ -Wall -fexceptions -g /usr/local/include/boost/xpressive/xpressive.hpp
I compiled the original code again with the -H
and got this output:
g++ -Wall -fexceptions -H -g -c main.cpp -o obj/Debug/main.o ! /usr/local/include/boost/xpressive/xpressive.hpp.gch main.cpp . /usr/include/c++/4.4/iostream .. /usr/include/c++/4.4/x86_64-linux-gnu/bits/c++config.h .. /usr/include/c++/4.4/ostream .. /usr/include/c++/4.4/istream main.cpp
The ! means that the compiler was able to use the precompiled header. An x means it was not able to use it. Using the appropriate compiler flags is crucial. I took off the -H and ran some speed tests. The precompiled header had an improvement from 14 seconds to 11 seconds. Not bad but not great.
Note: Here's the link to the example: http://www.boost.org/doc/libs/1_43_0/doc/html/xpressive/user_s_guide.html#boost_xpressive.user_s_guide.examples I couldn't get it to work in the post.
BTW: I'm using the following g++
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3