How to use precompiled headers with MinGW?

Do you have a question about makefiles, a compiler or IDE you are using and need to know how to set it up for wxWidgets or why it doesn't compile but other IDE's do ? Post your questions here.
Lestat
Experienced Solver
Experienced Solver
Posts: 68
Joined: Tue Apr 26, 2005 1:04 am
Location: Kemerovo, Russia

How to use precompiled headers with MinGW?

Post by Lestat »

First of all I should said that I read:
1. Using Precompiled Headers: http://gcc.gnu.org/onlinedocs/gcc-3.4.2 ... ed-Headers
2. Some topics on this forum that concerned to precompiled headers:
a. How to Use Precompiled Header with wx2.5.3 [Mingw 3.4.2]: http://forums.wxwidgets.org/viewtopic.php?t=407
b. "_puttchar" redefined: http://forums.wxwidgets.org/viewtopic.php?t=108
4. wxWidgets documentation (Include files): http://www.wxwidgets.org/manuals/2.4.2/wx11.htm.

For this time I'm using:
wxWidgets: 2.4.2
IDE: Dev-C++ 5 with MinGW 3.4.2
OS: WinXP Pro SP2
CPU: Athlon 1200
RAM: 256

The story starts from my topic "Why Dev-C++ + MinGW + wxWidgets 2.6.0 are so slow?": http://forums.wxwidgets.org/viewtopic.php?p=8649#8649

I'm absolutely wasn't satisfied by compilation time of my project (about 1000 lines). First that I did was removing all includes like

Code: Select all

#include <wx/wx.h>
they were replaced by only needed headers. So compilation time from 27 seconds was reduced to 16. Then I thought about precompiled headers. That was I did:

As written in wxWidgets documentation I refasion my includes like this:

Code: Select all

#include <wx/wxprec.h>

#ifndef WX_PRECOMP
  #include <wx/frame.h>
  #include <wx/icon.h>
  #include <wx/menu.h>
  #include <wx/statusbr.h>
  #include <wx/app.h>
  #include <wx/msgdlg.h>
#endif
But compilation time wasn't reduced. Then I thought about .gch files. As written in gcc documentation compiler first try to use .gch file if it can't he use .h file. Because I didn't find any connection between wxprec.h and .gch files I tried to create .gch file myself. So I typed "g++ wx.h" and .gch file was created but compilation time again wasn't reduced.

Who knows the truth?
WinXP Pro | Dev-C++ 5 | wxWidgtes 2.6.0 | wxGlade
Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Post by Jorg »

This is what I read here: http://gcc.gnu.org/onlinedocs/gcc/Preco ... aders.html

A precompiled header file can be used only when these conditions apply:

* Only one precompiled header can be used in a particular compilation.
* A precompiled header can't be used once the first C token is seen. You can have preprocessor directives before a precompiled header; you can even include a precompiled header from inside another header, so long as there are no C tokens before the #include.
* The precompiled header file must be produced for the same language as the current compilation. You can't use a C precompiled header for a C++ compilation.
* The precompiled header file must be produced by the same compiler version and configuration as the current compilation is using. The easiest way to guarantee this is to use the same compiler binary for creating and using precompiled headers.
* Any macros defined before the precompiled header is included must either be defined in the same way as when the precompiled header was generated, or must not affect the precompiled header, which usually means that they don't appear in the precompiled header at all.

The -D option is one way to define a macro before a precompiled header is included; using a #define can also do it. There are also some options that define macros implicitly, like -O and -Wdeprecated; the same rule applies to macros defined this way.
* If debugging information is output when using the precompiled header, using -g or similar, the same kind of debugging information must have been output when building the precompiled header. However, a precompiled header built using -g can be used in a compilation when no debugging information is being output.
* The same -m options must generally be used when building and using the precompiled header. See Submodel Options, for any cases where this rule is relaxed.
* Each of the following options must be the same when building and using the precompiled header:

-fexceptions -funit-at-a-time


* Some other command-line options starting with -f, -p, or -O must be defined in the same way as when the precompiled header was generated. At present, it's not clear which options are safe to change and which are not; the safest choice is to use exactly the same options when generating and using the precompiled header. The following are known to be safe:

-fpreprocessed -pedantic-errors
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb
Lestat
Experienced Solver
Experienced Solver
Posts: 68
Joined: Tue Apr 26, 2005 1:04 am
Location: Kemerovo, Russia

Post by Lestat »

I saw it. But it looks difficult. I'll try to comply this conditions. But first of all I want to hear something from someone who use precompiled headers with MinGW.
WinXP Pro | Dev-C++ 5 | wxWidgtes 2.6.0 | wxGlade
tiwag
Earned some good credits
Earned some good credits
Posts: 123
Joined: Tue Dec 21, 2004 8:51 pm
Location: Austria

Post by tiwag »

Lestat wrote:I saw it. But it looks difficult. I'll try to comply this conditions. But first of all I want to hear something from someone who use precompiled headers with MinGW.
download the latest version of
Chinook developer Studio
http://www.degarrah.com/chinookfree.php/

this IDE shows you how to deal with precompiled wx.h using mingw gcc 3.4

HTH
-tiwag
Lestat
Experienced Solver
Experienced Solver
Posts: 68
Joined: Tue Apr 26, 2005 1:04 am
Location: Kemerovo, Russia

Post by Lestat »

I solve first problem. Look in wxprec.h:

Code: Select all

// check if to use precompiled headers: do it for most Windows compilers unless
// explicitly disabled by defining NOPCH
#if ((defined(__BORLANDC__) || defined(__VISUALC__) || defined(__DIGITALMARS__) || defined(__WATCOMC__)) && defined(__WXMSW__)) || defined(__VISAGECPP__) || defined(__MWERKS__)
    #if !defined(NOPCH)
        #define WX_PRECOMP
    #endif
#endif
So wx thinks that only Borland, Visual C++, DigitalMars and WatcomC uses precompiled headers. I defined WX_PRECOMP myself and it starts working.

So my myprec.h looks like:

Code: Select all

#define WX_PRECOMP

#include <wx\wxprec.h>
#include "Class1.h"
#include "Class2.h"
#include <wx/socket.h>
#include "Class3.h"
#include <wx/notebook.h>
#include "Class4.h"
The following problem is that preprocessor uses myprec.h, but not myprec.h.gch. Why? Maybe it is that conditions about Jorg said? Is there any possibility to determine why .gch isn't used?
WinXP Pro | Dev-C++ 5 | wxWidgtes 2.6.0 | wxGlade
Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Post by Jorg »

Interesting. If GCC is not included in the precompiled header conditions, you might want to file this as a bug on the sf.net site of wxWidgets ..

- Jorgen
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb
tiwag
Earned some good credits
Earned some good credits
Posts: 123
Joined: Tue Dec 21, 2004 8:51 pm
Location: Austria

Post by tiwag »

it works for me with these compiler symbols defined :

Code: Select all

__WXDEBUG__,HAVE_W32API_H,__WXMSW__,WX_PRECOMP,NO_GCC_PRAGMA
here the complete config xml:

Code: Select all

        <config>
            <title>Debug GCC Win32</title>
            <compiler>D:\MinGW\bin\g++.exe</compiler>
            <compilerargs>-O0 -g2 -Wall</compilerargs>
            <includes>D:\wx260\Include,D:/wx260/Include/mswd</includes>
            <defines>__WXDEBUG__,HAVE_W32API_H,__WXMSW__,WX_PRECOMP,NO_GCC_PRAGMA</defines>
            <linker>D:\MinGW\bin\g++.exe</linker>
            <linkerargs>-mwindows -mthread</linkerargs>
            <libpaths>D:\wx260\Lib</libpaths>
            <libraries>wxmsw26d_core, wxbase26d, wxtiffd, wxjpegd, wxpngd , wxzlibd, wxregexd, wxexpatd, kernel32, user32, gdi32, comdlg32, winspool, winmm, shell32, comctl32, ole32, oleaut32, uuid, rpcrt4, advapi32, wsock32, odbc32</libraries>
            <buildpath>debug</buildpath>
        </config>



myprec.h (to be included in all modules)

Code: Select all

#include <wx/wxprec.h>
#ifdef __BORLANDC__
	#pragma hdrstop
#endif
#ifndef WX_PRECOMP
	#include <wx/wx.h>
#endif

module main.cpp

Code: Select all

#include "myprec.h"
#include "main.h"

IMPLEMENT_APP(cxApplication)

bool cxApplication::OnInit()
{
	Form1 = new FormMain( _T(wxVERSION_STRING) , 
                            wxPoint(0,0), 
                            wxSize(300,100));
	SetTopWindow(Form1);
	Form1->Show(true);
	return true;
}
good luck
Lestat
Experienced Solver
Experienced Solver
Posts: 68
Joined: Tue Apr 26, 2005 1:04 am
Location: Kemerovo, Russia

Post by Lestat »

Yes. I won it too. So at now I can said that precompiled headers works! The last problem was that I compiled my project and .gch file with different compiler options. When options became the same it started work!

The useful flag is -Winvalid-pch that will tell you about all problems.
WinXP Pro | Dev-C++ 5 | wxWidgtes 2.6.0 | wxGlade
Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Post by Jorg »

Thanks for sharing that!

Regards,
- Jorgen
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb
Lestat
Experienced Solver
Experienced Solver
Posts: 68
Joined: Tue Apr 26, 2005 1:04 am
Location: Kemerovo, Russia

Post by Lestat »

Thanks for sharing that!
Hope that it helps.
WinXP Pro | Dev-C++ 5 | wxWidgtes 2.6.0 | wxGlade
Lestat
Experienced Solver
Experienced Solver
Posts: 68
Joined: Tue Apr 26, 2005 1:04 am
Location: Kemerovo, Russia

Post by Lestat »

So now I can tell the summary:

1. Compile time with

Code: Select all

#include <wx/wx.h>
like including everywhere: 27 seconds
2. Compile time with including only necessary headers: 16 seconds
3. Compile time with precompiled headers: 10 seconds

So speed increasing is:
+41% in second method.
+63% in third method

Project consists of 918 lines of C++ code.

So I think I achieve great effect! :D
WinXP Pro | Dev-C++ 5 | wxWidgtes 2.6.0 | wxGlade
AkPhoenix
In need of some credit
In need of some credit
Posts: 5
Joined: Mon Apr 04, 2005 7:59 am

Post by AkPhoenix »

As a side remark, I found this thread so useful and relevant, that personally, I think it should be made a sticky. Hope the moderators agree...
Lestat
Experienced Solver
Experienced Solver
Posts: 68
Joined: Tue Apr 26, 2005 1:04 am
Location: Kemerovo, Russia

Post by Lestat »

I can write small FAQ on this topic. If someone find this necessary.
WinXP Pro | Dev-C++ 5 | wxWidgtes 2.6.0 | wxGlade
daggmano
In need of some credit
In need of some credit
Posts: 6
Joined: Tue May 03, 2005 10:46 pm
Contact:

Post by daggmano »

Lestat wrote:I can write small FAQ on this topic. If someone find this necessary.
Please do - the one thing that bugs me about MinGW under Windows compared to GCC under Linux is the long compile time. If this can be reduced, life would be much easier...
Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Post by Jorg »

It might also be useful in the wxWidgets WIKI. I will make this a sticky for now.

- Jorgen
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb
Post Reply