views:

1633

answers:

4

I have a Visual Studio C++ based program that uses pre-compiled headers (stdafx.h). Now we are porting the application to Linux using gcc 4.x.

The question is how to handle pre-compiled header in both environments. I've googled but can not come to a conclusion.

Obviously I want leave stdafx.h in Visual Studio since the code base is pretty big and pre-compiled headers boost compilation time.

But the question is what to do in Linux. This is what I found:

  1. Leave the stdafx.h as is. gcc compiles code considerable faster than VC++ (or it is just my Linux machine is stronger ... :) ), so I maybe happy with this option.
  2. Use approach from here - make stdafx.h look like (set USE_PRECOMILED_HEADER for VS only):

    #ifdef USE_PRECOMPILED_HEADER ... my stuff #endif

  3. Use the approach from here - compile VC++ with /FI to implicitly include stdafx.h in each cpp file. Therefore in VS your code can be switch easily to be compiled w/o pre-compiled headers without changing a line of code. I personally dislike dependencies and the mess stdafx.h is pushing a big code base towards. Therefore the option is appealing to me - on Linux you don't have stdafx.h, while still being able to turn on pre-compiled headers on VS by /FI only.

  4. On Linux compile stdafx.h only as a precompiled header (mimic Visual Studio)

Your opinion? Is there're another approaches to treat the issue?

+12  A: 

You're best off using precompiled headers still for fastest compilation.

You can use precompiled headers in gcc as well. See here.

The compiled precompiled header will have an extension appended as .gch instead of .pch.

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.

Brian R. Bondy
remove stdafx.h from where?
dimba
I meant just that after you run g++ -c stdafx.h -o stdafx.h.gch, you can remove stdafx.h and your compilation would still work (g++ a.cpp). You wouldn't actually do this, but I mentioned it as proof that it is using the precompiled header.
Brian R. Bondy
@Brian Maybe I'm wrong but this looks like option 4 I listed :) I tried to remove stdafx.h from a.cpp and it didn't compiled - precompiled header will be searched only if respective header file is included. I confirmed it with strace :)).
dimba
@idimba: Yes it is option 4, but you modified your question and added #4 three minutes after I posted my answer. The respective header file should be included anyway in source.
Brian R. Bondy
A: 

I used option 3 last time I needed to do this same thing. My project was pretty small but this worked wonderfully.

Lucas McCoy
A: 

I've done both option 2 (#ifdef) and option 4 (PCH for gcc) for cross platform code with no issues.

I find gcc compiles much faster than VS so the precompiled headers are generally not that important, unless you are referencing some huge header file.

Soo Wei Tan
+1  A: 

I'd either go for option 4 or option 2. I've experimented with precompiled headers on both various VS versions and GCC on Linux (blog posts about this here and here). In my experience, VS is a lot more sensitive to the length of the include paths, number of directories in the include path and the number of include files than G++ is. When I measured build times properly arranged precompiled headers would make a massive difference to the compile time under VS whereas G++ was pretty much unimpressed by this.

Actually, based on the above what I did the last time I worked on a project where this was necessary to rein in the compile time was to precompile the equivalent of stdafx.h under Windows where it made sense and simply used it as a regular file under Linux.

Timo Geusch