Using Precompiled Header Files for Library Developers

According to this answer, boost and STL headers refer to a precompiled header file ( stdafx.h in the MSVC world). So I changed the headers of my dynamic link library project and moved all the STL / Boost headers to stdafx.h my project.

Before

 #include <boost/smart_ptr.hpp> namespace XXX { class CLASS_DECL_BK CExampleClass // CLASS_DECL_BK is just a standard dll import/export macro { private: boost::scoped_ptr<Replica> m_replica; } } 

After

 namespace XXX { class CLASS_DECL_BK CExampleClass { private: boost::scoped_ptr<Replica> m_replica; } } 

Now I have the advantage of reducing compilation time , but all users of my library get build errors (for example, unknown boost :: scoped_ptr ...) due to missing includes (which now moved to my stdafx.h ).


What could be the solution to this dilemma?

I want to reduce compilation time and compile errors after including my header files, which is not acceptable for any DLL users.

Did it help?

  • leave all directives as they are, but duplicate them in my "stdafx.h"? Since stdafx.h is always included first in any cpp file of my project, I should be fine and users will not get any errors. Or am I losing my speed advantage if several inclusions of the same title are found in the same translation block (title defenders are obtained)?

Thanks for any tips!

+4
source share
3 answers

You should get almost the same speed increase when you leave the header - includes in the library headers and just add them to stdafx.h .

Alternatively, you can add an additional definition (array of external include guard )

 // stdafx.h #define MY_LIB_STD_HEADERS_ALREADY_INCLUDED // library_file.h #ifndef MY_LIB_STD_HEADERS_ALREADY_INCLUDED #include <boost/smart_ptr.hpp> ... #endif 

But I would only do this if you are sure it helps. Just grab a stopwatch and run a few re-compilations. (No need to bind.) Then you will see if there is a difference.

Besides

I'm not sure that adding all the heading headers that are needed somewhere in the project is such a good idea. I would say shared_ptr and friends, boost/foreach , maybe Boost.Format, ... is a good idea, but I would think twice about Boost.RegExp headers. Note: I did not take any speed measurements , but I vaguely remember a problem with the pch file size and some hiccups of the compiler. I really have to do some tests .

Also check to see if the Boost library provides a header forwarding library and whether to enable them. Weighing a precompiled header file may have its drawbacks.

+2
source

You can create an assembly configuration for this purpose (Debug, Release, CheckDependencies). An easy way to change this would be to use a preprocessor to enable / exclude inclusions based on the current configuration. using this, you can test and build using debug or release (which contains a larger set of inclusions), and then compile all the configurations before distribution.

for clarification, the conditional inclusion MON_LIBRARY_VALIDATE_DEPENDENCIES should not be used in library headers or sources in a precompiled header only:

 // my pch: #include <file1.hpp> #include <file2.hpp> // ... #if !defined(MON_LIBRARY_VALIDATE_DEPENDENCIES) #include <boost/stuff.hpp> // ... #endif 

then you must add MON_LIBRARY_VALIDATE_DEPENDENCIES to the list of preprocessor definitions in the CheckDependencies configuration.

in relation to guards: this should not be a problem if you use defenders under normal circumstances - compilers use optimization to detect these cases, which means that in many cases they can avoid opening a file if it was included and protected correctly. in fact, trying to outwit the compiler in this arena can actually slow down the process. I would say just leaving it as typical if your library / dependencies are huge and you really have noticeable problems.

+2
source

Creating your own compilation units (let them include everything they use) is highly desirable. This will prevent compilation errors from others that do not use precompiled headers, and, as you think, header protectors will keep these extra costs to a minimum.

It will also have the desired side effect to take a look at the headers, to indicate to users who use other headers in the block, and options for compiling a single block without any fuzz.

+1
source

All Articles