What is _PreComp_???

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
bensay
Posts: 202
Joined: Wed Dec 22, 2021 8:14 pm
Location: Danmark
Contact:

What is _PreComp_???

Post by bensay »

First of all, I am a total nooooob, so don't expect that I know too much about precompiled libraries.

What I have noticed is that there are 1302 places in the code where _PreComp_ is mentioned like this:

Code: Select all

#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
# include <QCoreApplication>
# include <QMessageBox>
# include <QRegExp>
#endif
But what is _PreComp_? When should an include be inside _PreComp_?

I also noticed, that the definition of _PreComp_ has been commented out since at least 2011 (GitHub doesn't go further back): https://github.com/FreeCAD/FreeCAD/blob ... fig.h#L321. So are _PreComp_ even still used or will ever come to use again?
Jee-Bee
Veteran
Posts: 2566
Joined: Tue Jun 16, 2015 10:32 am
Location: Netherlands

Re: What is _PreComp_???

Post by Jee-Bee »

I'm a noob too. But i like sometimes to dig around ;)

check this: https://en.wikipedia.org/wiki/Precompiled_header

and check this: https://wiki.freecadweb.org/User:Ian.rees (under FreeCAD Design (in the sense of source code) Guide) (Don't ask me why something is written about it in that and not in the developer wiki)

third good source (probably): https://raw.githubusercontent.com/qingf ... 190912.pdf
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: What is _PreComp_???

Post by wmayer »

I am a total nooooob, so don't expect that I know too much about precompiled libraries.
It is about pre-compiled headers (PCH). That's a technique to speed up the compilation process.

Currently, PCH is only used for MSVC under Windows and for each target the compiler builds PreCompiled.cpp as very first file. It creates a big binary file that contains the content of all header files of the corresponding PreCompiled.h.

Remark:
Because the creation of this binary file is quite expensive it must be avoided to re-create it too often. This can only be achieved if files are added that almost never change. So, that's why for PCH only 3rd party header files should be considered but not application header files.

If the compiler continues with the next source files then it replaces the "PreCompiled.h" with the content of the binary file. This avoids that the compiler has to open each header file separately that is listed in the PreCompiled.h and thus considerably speeds up the process. With activated PCH for MSVC we get a reduction of the build time of 40-50%.
But what is _PreComp_? When should an include be inside _PreComp_?
Because PCH is optional and not yet ready to be used for other compilers than MSVC it must be avoided to slow down the build process for them. Therefore it must be avoided that they had to include all headers of a PreCompiled.h and that's why the PreCompiled.h files have a guard of this form:

Code: Select all

#ifdef _PreComp_
...
include all needed headers for the target
#endif
However, when building a normal source file and the compiler needs the declaration of a used class or function then the header of this class or function has to go inside the #ifndef _PreComp_/#endif block.

To formulate this as a rule:
A header must be added inside an #ifndef _PreComp_/#endif block if the compiler requires a declaration that is provided by this file AND it's not already included AND if this header is listed in the target's PreCompiled.h file.
I also noticed, that the definition of _PreComp_ has been commented out since at least 2011 (GitHub doesn't go further back): https://github.com/FreeCAD/FreeCAD/blob ... fig.h#L321. So are _PreComp_ even still used or will ever come to use again?
If a header is already included by an application header file then it's not needed to include again. That's why some _PreComp_ are empty or commented out.
User avatar
bensay
Posts: 202
Joined: Wed Dec 22, 2021 8:14 pm
Location: Danmark
Contact:

Re: What is _PreComp_???

Post by bensay »

wmayer wrote: Thu Aug 04, 2022 12:34 pm
I also noticed, that the definition of _PreComp_ has been commented out since at least 2011 (GitHub doesn't go further back): https://github.com/FreeCAD/FreeCAD/blob ... fig.h#L321. So are _PreComp_ even still used or will ever come to use again?
If a header is already included by an application header file then it's not needed to include again. That's why some _PreComp_ are empty or commented out.
But isn't this the definition of _PreComp_ that has been commented out? Isn't _PreComp_ undefined because of this? As far as I see, _PreComp_ doesn't get defined anywhere in the whole repository, so wouldn't all #ifndef _PreComp_ always turn out to be true - thereby having no meaning?
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: What is _PreComp_???

Post by wmayer »

But isn't this the definition of _PreComp_ that has been commented out? Isn't _PreComp_ undefined because of this?
Didn't get your point.
As far as I see, _PreComp_ doesn't get defined anywhere in the whole repository, so wouldn't all #ifndef _PreComp_ always turn out to be true - thereby having no meaning?
It's defined in all the CMakeLists.txt files (example from src/App):

Code: Select all

if(FREECAD_USE_PCH)
    add_definitions(-D_PreComp_)
    ADD_MSVC_PRECOMPILED_HEADER(FreeCADApp PreCompiled.h PreCompiled.cpp FreeCADApp_CPP_SRCS)
endif(FREECAD_USE_PCH)
gneiss
Posts: 75
Joined: Tue Mar 05, 2019 4:13 pm

Re: What is _PreComp_???

Post by gneiss »

Hm, does FreeCad not use PCH under gcc ?
Here it is implemented using
#pragma hdrstop
#pragma once
and I use this in my projects wherever possible, because (if used with caution) it will speed up compilation a lot.
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: What is _PreComp_???

Post by wmayer »

Hm, does FreeCad not use PCH under gcc ?
No, it doesn't. The PCH support for MSVC is hand-crafted because older CMake versions didn't support it at all. Now CMake does it but you need a fairly new version that isn't available on all supported distributions.
Here it is implemented using
#pragma hdrstop
#pragma once
and I use this in my projects wherever possible, because (if used with caution) it will speed up compilation a lot
Can you describe this in more details, please? Don't you have to run the compiler with a special flag to create the PreCompiled.gch out of the PreCompiled.cpp?

Around 15 years ago I tested PCH with gcc and at that time it was totally useless because the creation of the gch file took almost as long as the actual build process without PCH and the generated file was more than 1 GB. Additionally, the build with PCH wasn't significantly faster than the build without PCH.
gneiss
Posts: 75
Joined: Tue Mar 05, 2019 4:13 pm

Re: What is _PreComp_???

Post by gneiss »

@wmayer

The mechanism is pretty simple.
"#pragma once" is just a shortcut for the standard "sentry", so not relevant here.

gcc will cache the content of all files included till it found a "#pragma hdrstop".
If the next file that was compiled uses the same files & order, it use the cached content instead of reading the files again.
So there is no (visible) file that contains precompiled code. It is (re-)generated at every "make" and/or if needed because the include sequence changed.

So, usually I use a "Project-Include-file" that includes all (most of) the files need for the majority of the files of the project.

eg.: A Projekt "MyProject" uses a file "CommonIncludes.h" that looks like this:

Code: Select all

#include <stdio>
#include <stream>
#include <string>
...
#pragma hdrstop
Now all Project files uses at the very beginning:

Code: Select all

#include "CommonIncludes.h" 

#include <stream> // even that is no problem, caching already stopped, 2. include stoppt due to "sentry" or "#pragma once"
BTW.: That mechanism I use since Windows NT with "Borland C++Builder". You see pretty old technique introduced by Borland, adopted by GNU :-((

Just some remarks:
I am not familiar with cmake. My job during the last ~25 Years are "bare metal" programs for microprocessors and some support prgs running on a PC.
So I use make for the microprocessor projects.
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: What is _PreComp_???

Post by wmayer »

Thanks for the details.
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: What is _PreComp_???

Post by wmayer »

Here is a simple description how to use PCH with CMake (3.16+): https://edgarluque.com/blog/cmake-precompiled-headers/
Post Reply