CMake - Header files with preprocessor directives - c++

Is it possible to compile header files with C/C++ preprocessor direktives? (Defines)
I have a project with some header files which are without a cpp file. For example typedefs for different platforms.
I'm looking for a simple solution that can be integrated into my cmakefile.

Are you looking for precompiled headers maybe? They can be compiled by a makefile.

If your headers are included in cpp files, they will automatically be used. If they are not included, what is the point of 'compiling' them ?
So basically, the answer is no, you cannot compile only header files. The purpose of compilation is to produce an executable, a file that do actions when executed. Definitions are not actions, they do nothing on their own.

Related

Does std:: library of c++ have .cpp files?

This may be a naive question since I'm a c++ beginner.
In a typical cpp project, we have cpp files and their header files. So based on my understanding, usually cpp files have definitions, while respective header files have declarations. During compiling, we have to include very cpp files in the project since header files do not specify the location of the definition of the declared object. Finally, linker links declaration and definition. This allows the communication between different translation units.
However, when it comes to std:: library, we do include header files but never compile its cpp files. For example, we write #include in main.cpp, but when compiling, the command does not have anything like g++ vector.cpp main.cpp ...
I even tried to search cpp files in the std library folder in my system, but all I can find is various header files.
I do know the definition and declaration can be included in a single header file, I don't think this is how std:: is wrote. Otherwise, it will result in multiple copies of definition when included in different cpp files.
Please help me to understand how this works? Can I do something like this with my own project?
When it comes to templated libraries, the source code must be found in the header files (.h or .hpp), so it is not exceptional to find header-only libraries.
If part of the code is not templated and its implementation is made in source files (.cpp), usually the code is precompiled and supplied as .lib (.a/.so) files to be linked to.
As regards open source APIs, if there are .cpp files they are delivered as well and you have to compile/precompile them by yourself.
Yes, there is compiled code in the standard library. You don't have to compile it because the library comes already compiled with your compiler. And you don't explicitly link to it, because the compiler knows about it. So you don't see it mentioned anywhere when you do normal builds. If you set your compiler to some form of verbose mode you can see that the name of the standard library gets passed to the linker, which pulls the code it needs from the library.

Main purpose of a Precompiled header file

My dll project is generating, not only DLL and LIB files but, also a Precompiled file header file. What is the main purpose of a PFH file in my project? Can I get rid of it?
Yes you can get rid of it, but it makes compilation notably faster by allowing the compiler to not recompile a ton (there's really a lot of code in there) of Windows SDK headers. MSDN has more details.
It's simply a way of speeding up compilation, by creating a single file containing all declarations and definitions from multiple header files. Often this file is in a post-parsed format, so the compiler don't have to parse it again.

Visual studio forces to include precompiled header file in all compilation units of the project?

When compiler compiles source (e.g. *.cpp) file, it creates object file (e.g. *.o), so that later it will be linked to other .o and .so (.lib files for Windows) files and will constitute the executable file.
Now for analogical situation for not compiling header files each time it creates some .pch files so that it will be linked it by the linker then.
Now if in the scope of a Visula Studio project it is defined a precompiled header, then why Visual Studio complains with an error (e.g. **fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?**) that the header file is not included into the .cpp file.
By summarizing, here are my questions:
Why in each .cpp file the precompiled header of the project is
necessary?
How does the requirement of presence of precompiled header in each compilation unit optimizes the compilation process? In other words, what is the benefit of this requirement? (It could be up to the user to decide where to include, where not!)
If precompiled header is included into a .cpp file, which uses only 2% of what is in .pch file, then the remaining 98% will be added to corresponding .o file to?
Why in each .cpp file the precompiled header of the project is necessary?
Because you asked for it. If you don't want to use it then you need to change the option for the .cpp file. Right-click it, Properties, C/C++, Precompiled Headers, "Create/Use" = "Not using precompiled headers". The default setting is "Use". There's little point in doing this.
How does the precompiled header in each compilation unit optimizes the compilation process?
By not having to parse the #includes. Particularly useful when you #include <windows.h>. Time saved is in the order of seconds, on large projects with hundreds of .cpp files that adds up to many minutes. It is by far the cheapest way to speed up the compiler with no loss of quality on the generated code.
then the remaining 98% will be added to corresponding .o file to?
Of course not.
It's not actually necessary to include the precompiled header in every compilation unit. You can set the "not using precompiled header" setting for a single file in the C/C++->Precompiled Headers properties section for that file. This is a lot of work though, and I've never known anyone to do it in production code.
The optimization is that the precompiled header is built just once and the whole shebang is reused for all compilation units without recompiling / re-including (sort of). If you have a set of files that are included a lot of times this can save much compilation time. See The Care And Feeding of Precompiled Headers too.
No, you don't get superfluous file contents, just like you don't when static-linking.
I guess your question means "why can't the compiler assume that this header is always there if it is mandatory". The reason is that VS does not want to deviate from the standard so much. If your .cpp file is using something from a header file, it must include it. This way your file will compile exactly the same even if you turn off precompiled headers (only it will take longer).
As others have said, you can explicitly disable precompiled headers for individual files if you want. The idea is that you should only include in the precompiled header those elements that you are using in most, if not all of your files.
No, the resulting object code should be the same regardless of the header being precompiled or not.

Precompiled Headers in Header Files

I ran into precompiled headers today for the first time..forever changing my life. I can't believe compiling my C++ code could be that fast. It makes total sense now..
Anyway, one thing that is confusing me is that from what I've read so far, pre-compiled headers only should be added to source files( cpp? ).
In Visual Studio, there is an option under Project Properties->C/C++->Advanced to "Force Include File". I set that compiler option to stdafx.h.
After doing this..I no longer require to include the headers I have added to my stdafx.h, even inside my header files ( source files are supposed to automatically include stdafx.h ). Is this expected behaviour?
I can't find a place that's clear in the distinction between header/source files.
If it does..great but I'm afraid it's another one of those things VC++ lets you get away with but will break in GCC. And yes..it needs to be portable; at least between GCC and VC++.
StdAfx.h really should only be included in source files, not headers. I would suggest you #include "StdAfx.h" first in every cpp and not use the "Force Include File" option. Thats how I do it with my cross-platform projects. For the record, I don't actually use precompiled headers in GCC I just build it normally and it works well.
For some background. The compiler only looks at source files (ie, *.cpp, *.c, etc) and so when it compiles them it has to include every header and compile any code found in the headers as well. The precompiled headers option allows for compiling all of that code (ie, the globally include'd code in StdAfx.h) once so that you don't have to do it all of the time. Thats what StdAfx.cpp is for. The compiler compiles StdAfx.cpp with all of the code included in StdAfx.h once instead of having to do it every time you build.
So, since you include StdAfx.h in every source file as the first item, it doesn't make sense to include it in any of the headers since they will be included AFTER StdAfx.h and thus will have access to all of the code in StdAfx.h. Plus you can then use those headers in other projects without having to worry about having a StdAfx.h around or including the wrong one.
Yes, it is expected behaviour. The Project Properties->C/C++->Advanced to "Force Include File" setting controls Visual C++ compiler option /FI:
This option has the same effect as specifying the file with double
quotation marks in an #include directive on the first line of every
source file
So, it frees you from including the stdafx.h manually.
Although, you can use precompiled headers with GCC and other compilers
The Visual C++'s shortcut behaviour is not portable across other compilers. So, check How to handle stdafx.h in cross-platform code? where ideas for portable solutions are discussed.
Long story short, include stdafx.h manually in your .cpp source files and you should be fine also with GCC (assuming, you will configure your build for GCC to use precompiled headers).
Do not use the "Force Include File" setting (/FI) as it breaks Edit & Continue !
(and MS doesn't seem to want to fix this issue)
See
https://connect.microsoft.com/VisualStudio/feedback/details/668339/vs-2010-sp1-c-edit-and-continue-fails-with-fi
and
https://connect.microsoft.com/VisualStudio/feedback/details/342441/visual-studio-2005-force-includes-breaks-edit-and-continue-with-pre-compiled-headers
#include "stdafx.h" should only be found as the first non-comment line in your source files, not in header files.

What to put in precompiled header? (MSVC)

What are the best candidates for a precompiled header file? Can I put STL and Boost headers there, even though they have templates? And will that reduce compile times?
Also, what are the best IDE settings to reduce compile times?
The quick answer: the STL and Boost headers do indeed belong in the precompiled header file, even though these header files define template classes.
When generating a precompiled header file, a compiler parses the header text (a significant task!), and converts it into a binary format that is optimised for the compiler's benefit.
Even though the template classes will be instantiated when other .cpp files are compiled, they will be instantiated from information in the precompiled header, which is significantly faster for the compiler to read.
(later addition)
One thing that you should not include in a precompiled header are files that are part of your project and are changed frequently, even if every single .CPP file includes these files.
The reason is this - the generation of the precompiled header can take a long time, because the boost, stl and windows libraries are very large.
You might have a simple file (eg "StringDefs.h") that everything uses. If StringDefs.h is included in stdafx.h, and one developer touches StringDefs.h, then every developer has to wait until the entire precompiled header recompiles. It would be much faster if StringDefs.h was left out of the precompiled header, and parsed along with each .CPP file.
One addition to Andrew Shepherd's answer. Use the precompiled header for header files that are external to your project, for files that change infrequently. If you're changing the header files in the current project all the time, it's probably not worth precompiling them.
I've written an article on techniques that reduce the compilation time. Among these techniques a post on precompiled header and its application can be found here. It also has a section on best practices that you may find interesting. CMake scripts that handle it transparently are included.
Put anything in the precompiled header that most of the .cpp files in that project would include anyway. This goes for any header file, really. This allows the compiler to parse these files once, and then reuse that information in all .cpp files in the same project.